1. #1
    Sencha User
    Join Date
    May 2013
    Posts
    7
    Vote Rating
    0
    JustaCoder is on a distinguished road

      0  

    Default Help with Dynamic Checkboxes

    Help with Dynamic Checkboxes


    Hello,

    Coder of 17 years but new to Ext.js. Basically I am lost with it. Working on an issue in a component installed in Modx admin with Ext version 3.4.0. For this reason many of the code samples out there, including the Sencha checkboxgroup samples, aren't working. Please assume I've been over the documentation as well as a few hundred other resources trying to solve this **simple** task:

    The task:

    A "company" has "workers" and the workers may work at multiple locations. When the worker edit window loads, it queries a php script that indeed returns a valid JSON string with the company's locations. I simply cannot get the data into checkboxes that render in the form.

    What DOES (sorta) work: This is a combo box that does populate the locations, but for whatever reason, multiSelect does NOT work (probably something deep in the modx code disabling it: )

    Code:
    ThisComponent.combo.Locations = function(config) {
        config = config || {};
        Ext.applyIf(config,{
            name: 'locations'
            ,hiddenName: 'locations'
            ,displayField: 'name'
            ,valueField: 'id'
            ,multiSelect: true
            ,fields: ['id','name']
            ,url: ThisComponent.config.connectorUrl
            ,baseParams: { 
                action: "mgr/locations/getCheckboxList"
                ,practice: ThisComponent.request.practice
            }
        });
        ThisComponent.combo.Locations.superclass.constructor.call(this,config);
    };
    Ext.extend(ThisComponent.combo.Locations,MODx.combo.ComboBox);
    Ext.reg('this-component-combo-locations',ThisComponent.combo.Locations);
    If multiSelect worked as it should, we could use this, but it doesn't. On to checkboxes.

    There is a master .js in the component that defines the objects, here is what I've come up with gathered from various sources:

    Code:
    var LocationsItems = [];
    Ext.namespace("Ext.checkboxgroup");
    Ext.checkboxgroup.RemoteCheckboxGroup = function(config) {
        config = config || {};
        
        var resourceStore = new Ext.data.JsonStore({
            fieldValue: 'id'
            ,fields: ["id", "name"]                                                                                                          
            ,autoLoad: true 
            ,root: "results"
            ,url: ThisComponent.config.connectorUrl
            ,baseParams: { 
                action: "mgr/locations/getCheckboxList"
                ,practice: ThisComponent.request.companyid
            }                                                                                                                                                                             
            ,listeners: {                                                                                                                         
                load: function(results) {                                 
                     for(var i = 0; i < records.length; i++) {                                                                                         
                       LocationsItems.push({id: records[i].data.id, boxLabel: records[i].data.name});                                             
                     }                                                                                                                            
                }                                                                                                                                  
            }
            ,items:LocationsItems                                                                                                                           
        });                                                                                                                                                                                                                                                                            
        resourceStore.load();
        Ext.checkboxgroup.RemoteCheckboxGroup.superclass.constructor.call(this, config);
    };
    Ext.extend(Ext.checkboxgroup.RemoteCheckboxGroup,Ext.form.CheckboxGroup);
    Ext.reg('this-component-checkboxgroup-locations',Ext.checkboxgroup.RemoteCheckboxGroup);
    And my window, which otherwise works fine:

    Code:
    PD.window.UpdateWorker = function(config) {
    
        this.ident = config.ident || 'this-component-window-du';
        Ext.applyIf(config,{
            id: this.ident
            ,width: 500
            ,title: 'Update Worker'
            ,url: ThisComponent.config.connectorUrl
            ,action: 'mgr/workers/update'
            ,fields: [{
                xtype: 'hidden'
                ,name: 'id'
                ,value: true
             },{
                xtype: 'this-component-checkboxgroup-locations'
                ,fieldLabel: 'Locations'
            },{
            // For the combo list that doesn't work as multiselect
            /* },{
                xtype: 'this-component-combo-locations'
                ,fieldLabel: 'Locations (Hold CRTL to select multiple locations)'
                ,fieldValue: 'id'
                ,width: 300
            },{*/
                 fieldLabel: 'First Name'
                 ,name: 'first_name'
                 ,xtype: 'textfield'
                 ,width: 300
                 ,allowBlank: false
             },{
                 fieldLabel: 'Last Name'
                 ,name: 'last_name'
                 ,xtype: 'textfield'
                 ,width: 300
                 ,allowBlank: false
             },{
                 fieldLabel: 'Specialty'
                 ,name: 'specialty'
                 ,xtype: 'this-component-combo-fullspecialty'
                 ,width: 300
                 ,allowBlank: false
             }]
        });
        ThisComponent.window.UpdateWorker.superclass.constructor.call(this,config);
    };
    What can I do here to get the checkboxes in the form window?

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,541
    Vote Rating
    872
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    So you are just pushing items to the LocationsItems array and expecting it to know about this? That's not really how JavaScript works. Instead of pushing the items to the LocationsItems array, create an array and use the add method on the checkbox group and doLayout. Here is a little example of what I mean:

    Code:
    var form = new Ext.form.FormPanel({
        renderTo : document.body,
        title    : 'Test',
        items    : [
            {
                xtype      : 'checkboxgroup',
                fieldLabel : 'Foo',
                items      : [
                    {
                        boxLabel : 'One'
                    },
                    {
                        boxLabel : 'Two'
                    }
                ]
            },
            {
                xtype   : 'button',
                text    : 'Add Items',
                handler : function() {
                    var group  = form.getComponent(0),
                        panel  = group.panel,
                        items  = [],
                        i      = 0,
                        length = 5;
    
                    for (; i < length; i++) {
                        items.push({
                            xtype    : 'checkbox',
                            boxLabel : 'Checkbox ' + i
                        });
                    }
    
                    panel.removeAll();
                    panel.add(items);
                    panel.doLayout();
                }
            }
        ]
    });
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha User
    Join Date
    May 2013
    Posts
    7
    Vote Rating
    0
    JustaCoder is on a distinguished road

      0  

    Default


    Thank you - yes I knew it had something to do with scope of "LocationItems" but I've tried many things and none of them seemed to work. Thank you again and I'll give this a try!

  4. #4
    Sencha User
    Join Date
    May 2013
    Posts
    7
    Vote Rating
    0
    JustaCoder is on a distinguished road

      0  

    Default


    Busy day yesterday, I've re-visited this project and had a look.

    The problem is not that I'm pushing items to the LocationsItems array - the data never gets there. If it did, it might even work. :-) In fact, in one interation I had named it "items" and it's still empty/null.

    See my "working" but not working example. This indeed returns the JSON containing the data:

    Code:
            ,baseParams: { 
                action: "mgr/locations/getCheckboxList"
                ,practice: ThisComponent.request.companyid
            }
    But it never gets here:

    Code:
            ,listeners: {                                                                                                                         
                load: function(results) {                                 
                     for(var i = 0; i < records.length; i++) {                                                                                         
                       LocationsItems.push({id: records[i].data.id, boxLabel: records[i].data.name});                                             
                     }                                                                                                                            
                }                                                                                                                                  
            }
            ,items:LocationsItems
    results is undefined, records is undefined, it's like "listeners" has no effect.

    I need to understand what's happening there, and don't. :-\ Thank you for your patience with the EXT newb.

  5. #5
    Sencha User
    Join Date
    Jan 2011
    Posts
    546
    Vote Rating
    53
    willigogs is a jewel in the rough willigogs is a jewel in the rough willigogs is a jewel in the rough

      0  

    Default


    The issue is that your locationItems array is empty when the store is initialized - and even though you may update this array later - that doesn't update the items in the store. You would have to tell the store to reload this array again once you've populated it...

  6. #6
    Sencha User
    Join Date
    May 2013
    Posts
    7
    Vote Rating
    0
    JustaCoder is on a distinguished road

      0  

    Default


    Thank you - here's a new version, I took another look at a combo box that is working. Firebug error is "this.items is undefined" in ext-all.js.

    Code:
    Ext.namespace("Ext.checkboxgroup");
    Ext.checkboxgroup.RemoteCheckboxGroup = function(config,getStore) {
        config = config || {};
        
        Ext.applyIf(config,{
            fieldValue: 'id'
            ,fields: ["id", "name"]                                                                                                          
        });
        Ext.applyIf(config,{
            store: new Ext.data.JsonStore({
                url: ThisComponent.config.connectorUrl
                ,autoLoad: true 
                ,root: "results"
                ,totalProperty: 'total'
                ,errorReader: MODx.util.JSONReader
                ,remoteSort: config.remoteSort || false
                ,autoDestroy: true
                ,baseParams: { 
                    action: "mgr/locations/getCheckboxList"
                    ,companyid: ThisComponent.request.companyid
                }                                                                                                                                                                             
                ,listeners: {                                                                                                                         
                    load: function(results) {               
                         for(var i = 0; i < records.length; i++) {                                                                 
                               items.push({id: records[i].data.id, boxLabel: records[i].data.name});                                             
                         }                                                                                                                            
                    }                                                                                                                                  
                }
            })                                                                                                                           
        });
        if (getStore === true) {
           config.store.load();
           return config.store;
        }
        Ext.checkboxgroup.RemoteCheckboxGroup.superclass.constructor.call(this,config);
        this.config = config;
        return this;
    };
    Ext.extend(Ext.checkboxgroup.RemoteCheckboxGroup,Ext.form.CheckboxGroup);
    Ext.reg('pd-checkboxgroup-locations',Ext.checkboxgroup.RemoteCheckboxGroup);
    The json returned as reported by Firebug (I can see I have an issue with the PHP at companyid, I just need to get this data into the window!)

    {"total":"3","results":[{"id":83,"companyid":0,"name":"new name","url":"","address":"","address2":"","city":"","state":"","zip":"","telephone":""},{"id":82,"companyid":0,"name":"steve test 2","url":"","address":"","address2":"","city":"","state":"","zip":"","telephone":""},{"id":81,"companyid":0,"name":"steve test 3-17-13","url":"","address":"","address2":"","city":"","state":"","zip":"","telephone":""}]}

  7. #7
    Sencha User
    Join Date
    May 2013
    Posts
    7
    Vote Rating
    0
    JustaCoder is on a distinguished road

      0  

    Default


    Can someone please help with this. All we need to do is get the JSON into the items array. We will gladly pay to solve this one thing.

  8. #8
    Sencha User
    Join Date
    May 2013
    Posts
    7
    Vote Rating
    0
    JustaCoder is on a distinguished road

      0  

    Default


    I've almost got it! The below code now dumps "items" in the console, items is populating, but still getting "this.items[0] is undefined" in ext.all.js. I just need one little push, anyone see it?

    The difference was adding the fields to the first config block.

    Code:
    Ext.namespace("Ext.checkboxgroup");
    Ext.checkboxgroup.RemoteCheckboxGroup = function(config,getStore) {
        config = config || {};
        
        Ext.applyIf(config,{
            fieldValue: 'id'
            ,fields: ["id", "name"]  
            ,items: []                                                                                                        
        });
        Ext.applyIf(config,{
            store: new Ext.data.JsonStore({
                url: ThisComponent.config.connectorUrl
                ,autoLoad: true 
                ,root: "results"
                ,totalProperty: 'total'
                ,fields: config.fields
                ,errorReader: MODx.util.JSONReader
                ,remoteSort: config.remoteSort || false
                ,autoDestroy: true
                ,baseParams: { 
                    action: "mgr/locations/getCheckboxList"
                    ,practice: ThisComponent.request.companyid
                }                                                                                                                                                                             
                ,listeners: {                                                                                              
                    load: function(t, records, options) {
                        items = [];                
                         for(var i = 0; i < records.length; i++) {                                                             
                               items.push({id: records[i].data.id, boxLabel: records[i].data.name});                                             
                         }  
                        console.log(items);                                                                                                                          
                    }                                                                                                                                  
                }
            })                                                                                                                           
        });
        if (getStore === true) {
           config.store.load();
           return config.store;
        }
        Ext.checkboxgroup.RemoteCheckboxGroup.superclass.constructor.call(this,config,getStore);
        this.config = config;
        return this;
    };
    Ext.extend(Ext.checkboxgroup.RemoteCheckboxGroup,Ext.form.CheckboxGroup);
    Ext.reg('this-component-checkboxgroup-locations',Ext.checkboxgroup.RemoteCheckboxGroup);

  9. #9
    Sencha User
    Join Date
    May 2013
    Posts
    7
    Vote Rating
    0
    JustaCoder is on a distinguished road

      0  

    Default


    I think I see it (doh.) items is only within the scope of the function in listeners->load. Close? How do I return it to the parent object?

Thread Participants: 2