1. #1
    Sencha User
    Join Date
    Jan 2012
    Location
    New York City
    Posts
    109
    Answers
    1
    Vote Rating
    2
    infernoz is on a distinguished road

      0  

    Default Unanswered: Error (a is null, d is undefined) related to store and gridpanel

    Unanswered: Error (a is null, d is undefined) related to store and gridpanel


    Hello,

    I have a gridpanel that is backed by a store. I have methods available to populate the store (and by associated the grid) via server requests.

    I noticed that when records are in the grid and I click any of them with my mouse, the next time I try to remove all elements and refresh the store/grid with new data, or possibly just clear all data. I receive the following errors:

    In Firefox 12

    first error I receive
    a is null


    ...MouseUp:function(k){var j=this,a=j.getEventXY(k),b=j.series.items,d,h,c,g;if(j.e...

    second error
    d is undefined


    ...MouseUp:function(k){var j=this,a=j.getEventXY(k),b=j.series.items,d,h,c,g;if(j.e...

    In IE
    Webpage error details

    User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; InfoPath.3; MS-RTC LM 8)
    Timestamp: Fri, 18 May 2012 22:25:51 UTC

    First Error received
    Message: 'viewIndex' is null or not an object
    Line: 21
    Char: 676249
    Code: 0
    URI: http://localhost:8080/extjs/ext-all.js

    Second Error
    Message: 'undefined' is null or not an object
    Line: 21
    Char: 941412
    Code: 0
    URI: http://localhost:8080/extjs/ext-all.js

    To reiterate, this only occurs after I click on the grid panel. Here is my store, grid panel, and form (which contains logic to reset and repopulate the grid). I tried changing my calls to store.removeAll(false) to true but this did not solve the issue.

    //store
    Code:
    Ext.define('DMT.store.OrgStatisticsStore', {
         extend: 'Ext.data.Store',
         model: 'DMT.model.OrgStatisticsModel',
         alias : 'widget.OrgStatisticsStore',
         storeId: 'orgStatisticsStore',
    
         proxy: {
             type: 'ajax',
             url: '/DMT/submit.html',
             reader: {
                 type: 'json',
                 root: 'data'
             },
             writer: {
                 type: 'json',
                 root: 'data',
                 encode: true,
                 writeAllFields: true
             },
             extraParams: {'processorType': 'orgStatistics'}
         }
     });
    //grid
    Code:
    Ext.require(['Ext.window.MessageBox',
                  'DMT.view.OrgStatisticsSearchForm']);
    
     Ext.define('DMT.view.OrgStatisticsView' ,{
         extend: 'Ext.grid.Panel',
         alias : 'widget.orgStatisticsView',
         id: 'orgStatisticsView',
         store: 'OrgStatisticsStore',
         selType: 'cellmodel',
         layout: 'fit',
      
         /*, renderer: Ext.util.Format.dateRenderer('n/j/Y G:i:s')*/
         initComponent: function() {
             currentView = this;
             
             var orgStatisticsStore = Ext.data.StoreManager.lookup('OrgStatisticsStore');
             var orgStatisticsProxy = orgStatisticsStore.getProxy();
             
              Ext.apply(this, {
                  plugins: [{
                         ptype: 'cellediting',
                         clicksToEdit: 1
                     }],
                     
                 columns: {
                     items: [{header: 'ID', dataIndex: 'id', hidden: true, hideable: false},
                           {header: 'a_ID', dataIndex: 'a',  hideable: false},
                           {header: 'b_ID', dataIndex: 'b',  hideable: true},
                           {header: 'c_ID', dataIndex: 'c', hideable: true},
                           {header: 'd_ID', dataIndex: 'd',   hideable: true},
                           {header: 'e_ID', dataIndex: 'e', hideable: true},
                           {header: 'f_ID', dataIndex: 'f',  hideable: true},
                           {header: 'g_ID', dataIndex: 'g', hideable: true},
                           {header: 'ID_TYPE', dataIndex: 'idtype', hidden: true, hideable: false},
                           {header: 'DATA_SOURCE_ID', dataIndex: 'DataSourceId', hidden: true, hideable: false},
                           {header: 'START_DATE', dataIndex: 'startDate', hidden: true, hideable: false},
                           {header: 'END_DATE', dataIndex: 'endDate', hidden: true, hideable: false},
                           {header: 'UPDATE_DATE', dataIndex: 'updateDate', hidden: true, hideable: false},
                           {header: 'UPDATE_ID', dataIndex: 'updateId', hidden: true, hideable: false},
                           {header: 'STAT_CODE', dataIndex: 'statCode', /*width: 170,*/ flex: 3, hideable: false},
                           {header: 'STAT_VALUE', dataIndex: 'statValue', /*width: 170,*/ flex: 3, editor: 'textfield', hideable: false},
                           {header: 'DELETE', dataIndex: 'deleteRow', xtype: 'checkcolumn', /*width: 60*/ flex: 1, /*maxWidth: 60,*/ editor: 'checkbox', sortable: false, hideable: false}
                 ],
                     defaults: {
                         flex: 2
                     }
                 },
                 dockedItems: [{
                     xtype: 'toolbar',
                     dock: 'top',
                     ui: 'footer',
                     layout: {
                         type: 'hbox',
                         pack: 'start',
                         align: 'middle'
                     },
                     items: [
                         //Form which user can search for org stats data
                         {xtype: 'orgStatisticsSearchForm', width: 380, height: 110, x:0, y:10,
                             listeners: { 'afterrender': function() {
                                 orgSearchForm = this;
                                 searchButton = orgSearchForm.getComponent('orgStatsSearchButton');
                             }}},
                         
                         //Sends updates
                         { xtype: 'button', text: 'Submit', width: 80, maxWidth: 80,
                             initComponent: function() {
                                 submitButton = this;
                             },
                             listeners: {
                                 'click': function() {
                                     orgStatisticsStore.on({
                                         scope: currentView,
                                         beforesync: currentView.disableButtons,
                                         write: currentView.submitFinished
                                     });
                                     orgStatisticsProxy.on({
                                         scope: currentView,
                                         exception: currentView.showSubmitError
                                     });
                                     
                                     orgStatisticsStore.sync();
                             }}},
                             
                         //Clears all data from grid
                         { xtype: 'button', text: 'Clear', width: 80, maxWidth: 80,
                             initComponent: function() {
                                 clearButton = this;
                             },
                             listeners: {
                             'click': function() {
                                 currentView.disableButtons();
                                 orgStatisticsStore.removeAll(false);
                                 currentView.enableButtons();
                             }
                         }}
                     ]
                 }]
              });
             
             this.callParent(arguments);
         },
         
         /**
          * Function to disable all buttons in panel
          */
         disableButtons: function(){
             submitButton.disable(true);
             clearButton.disable(true);
             searchButton.disable(true);
            },
            
         /**
          * Function to enable all buttons in panel
          */
            enableButtons: function(){
                submitButton.enable(true);
                clearButton.enable(true);
             searchButton.enable(true);
            },
            
            /**
             * Function encapsulating the message that should be shown to users after
             * a submit button response comes back from server successfully
             */
            submitFinished: function() {
                var messageBox = Ext.Msg.show({
                    title:'DMT Response',
                    msg: 'Changes have been successfully sent',
                    animateTarget: submitButton,
                    icon: Ext.Msg.INFO,
                    closable: false
                });
    
                setTimeout(function(){
                    messageBox.close();
                }, 2700);
    
                currentView.enableButtons();
            },
            
          /**
             * Function encapsulating the message that should be shown to users after
             * a submit button response comes back from server with a failure :(
             */
            showSubmitError: function() {
                var errorMessageBox = Ext.Msg.show({
                    title:'DMT Response',
                    msg: 'An error has occured while sending changes. Please contact support or try again.',
                    animateTarget: submitButton,
                    icon: Ext.Msg.ERROR,
                    closable: false
                });
    
                setTimeout(function(){
                    errorMessageBox.close();
                }, 2700);
                
                currentView.enableButtons();
            }
     });
    //form - which allows searches and populates the grid panel with the search results
    Code:
    Ext.require(['DMT.view.OrgComboBox',
                  'DMT.view.IssueIdMultiSearchData']);
    
     Ext.define('DMT.view.OrgStatisticsSearchForm' ,{
         extend: 'Ext.form.Panel',
         alias : 'widget.orgStatisticsSearchForm',
         defaultType: 'textfield',
         border: false,
         layout: 'absolute',
         
         initComponent: function () {
             multiIdSearchArray = new Array();
             this.callParent(arguments);
             currentForm = this;
         },
            
         items: [
             { xtype: 'hiddenfield', name: 'processorType', value: 'orgStatisticsSearch'},
             { xtype: 'textfield', fieldLabel: 'Issue Id', name: 'issueId',
                 validateOnChange: false,
                 validateOnBlur: false,
                 x:0, y:0, width: '250',
                 
                 //override validation for textfield
                 validator: function(value){
                     
                     //value of text field doesnt matter if multi search is being done
                     if (multiIdSearchArray.length != 0) {
                         return true;
                     }
                     
                     //value of text field is fine if its trimed value is not blank
                     if (Ext.String.trim(value) != '') {
                         return true;
                     }
    
                     //Failed validation otherwise
                     return 'Issue Id is required if Multi Id Search param is blank';
                 }
             },
             {    xtype: 'orgComboBox',
                 name: 'idType',
                 width: 250,
                 x:0,
                 y:25
             },
             
             //Button used to submit search to server and return results to org statistics grid panel
             { xtype: 'button', id: 'orgStatsSearchButton', text: 'Search', width: 80, x:275, y:23,
                 handler: function() {
                     var form = this.up('form').getForm();
                     if (form.isValid()) {
                         form.submit({scope: this, waitMsg:'Searching', url: '/DMT/search.html',
                             params: {issueArray: multiIdSearchArray},
                             success: function(form, action) {
                                 
                                 var total = action.result.total;
                                 if (total == 0) {
                                     Ext.Msg.show({
                                         title:'DMT Search',
                                         msg: 'No data returned from search',
                                         animateTarget: this,
                                         icon: Ext.Msg.WARNING,
                                         buttons: Ext.Msg.OK
                                  });
                                 }
                                 else {
                                     var orgStatisticsStore = Ext.data.StoreManager.lookup('OrgStatisticsStore');
                                     orgStatisticsStore.removeAll(true);
                                     orgStatisticsStore.add(action.result.data);
                                 }
                             },
                             failure: function(form, action) {
                                 Ext.Msg.show({
                                        title:'DMT Search',
                                        msg: 'An error has occured while searching for data. Please contact support or try again.',
                                        animateTarget: this,
                                        icon: Ext.Msg.ERROR,
                                        buttons: Ext.Msg.OK
                                 });
                             }
                         });
                     }
                 }
             },
             
             //Used to search for multiple org statistics at once. If this field is populated,
             //it will override the search parameter that is specified in the text field above
             {
                 xtype     : 'textareafield',
                 name      : 'Multi Id Search',
                 fieldLabel: 'Multi Id Search',
                 readOnly: true,
                 autoScroll: true,
                 width: 250,
                 height: 60,
                 listeners: {
                     'focus': function() {
                         if (multiIdSearchArray.length > 1) {
                             var someStuff = multiIdSearchArray[0];
                             var text = someStuff.issueId;
                         }
                         someWindow = Ext.widget('issueIdMultiSearchWindow', {
                             parentForm: currentForm
                         });
                         someWindow.show();
                     }
                 },
                 x:0, y:50
             }
         ],
         
         //Returns the array holding the multi search parameters that will searched
         getMultiSearchArray: function () {
             return multiIdSearchArray;
         },
         
         //Sets the textfield area and the array multiIdSearchArray in this form
         setMultiSearchArray: function (multiSearchArray) {
             var multiSearchTextArea = this.down('textareafield');
             var newTextValue = '';
             
             Ext.each(multiSearchArray, function(searchData, index, arrayItSelf) {
                 var issue = searchData.issueId;
                 
                 if (newTextValue !== '') {
                     newTextValue = newTextValue + '\n';
                 }
                 newTextValue = newTextValue + issue
               });
             
             multiSearchTextArea.setValue(newTextValue);    
             multiIdSearchArray = multiSearchArray;
         }
     })
    Thanks,

    infernoz

  2. #2
    Sencha - Support Team scottmartin's Avatar
    Join Date
    Jul 2010
    Location
    Houston, Tx
    Posts
    9,000
    Answers
    666
    Vote Rating
    456
    scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future scottmartin has a brilliant future

      0  

    Default


    Have you tried tracing through you code .. in your listeners to see where it is getting lost?

    Regards,
    Scott.

  3. #3
    Sencha User
    Join Date
    Jan 2012
    Location
    New York City
    Posts
    109
    Answers
    1
    Vote Rating
    2
    infernoz is on a distinguished road

      0  

    Default


    I switched to ext-all-debug from ext-all and traced the code a bit. I'm getting a different error with ext-all-debug, which is 'node is null'.

    It seems that the issue is coming about when I call orgStatisticsStore.add(action.result.data) in my form. The trace for this is below (a bit messy, I apologize though I'm not sure of a better way of presenting).

    Code:
    node is null
    indexOf()ext-all-debug.js (line 61788)node = null
    
    
    
    setPosition()ext-all-debug.js (line 83844)row = Object { phantom=false,  internalId="ext-record-32",  data={...},  more...}
    col = Object { dataIndex="statValue",  flex=3,  hideable=false,  more...}
    
    
    
    onViewRefresh()ext-all-debug.js (line 83800)
    fire()ext-all-debug.js (line 8586)
    continueFireEvent()ext-all-debug.js (line 24623)eventName = "refresh"
    args = [Object { deferInitialRefresh=true,  scroll=true,  xtype="gridview",  more...}]
    bubbles = undefined
    
    
    
    fireEvent()ext-all-debug.js (line 24601)eventName = "refresh"
    
    
    
    fireEvent()ext-all-debug.js (line 57133)ev = "refresh"
    
    
    
    refresh()ext-all-debug.js (line 61364)
    callParent(args=[])ext-all-debug.js (line 3728)
    refresh()ext-all-debug.js (line 103408)
    callParent(args=[])ext-all-debug.js (line 3728)
    refresh()ext-all-debug.js (line 105748)
    onAdd()ext-all-debug.js (line 61505)ds = Object { data={...},  groupers={...},  storeId="OrgStatisticsStore",  more...}
    records = [Object { phantom=false,  internalId="ext-record-37",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-38",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-39",  data={...},  more...}, 5 more...]
    index = 0
    
    
    
    callParent()ext-all-debug.js (line 3728)args = [Object { data={...},  groupers={...},  storeId="OrgStatisticsStore",  more...}, [Object { phantom=false,  internalId="ext-record-37",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-38",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-39",  data={...},  more...}, 5 more...], 0, Object { scope={...},  refresh=function(),  add=function(),  more...}]
    
    
    
    onAdd()ext-all-debug.js (line 106080)ds = Object { data={...},  groupers={...},  storeId="OrgStatisticsStore",  more...}
    records = [Object { phantom=false,  internalId="ext-record-37",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-38",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-39",  data={...},  more...}, 5 more...]
    index = 0
    
    
    
    fire()ext-all-debug.js (line 8586)
    continueFireEvent()ext-all-debug.js (line 24623)eventName = "add"
    args = [Object { data={...},  groupers={...},  storeId="OrgStatisticsStore",  more...}, [Object { phantom=false,  internalId="ext-record-37",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-38",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-39",  data={...},  more...}, 5 more...], 0]
    bubbles = undefined
    
    
    
    fireEvent()ext-all-debug.js (line 24601)eventName = "add"
    
    
    
    insert()ext-all-debug.js (line 50005)index = 0
    records = [Object { phantom=false,  internalId="ext-record-37",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-38",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-39",  data={...},  more...}, 5 more...]
    
    
    
    add()ext-all-debug.js (line 50046)records = [Object { phantom=false,  internalId="ext-record-37",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-38",  data={...},  more...}, Object { phantom=false,  internalId="ext-record-39",  data={...},  more...}, 5 more...]
    The add event that updates the data calls the event add which seems to screw up when it is looking for a valid row in the setPosition() function:

    else if (row.isModel) { me.record = row;
    me.row = view.indexOf(row); -- row ends up being null....

    }

    This definitely has something to do with the fact that I am calling removeAll() prior to adding the records, but I cant pinpoint why.

    P.S. I'm using ExtJS 4.1.0

    Cheers,

    infernoz
    Last edited by infernoz; 21 May 2012 at 1:57 PM. Reason: changing ext version to 4.1.0 instead of 4.10

  4. #4
    Sencha User
    Join Date
    Jan 2012
    Location
    New York City
    Posts
    109
    Answers
    1
    Vote Rating
    2
    infernoz is on a distinguished road

      0  

    Default


    What I believe solved the issue discussed above was adding the call gridPanel.getSelectionModel().deselectAll() after removing all rows from the grid via store.removeAll(false). I also added the same call prior to calling sync() on the store associated with the grid, though I dont know if this is needed.

    If someone could tell me why this call is needed, or if this is the right way to solve my issue, your enlightenment is appreciated. But, in any case my a is null errors are no longer appearing.

    Cheers,

    infernoz

Thread Participants: 1

Tags for this Thread