We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 34127
    • 135 Posts
    With Revolution on the way, I’ve really wanted to get some of my 096 snippets (and a module ) moved over to the new API. Recently I’ve been working on my poll system and actually have it in a state which I’d like to share it with the MODx community, and I just have a couple of finishing touches to put on it. I’m having trouble with two things in the Manager (both ExtJS problems), and knowing pretty much nothing about ExtJS, I was hoping I could get some help with them from here.

    First, I’m trying to make my action page in the manager tabbed. I have a single (untabbed) page working just fine - it loads a grid of polls into the manager where they can be manipulated. But trying to add tabbed functionality causes the entire page to break (it’s totally blank). Here’s my code for the ajaxpoll.js file:
    Ext.namespace('MODx', 'AjaxPoll');
    
    AjaxPoll = function(config) {
        config = config || {};
        Ext.applyIf(config,{
            base_url: MODx.config.context_url,
            connectors_url: MODx.config.context_url + 'core/connectors/',
            tabs: [{
            	contentEl: 'tab_polls',
            	title: _('polls')
            },
            {
            	contentEl: 'tab_tools',
            	title: _('tools')
            }],
            components: [{
            	xtype: 'grid-ajaxpoll',
            	el: 'grid_ajaxpolls'
            },
            {
            	xtype: 'panel-tools',
            	el: 'panel_tools'
            }]
        });
        
        AjaxPoll.superclass.constructor.call(this, config);
        this.config = config;
    };
    Ext.extend(AjaxPoll, Ext.Component, {
        config: {}
    });
    Ext.reg('ajaxpoll', AjaxPoll);
    
    AjaxPoll = new AjaxPoll();


    It seems like the following line is causing a problem with the tabbed interface:
    Ext.extend(AjaxPoll, Ext.Component, {

    And changing Ext.Component to MODx.component will cause the page to show up.... minus the grid. IS there any trick to getting tabs to work on a custom component?

    The second problem most likely has a simple solution... in two of my grids I use ComboBoxes for editors. I have displayField and valueField defined for them, but the valueField is being displayed in the grid instead of the displayField. Is there any simple way of fixing that?

    Thanks for any help you guys can give me!
      • 28215
      • 4,149 Posts
      Actually, your code will work better like this:

      var AjaxPoll = function(config) {
          config = config || {};
          Ext.applyIf(config,{
              base_url: MODx.config.context_url,
              connectors_url: MODx.config.context_url + 'core/connectors/',
              tabs: [{
              	contentEl: 'tab_polls'
              	,title: _('polls')
              },{
              	contentEl: 'tab_tools'
              	,title: _('tools')
              }],
              components: [{
              	xtype: 'grid-ajaxpoll',
              	renderTo: 'grid_ajaxpolls' // change el: to renderTo:
              },{
              	xtype: 'panel-tools',
              	renderTo: 'panel_tools'
              }]
          });
          AjaxPoll.superclass.constructor.call(this, config);
          // no need to set this.config, it's auto-set in MODx.Component
      };
      Ext.extend(AjaxPoll, MODx.Component);
      Ext.reg('ajaxpoll', AjaxPoll);
      
      // note that i changed this to ap, since otherwise
      // you are overwriting the class definition
      var ap = new AjaxPoll();


      (by the way, there is a MODx.config.connectors_url and MODx.config.base_url as well...)

      As for why the grid isn’t working...well, a lot of things.

      1. Is the HTML element you’re rendering to a <div> element?
      2. Is the JavaScript included _after_ the HTML element is defined?
      3. What errors are generated when the grid doesn’t render? What happens?

      As for the comboboxes as grid editors, make sure they extend MODx.combo.ComboBox. Other than that I’d have to see the code to give you any more help.

        shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
        • 34127
        • 135 Posts
        Quote from: splittingred at Aug 19, 2008, 03:48 AM

        Actually, your code will work better like this:

        var AjaxPoll = function(config) {
        ...
        var ap = new AjaxPoll();


        (by the way, there is a MODx.config.connectors_url and MODx.config.base_url as well...)
        Thanks, I’m new at this Ext stuff. tongue

        Quote from: splittingred at Aug 19, 2008, 03:48 AM

        As for why the grid isn’t working...well, a lot of things.

        1. Is the HTML element you’re rendering to a <div> element?
        2. Is the JavaScript included _after_ the HTML element is defined?
        3. What errors are generated when the grid doesn’t render? What happens?
        1. Yes.
        2. Yes, the JS is all at the end of the file.
        3. There’s actually one:
        Error: types[config.xtype || defaultType] is not a constructor
        Source File: http://localhost/revolution/manager/assets/ext2/ext-all.js
        Line: 12086


        The odd thing is that if I set the xtype to something like "textfield", the element (textfield) renders where it should... I’m wondering if maybe there’s something wrong with the definition of my polls grid (or just something that needs to be changed to be displayed in a tab)?
        AjaxPoll.grid.AjaxPoll = function(config){
            config = config || {};
            Ext.applyIf(config, {
                title: _('polls'),
                url: AjaxPoll.connectors_url + 'ajaxpoll.php',
        		paging: true,
                autosave: true,
                remoteSort: true,
                primaryKey: 'poll_id',
                fields: [{
        			name: 'poll_id',
        			type: 'int'
        		}, {
        			name: 'start_date',
        			type: 'date', 
        			dateFormat: 'timestamp'
        		}, {
        			name: 'topic',
        			type: 'string'
        		}, {
        			name: 'votes',
        			type: 'int'
        		}, {
        			name: 'status',
        			type: 'int'
        		}, {
        			name: 'menu'
        		}],
                columns: [{
                    header: _('poll_id'),
                    dataIndex: 'poll_id',
                    width: 50,
                    sortable: true
                }, {
                    header: _('start_date'),
                    dataIndex: 'start_date',
        			width: 100,
        			sortable: true,
        			renderer: Ext.util.Format.dateRenderer('M j, Y g:i A')
                }, {
                    header: _('topic'),
                    dataIndex: 'topic',
                    editor: { 
                    	xtype: 'textfield', 
                    	allowBlank: false 
                    },
        			sortable: true
                }, {
                    header: _('votes'),
                    dataIndex: 'votes',
        			width: 100,
        			sortable: true
                }, {
                    header: _('status'),
                    dataIndex: 'status',
                    width: 100,
        			sortable: true,
        			editor: { 
        				xtype: 'combo-ajaxpoll-status'
        			}
                }],
                tbar: [{
                    text: _('new_poll'),
                    handler: {
                        xtype: 'window-ajaxpoll-create',
                        blankValues: true
                    }
                }]
            });
            AjaxPoll.grid.AjaxPoll.superclass.constructor.call(this, config);
        };
        Ext.extend(AjaxPoll.grid.AjaxPoll, MODx.grid.Grid, {
        	update: function(itm, e){
        		//
        	}
        });
        Ext.reg('grid-ajaxpoll', AjaxPoll.grid.AjaxPoll);


        Thanks for your help!
          • 28215
          • 4,149 Posts
          Actually, your code needs to be:

          editor: { 
          	xtype: 'combo-ajaxpoll-status'
          	,renderer: true
          }
          


          The combo-in-a-grid editor isn’t a built-in feature of Ext; we’ve added it in our MODExt implementation. The ’renderer’ parameter tells the wrapper grid class to render a combo-editor there. It has a couple values: true, if you’re using a class that extends MODx.combo.ComboBox, or ’boolean’ if you want it to render a Yes/No combo when used in conjunction with the ’combo-boolean’ xtype.
            shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
            • 34127
            • 135 Posts
            Got it, thanks a bunch! The grid now loads as it should, and the tabs are working (yay)! laugh

            I’m still having trouble with the ComboBox though. When I extend MODx.combo.ComboBox I keep getting the error "this.proxy is undefined". The stores for my ComboBoxes are local JS arrays which work when I extend Ext.form.ComboBox, but it seems that MODx.combo.ComboBox uses an ajax request to populate the store, even when mode is set to ’local’. Here’s the code for my ComboBox if it helps at all:
            AjaxPoll.combo.PollStatus = function(config) {
            	config = config || {};
            	Ext.applyIf(config, {
            		name : 'status',
            		hiddenName : 'status',
            		displayField : 'name',
            		valueField : 'id',
            		triggerAction : 'all',
            		mode : 'local',
            		editable : false,
            		width : 150,
            		store : new Ext.data.SimpleStore({
            			fields : ['id', 'name'],
            			data : [['0', _('closed')], ['1', _('open')], ['2', _('hidden')]]
            		})
            	});
            	AjaxPoll.combo.PollStatus.superclass.constructor.call(this, config);
            };
            Ext.extend(AjaxPoll.combo.PollStatus, MODx.combo.ComboBox);
            Ext.reg('combo-ajaxpoll-status', AjaxPoll.combo.PollStatus);
              • 28215
              • 4,149 Posts
              Seemed to have been an oversight. I’ve committed a fix in r3958 in SVN...in the meantime, if you want to apply the fix manually, change line 60 of manager/assets/modext/ui/combos.js from:

                      if (this.isLoaded || b == true) {


              to:

                      if (this.isLoaded || b == true || this.mode == 'local') {
                shaun mccormick | bigcommerce mgr of software engineering, former modx co-architect | github | splittingred.com
                • 34127
                • 135 Posts
                Thanks, your fix for loading local combos worked perfectly, but the actual displayField still isn’t showing up in the grid. I ended up just using a quick custom render function to do it instead:

                function comboGridRenderer(value) {
                    var record = statusStore.getById(value);
                    
                    return record ? record.data.name : value;
                }


                Thanks again for all your help!