We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 25357
    • 92 Posts
    Revo 2.2.1
    Ext.js version: not sure (came with install)

    Task: get an Ext window to dynamically load checkboxes for possible locations for a worker in a company.

    I've no idea what I'm doing in Ext. I know enough to find out ModX doesn't have an inherent checkbox group object (or, not that I could find in this install) and that I'm totally lost trying to create one. undecided

    Checkbox GROUP - not checkbox.

    My connector action is returning valid JSON, I just can't get it to output the checkboxes. I have been to this and this and about a thousand other resources trying to solve this. Help would be appreciated.

    Here is what I have. In the below, "ThisComponent" is a component that was installed I'm trying to extend to include checkboxes. the "parentresource" is say, a company, with multiple locations. Each "worker" may have multiple locations. That is why the client requested checkboxes. This opens the "worker" update window.

    Window code (window opens fine):

    ThisComponent.window.UpdateResource = 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/doctors/update'
            ,fields: [{
                xtype: 'hidden'
                ,name: 'id'
                ,value: true
             },
              // My broken code. :-\
             {
                xtype: 'this-component-checkboxgroup-locations'
                ,fieldLabel: 'Locations'
    			,fieldValue: 'id'
    			,root: "results"
    			,url: PD.config.connectorUrl
    			,items: LocationsItems
    			,baseParams: { 
    				action: "mgr/locations/getCheckboxList"
    				,practice: ThisComponent.request.parentname
    			}
            },{
                 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.UpdateResource.superclass.constructor.call(this,config);
    };
    Ext.extend(ThisComponent.window.UpdateResource,MODx.Window, {});
    Ext.reg('this-component-window-doctor-update',ThisComponent.window.UpdateResource);
    


    The object model:

    This is probably where I'm making the mistake. I have fiddled with it a bit, when I uncomment the loop I get records is not defined (obviously.) I've no idea where the parameters come from. In it's current state, I get "this.proxy is undefined," but have had it connecting properly and responding with a JSON object. Just can't get the data into the window and checkboxes. undecided

    LocationsItems = [];
    Ext.namespace("Ext.checkboxgroup");
    Ext.checkboxgroup.RemoteCheckboxGroup = function(config) {
        config = config || {};
    	
    	var resourceStore = new Ext.data.JsonStore({
    		url: this.url                                                               
    		,root: "results"
    		,baseParams: this.baseParams
    		,fields: ["id", "name"]                   
    		,autoLoad: false                             
    		,listeners: {                            
            	load: function(t, records, options) {
    				// for(var i = 0; i < records.length; i++) {
    				//   LocationsItems.push({id: records[i].data.id, boxLabel: records[i].data.name});
    				// }                               
            	}                                     
    		}                                         
    	});                                                            
    	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);
    

    [ed. note: rocknbil last edited this post 13 years, 4 months ago.]
      • 4172
      • 5,888 Posts
      I think it should be much easier to create this same thing (your CMP) with help of MIGXdb.
      For the checkbox-group you could use a checkbox-TV-type with dynamic inputOptions (@EVAL - binding, @CHUNK - binding or @SELECT - binding)

        -------------------------------

        you can buy me a beer, if you like MIGX

        http://webcmsolutions.de/migx.html

        Thanks!
        • 25357
        • 92 Posts
        Thank you, and you have a sample and tutorial link for that, correct?
          • 25357
          • 92 Posts
          Still not solved, but approaching something usable with the following:

          PD.combo.Locations = function(config) {
              config = config || {};
              Ext.applyIf(config,{
                  name: 'locations'
                  ,hiddenName: 'locations'
                  ,displayField: 'name'
                  ,valueField: 'id'
          	,multiSelect: true // not creating a multiselect
                  ,fields: ['id','name']
                  ,url: ThisComponent.config.connectorUrl
          		,baseParams: { 
          			action: "mgr/locations/getCheckboxList"
          			,practice: ThisComponent.request.parentname
          		}
              });
              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);
          


          The pulls in the locations values, but the multiselect doesn't work. undecided
            • 4172
            • 5,888 Posts
              -------------------------------

              you can buy me a beer, if you like MIGX

              http://webcmsolutions.de/migx.html

              Thanks!
              • 25357
              • 92 Posts
              Well, thank you, but the issue is 1) that this component already has it's own extensions of Ext, 2) I don't see the advantage of investing the time to install yet another add on to find it won't work (I will likely break it or get something horribly wrong), and 3) this simple task is already too complicated. If I were coding outside this framework it would be done.

              All we need is the ability to multiple select locations. That is all, by checkboxes or multi-select, doesn't matter. I'm getting valid JSON responses, the combo box is populating, but the multiSelect config has no effect, and I cannot get the data to output checkboxes in the first example.

              I've determined the Ext version: 3.4.0. The docs say multiselect should work in 3.4, but it has no effect (maybe because I'm extending the Modx.combo object? Don't know.) Update to v4? Tried it, spent and hour chasing JS errors and rolled it back, it broke too much other stuff.

              Can someone kindly look at my code and give a little advice? It's THIS CLOSE ->||<-- to working!
                • 25357
                • 92 Posts
                Still hoping for a little help here, thank you.
                  • 4172
                  • 5,888 Posts
                  why are you asking for a tutorial and later you say:

                  1) that this component already has it's own extensions of Ext, 2) I don't see the advantage of investing the time to install yet another add on to find it won't work (I will likely break it or get something horribly wrong)

                  If I were coding outside this framework it would be done.
                  you can create CMPs also without using Ext or you can create something on the frontend or, if you want to use Ext in the manager, but have not the ext-knowledge, you can try to solve it with help of MIGXdb, or you can ask for help on the ext-forums for ext-related questions.
                    -------------------------------

                    you can buy me a beer, if you like MIGX

                    http://webcmsolutions.de/migx.html

                    Thanks!
                    • 25357
                    • 92 Posts
                    This component stands alone in modX, that is why. I can't take it out of the context of this component for a single checkbox group.

                    Almost there. I have items outputting to Firebug's console, getting ext error: "this.items[0] is undefined." SO CLOSE! undecided This is built off of the core modx combo box, as best as I can gather.

                    I can see that the scope of items[] is only with in the load: function, just can't figure out how to get it into the group element.

                    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.parentname
                    			}                                                                                                                                                                             
                    			,listeners: {                                                                                              
                            		load: function(t, records, options) {
                    					items = [];                
                    				 	for(var i = 0; i < records.length; i++) {   //console.log (records[i].data.id);                                                                
                    				   		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);
                    



                    The updated window code:

                    PD.window.UpdateResource = function(config) {
                    
                        this.ident = config.ident || 'pd-window-du';
                        Ext.applyIf(config,{
                            id: this.ident
                            ,width: 500
                            ,title: 'Update Worker'
                            ,url: PD.config.connectorUrl
                            ,action: 'mgr/workers/update'
                            ,fields: [{
                                xtype: 'hidden'
                                ,name: 'id'
                                ,value: true
                             },{
                                xtype: 'this-component-checkboxgroup-locations'
                                ,fieldLabel: 'Locations'
                    			,items: []
                            },{
                                 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
                             }]
                        });
                        ThisComonent.window.UpdateDoctor.superclass.constructor.call(this,config);
                    };
                    Ext.extend(ThisComponent.window.UpdateResource,MODx.Window, {});
                    Ext.reg('this-component-window-resource-update',ThisComponent.window.UpdateResource);
                    


                    Might have some typos in there as I tried to anonymize the code, but the target is this-component-checkboxgroup-locations.

                    What am I missing? I have JSON response, items is populating . .. why isn't it outputting checkboxes?
                      • 25357
                      • 92 Posts
                      Going to try this again. This project was developed by "experts" who promptly abandoned the client with the project incomplete and we're trying to make this work. I'm about to pitch the whole mess and put it on a different CMS. I really like modx except in situations like these where we really need help and it's total crickets.

                      We have paid Ext developers to look at this and it's still not solved. The issue now is that yes, we can get the checkboxes to load, but only externally from this component. This causes the data to load **too late** and doesn't render to the form.

                      The task is simple: when the EXT Update Worker window opens, Load all the locations for this division as checkboxes. We have the JSON returning data, all we need it to render it to the form.

                      Current status:

                      One developer got the data to load this way, by loading this in the base model file, external to the EXT definitions, making the array preload and global.
                      This **works**, but a) required we add an Ext.onReady line to header.php for the component, so it loads as the entire grid loads, and b) is useless if we can't check the boxes the worker (from the grid) is already registered with.

                      var glbl_locations_items = [{"boxLabel":"None"}];
                      
                      var glbl_locations_store = new Ext.data.JsonStore({
                      	//url: ThisComponent.config.connectorUrl // out of scope here, so we hard-coded to get it to work
                      	url:'/assets/components/this-component/connector.php'
                      	,autoLoad: false
                      	,root: "results"
                      	,totalProperty: 'total'
                      	,fields: ["id", "name"]
                      	,remoteSort: false
                      	,autoDestroy: true
                      	,baseParams: {
                      	     action: "mgr/workers/getCheckboxList"
                              ,parent_id: MODx.request.parentname // ditto, "thisComponent" not created yet
                      
                      	}
                      	,listeners: {
                      		load: function(t, records, options) { console.log('loadData');
                      			glbl_locations_items = [];
                      			for(var i = 0; i < records.length; i++) { //console.log (records[i].data.id);
                      				glbl_locations_items.push({id: records[i].data.id, boxLabel: records[i].data.name});
                      				console.log(' load items ' + records[i].data.name);
                      			}
                      			return glbl_locations_items;
                      		}
                      	}
                      });
                      


                      The changes to "Ext.namespace("Ext.checkboxgroup")" from the previous post lines 10-34:

                      	Ext.applyIf(config,{
                      		store: glbl_locations_store
                      	});
                      


                      The changes to "ThisComponent.window.UpdateResource" lines 15-17 from the previous post in our view window

                               {
                                  xtype: 'this-component-checkboxgroup-locations'
                                  ,fieldLabel: 'Locations'
                      			,items: glbl_locations_items
                              },{
                      


                      I attempted changing this (on click of the "Update" context menu)

                              if (!this.windows.updateWorker) {
                                  this.windows.updateDoctor = MODx.load({
                                      xtype: 'pd-window-doctor-update'
                                      ,record: r
                                      ,listeners: {
                                          ,'success': {fn:function(r) {
                                  			Ext.getCmp('pd-grid-doctors').getStore().load();
                                          },scope:this}
                                      }
                                  });
                              }
                      


                      to this, adding a listener

                              if (!this.windows.updateWorker) {
                                  this.windows.updateWorker = MODx.load({
                                      xtype: 'this-component-update'
                                      ,record: r
                                      ,listeners: {
                      					beforerender: { fn: function() {glbl_locations_store.load(); } }
                                          ,'success': {fn:function(r) {
                                  			Ext.getCmp('pd-grid-workers').getStore().load();
                                          },scope:this}
                                      }
                                  });
                              }
                      


                      Firebug still shows the JSON data loading perfectly - BUT TOO LATE. After the Update view renders.

                      I've tried at least two dozen other approaches to get this to work, we will gladly pay to get this off our plate. Can someone help out?