Search code examples
javascriptaccordiondojoaccordionpane

Populating Dojo AccordionContainer


This code generates an array length of children in an accordion style

require(["dijit/layout/AccordionContainer", "dijit/layout/ContentPane", "dojo/domReady!"],
        function(AccordionContainer, ContentPane){
    var aContainer = new AccordionContainer({style:"height: 300px"}, "markup");
    len = dataArray.length;
    for ( var i =0; i<len; i++);
    {
    aContainer.addChild(new ContentPane({
        title:dataArray[i].title,
        content: dataArray[i].content
    }));
    }
    aContainer.startup();
});

I am trying to populate the content part of each child. For instance, let's assume I have a list of 10 things to add to the content area. How do i populate the content area with this list(thinking of a for loop but just not sure how to implement it), and also possibly add a checkbox beside each item in the list, and then a button at the end. For example, let's assume the title of the of the contentpane is Cars. Once Cars is clicked, a list of car models will appear in accordion style with a checkbox beside it. A "Buy" button will be at the bottom of the content area to be clicked once specific cars are selected. I am new to Dojo. Been stuck on this for a while. Any help will be greatly appreciated.


Solution

  • So, if I understand well, you want to dynamically fill the content of a single ContentPane? Or do you want to dynamically create the ContentPane's (like the answer of Miriam is describing).

    If you're interested in dynamically adding checkboxes to your contentpane and adding a button to it, the best thing you could do is create your own widget and use a store to represent the data.

    For example:

    var FacetPane = declare("dijit/layout/FacetPane", [ ContentPane ], {
        store: null,
        labelAttr: 'name',
        _setStoreAttr: function(store) {
            this.store = store;
            this.update();
        },
        _getStoreAttr: function() {
            return this.store;   
        },
        postCreate: function() {
            this.inherited(arguments);
            this.itemNode = domConstruct.create("div", {
                class: "itemNode"   
            }, this.domNode);
            this.update();
        },
        _destroyItems: function() {
            if (this.itemNode) {
                console.log("Destroying items");
                arr.forEach(registry.findWidgets(this.itemNode), function(item) {
                    console.log("Destroy item : " + item.id);
                    item.destroy(); 
                });
            }
        },
        update: function() {
            if (this.store) {
                this._destroyItems();
                this.store.query({}).forEach(lang.hitch(this, this._updateRecord));   
            }
            new Button({
                label: "Buy"
            }, domConstruct.create("button", null, this.itemNode));
        },
        _updateRecord: function(item) {
            var row = domConstruct.create("div", {
                class: "rowNode"   
            }, this.itemNode);
            new CheckBox({
                label: item[this.labelAttr]
            }, domConstruct.create("input", null, row));
            domConstruct.create("label", {
                innerHTML: item[this.labelAttr]
            }, row);
        }
    });
    

    I know, this might look like a lot of code, but what happens is quite easy. I created my own wiget called FacetPane which inherits from a ContentPane. This new module has two properties:

    • store: The store containing the items that should be "converted" to checkboxes
    • labelAttr: The attribute of each element in the store that should be used as the label of the checkbox

    Then I override the postCreate() function and tell it to create an extra sub-DOMnode that will contain our items and after that I update it based on the items inside the store (which you can find in the update()) function.

    For each item in the store (_updateRecord()) I add a new row node containing a checkbox and a label.

    This solution can probably be improved a lot, but this should give you a basic idea of how you could create such a widget. The basic idea is to have a store for your model data and to dynamically create DOM nodes and widgets based on the store values.

    A full example can be found on JSFiddle: http://jsfiddle.net/LaLNH/