Thursday, September 2, 2010

Palm Developer Blog: Dynamic Widget Instantiation


Posted: 01 Sep 2010 05:40 PM PDT
Have you ever needed to set up a Mojo widget sometime after a scene’s setup method has been called? Perhaps you aren’t ready or don’t want the overhead of setting your widget up when the scene first loads. Or maybe you’re waiting until some condition has been met, such as the activate method being called after a scene above is popped. Or maybe you want to do something fancy like create an engine that programmatically populates a scene & its widgets at any point in a scene’s lifecycle.
Well, the instantiateChildWidgets function does just what you need here and it’s a method that sometimes gets overlooked. The basic idea is that you’ll setup your widgets as usual, just not in the scene’s setup method, then use the scene’s controller to call the instantiateChildWidgets function on the container div of the widgets you’re setting up.
Here’s a more detailed & totally contrived example (my specialty) where we’ll instantiate a list of list selectors, but not until after the setup method of our scene is called. All the code is included in the attached sample app here.
Step 1 – Generate an application. Mine is titled DynamicWidgets.
Step 2 – Generate a scene. I named mine ‘main’.
Step 3 – Add the following HTML to your new scene:
   
The choiceList element is just a standard Mojo list. However notice it’s contained in a div named “container”. We’ll use this later when we call instantiateChildWidgets which instantiates any widgets in the container div passed to it.
Step 4 – Add a new HTML file in your scene’s view directory. Mine is named list-item.html. In that file add the following HMTL:
   
      
   
This is standard HTML for a list item, and you can see that each item contains a ListSelector widget. Still nothing new here.
Step 5 – In your scene assistant, add the following code (change the assistant name to match what you’ve called yours):
function MainAssistant(){};

MainAssistant.prototype = {

    selectorChoices: [
        {label:'Choice 1', value:"choice1"},
        {label:'Choice 2', value:"choice2"},
        {label:'Choice 3', value:"choice3"},
        {label:'Choice 4', value:"choice4"},
        {label:'Choice 5', value:"choice5"}
    ],

    choiceListModel: {
        items: [
            {choice:'choice1'},
            {choice:'choice2'},
            {choice:'choice3'},
            {choice:'choice4'}
        ]},

    setup: function() {
        setTimeout(this.loadList.bind(this), 5000);

    },

    loadList: function() {
        this.controller.setupWidget('choiceList',
            {
                itemTemplate:'main/list-item'
            },
            this.choiceListModel
        );

        this.controller.setupWidget('choiceSelector',
            {
                label: 'Choice',
                modelProperty: 'choice',
                choices: this.selectorChoices
            }
        );

        this.controller.instantiateChildWidgets($('container'));

    }
};
Here we set up our list selector options and model as members of the scene assistant, but you can do this however you’d like as long as they’re defined prior to setting up the related widgets. The more interesting piece is that in our assistant’s setup function, rather than setting up our widgets we specify another function to be called after 5 seconds. In that function, loadList, we set up our list and selector widgets. Finally we call the star of this post, the instantiateChildWidgets function, which will instantiate our widgets contained in the div we pass to it.
Step 6 – Before we can run this example, don’t forget to add the following to stage-assistant.js:
this.controller.pushScene('main');
Now after packaging, installing, running, and waiting 5 seconds (for the timeout we added) here’s what you should see:

It’s not incredibly exciting I suppose, but in the attached sample as an extra special bonus I’ve included a dynamically instantiated button in each list item plus a tap handler!
I hope this sheds a bit of light on an API that is relatively obscure. In the right situation, though, it may be just what you need, and not at all difficult to take advantage of. Also note that there is an example in our mojomatters sample app (included in our SDK) which demonstrates a lazy list with dynamically instantiated drawer widgets added dynamically to the scene with a string of HTML and a call to instantiateChildWidgets. You’ll find it in the lazylistlazywidgets-assistant.js code.

  

No comments:

Post a Comment

[Invitation] Galaxy Unpacked 2024, Jan 17: Opening a New Era of Mobile AI.

A revolutionary mobile experience is coming. Get ready to discover a new era full of possibilities with the latest Galaxy innovations, desig...

Popular Posts