0
votes

I have been encountering a problem when dynamically adding tabs to a tabpanel in ext 3.4. Here is the gist of what is going on:

  1. create tab panel
  2. add tabs with editor grid panel with proper editor defined in column model
  3. editor is bound to some fields on some tabs, but not all fields on all tabs

Anybody know what the issue might be?

I created the following plunk (very simple version of what I'm actually doing): Fiddle Here

Ext.onReady(function() {
  var scheduleRec = {
   "Sunday":[{"StartTimeHours":0,"StartTimeMinutes":0,"EndTimeHours":0,"EndTimeMinutes":0}],
    "Monday":[{"StartTimeHours":0,"StartTimeMinutes":0,"EndTimeHours":0,"EndTimeMinutes":0}],
    "Tuesday":[{"StartTimeHours":0,"StartTimeMinutes":0,"EndTimeHours":0,"EndTimeMinutes":0}],
    "Wednesday":[{"StartTimeHours":0,"StartTimeMinutes":0,"EndTimeHours":0,"EndTimeMinutes":0}],
    "Thursday":[{"StartTimeHours":0,"StartTimeMinutes":0,"EndTimeHours":0,"EndTimeMinutes":0}],
    "Friday":[{"StartTimeHours":0,"StartTimeMinutes":0,"EndTimeHours":0,"EndTimeMinutes":0}],
    "Saturday":[{"StartTimeHours":0,"StartTimeMinutes":0,"EndTimeHours":0,"EndTimeMinutes":0}],
  };

  //Build a schedule array...
  scheduleArray = [];
  if (scheduleRec) {
    for (srec in scheduleRec) {
      if (scheduleRec.hasOwnProperty(srec)) {
        if (typeof scheduleRec[srec] === 'object' && srec !== 'HolidaySets') {
          scheduleArray.push([srec, scheduleRec[srec]]);
        }
      }
    }
  }

  // simple array store
  var comboStore = new Ext.data.ArrayStore({
    fields: ['day', 'schedule'],
    data: scheduleArray
  });

  var fm = Ext.form;

  Ext.util.Format.timefieldRenderer = function(format) {
    return function(v) {
      if (v instanceof Date) {
        return v.format(format);
      } else {
        return v;
      }
    };
  };

  var cm = new Ext.grid.ColumnModel({
    defaults: {
      sortable: true
    },
    columns: [{
      header: 'Start Time',
      dataIndex: 'StartTime',
      format: 'H:i',
      width: 75,
      renderer: Ext.util.Format.timefieldRenderer('H:i'),
      editor: {
        xtype: 'timefield',
        format: 'H:i',
        increment: 1
      }
    }, {
      header: 'End Time',
      dataIndex: 'EndTime',
      format: 'H:i',
      width: 75,
      renderer: Ext.util.Format.timefieldRenderer('H:i'),
      editor: {
        xtype: 'timefield',
        format: 'H:i',
        increment: 1
      }
    }]
  });

  var createDate = function(H, M) {
    var tmpDate = new Date();
    tmpDate.setHours(H);
    tmpDate.setMinutes(M);
    return tmpDate;
  }

  var gridStoreFields = [{
    name: 'StartTime',
    type: 'date',
    convert: function(v, rec) {
      var tmpDate = createDate(rec.StartTimeHours, rec.StartTimeMinutes);
      return tmpDate;
    }
  }, {
    name: 'EndTime',
    type: 'date',
    convert: function(v, rec) {
      var tmpDate = createDate(rec.EndTimeHours, rec.EndTimeMinutes)
      return tmpDate;
    },
    format: 'H:i'
  }];

  var gridStore = new Ext.data.JsonStore({
    autoLoad: false,
    fields: gridStoreFields
  });

  var panel = new Ext.TabPanel({
    id: 'tabPanelId',
    activeTab: 0,
    height: 300,
    renderTo: Ext.getBody()
  });

  comboStore.each(function(records) {
    var theDay = records.get('day');

    var newStore = new Ext.data.JsonStore({
      storeId: theDay + 'Store',
      data: records.get('schedule'),
      autoLoad: false,
      fields: gridStoreFields
    });

    var newGrid = new Ext.grid.EditorGridPanel({
      id: theDay + 'Grid',
      xtype: 'editorgrid',
      height: 300,
      store: newStore,
      cm: cm,
      border: false,
      clicksToEdit: 1
    });

    Ext.getCmp('tabPanelId').add({
      title: theDay,
      items: newGrid
    });
  });
  Ext.getCmp('tabPanelId').setActiveTab(0);
});

Thanks in advance for your help.

I've verified in chrome dev tools that all of the dynamically created tabs have the correct grid id associated and that each grid has the correct storeId and correct editor bound in the column model.

EDIT: I did a little playing around with the fiddle, the problem appears to be that each field can be an editor field on exactly 1 grid at a time. For instance, if you edit field 1 on tab 1 and then edit field 2 on tab 2, field 2 is not editable on tab 1 and field 1 is not editable on tab 2.

1

1 Answers

0
votes

I figured it out after endless hours of tinkering today. I took the approach of independently declaring everything. Finally, when expanding out the column model, I arrived at the root of the issue. This plunk proves it!

There appears to be a bug when defining and re-using a column model containing editors. The workaround for me is to simply either define them in place or 'new' a column model object based on an object I've already defined.

Plunk Here

Ext.onReady(function() {
  Ext.util.Format.timefieldRenderer = function(format) {
    return function(v) {
      if (v instanceof Date) {
        return v.format(format);
      } else {
        return v;
      }
    };
  };

  var createDate = function(H, M) {
    var tmpDate = new Date();
    tmpDate.setHours(H);
    tmpDate.setMinutes(M);
    return tmpDate;
  }

  var panel = new Ext.TabPanel({
    id: 'tabPanelId',
    activeTab: 0,
    height: 300,
    items: [{
      title: 'Sunday',
      items: new Ext.grid.EditorGridPanel({
        id: 'sundayGrid',
        xtype: 'editorgrid',
        height: 300,
        store: new Ext.data.JsonStore({
          storeId: 'sundayStore',
          data: [{"StartTimeHours":0,"StartTimeMinutes": 0,"EndTimeHours":0,"EndTimeMinutes":0}],
          autoLoad: false,
          fields: [{
            name: 'StartTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.StartTimeHours, rec.StartTimeMinutes);
              return tmpDate;
            }
          }, {
            name: 'EndTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.EndTimeHours, rec.EndTimeMinutes)
              return tmpDate;
            },
            format: 'H:i'
          }]
        }),
        cm: new Ext.grid.ColumnModel({
          defaults: {
            sortable: true
          },
          columns: [{
            header: 'Start Time',
            dataIndex: 'StartTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }, {
            header: 'End Time',
            dataIndex: 'EndTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }]
        }),
        border: false,
        clicksToEdit: 1
      })
    }, {
      title: 'Monday',
      items: new Ext.grid.EditorGridPanel({
        id: 'mondayGrid',
        xtype: 'editorgrid',
        height: 300,
        store: new Ext.data.JsonStore({
          storeId: 'mondayStore',
          data: [{"StartTimeHours":0,"StartTimeMinutes": 0,"EndTimeHours":0,"EndTimeMinutes":0}],
          autoLoad: false,
          fields: [{
            name: 'StartTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.StartTimeHours, rec.StartTimeMinutes);
              return tmpDate;
            }
          }, {
            name: 'EndTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.EndTimeHours, rec.EndTimeMinutes)
              return tmpDate;
            },
            format: 'H:i'
          }]
        }),
        cm: new Ext.grid.ColumnModel({
          defaults: {
            sortable: true
          },
          columns: [{
            header: 'Start Time',
            dataIndex: 'StartTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }, {
            header: 'End Time',
            dataIndex: 'EndTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }]
        }),
        border: false,
        clicksToEdit: 1
      })
    }, {
      title: 'Tuesday',
      items: new Ext.grid.EditorGridPanel({
        id: 'tuesdayGrid',
        xtype: 'editorgrid',
        height: 300,
        store: new Ext.data.JsonStore({
          storeId: 'tuesdayStore',
          data: [{"StartTimeHours":0,"StartTimeMinutes": 0,"EndTimeHours":0,"EndTimeMinutes":0}],
          autoLoad: false,
          fields: [{
            name: 'StartTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.StartTimeHours, rec.StartTimeMinutes);
              return tmpDate;
            }
          }, {
            name: 'EndTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.EndTimeHours, rec.EndTimeMinutes)
              return tmpDate;
            },
            format: 'H:i'
          }]
        }),
        cm: new Ext.grid.ColumnModel({
          defaults: {
            sortable: true
          },
          columns: [{
            header: 'Start Time',
            dataIndex: 'StartTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }, {
            header: 'End Time',
            dataIndex: 'EndTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }]
        }),
        border: false,
        clicksToEdit: 1
      })
    }, {
      title: 'Wednesday',
      items: new Ext.grid.EditorGridPanel({
        id: 'wednesdayGrid',
        xtype: 'editorgrid',
        height: 300,
        store: new Ext.data.JsonStore({
          storeId: 'wednesdayStore',
          data: [{"StartTimeHours":0,"StartTimeMinutes": 0,"EndTimeHours":0,"EndTimeMinutes":0}],
          autoLoad: false,
          fields: [{
            name: 'StartTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.StartTimeHours, rec.StartTimeMinutes);
              return tmpDate;
            }
          }, {
            name: 'EndTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.EndTimeHours, rec.EndTimeMinutes)
              return tmpDate;
            },
            format: 'H:i'
          }]
        }),
        cm: new Ext.grid.ColumnModel({
          defaults: {
            sortable: true
          },
          columns: [{
            header: 'Start Time',
            dataIndex: 'StartTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }, {
            header: 'End Time',
            dataIndex: 'EndTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }]
        }),
        border: false,
        clicksToEdit: 1
      })
    }, {
      title: 'Thursday',
      items: new Ext.grid.EditorGridPanel({
        id: 'thursdayGrid',
        xtype: 'editorgrid',
        height: 300,
        store: new Ext.data.JsonStore({
          storeId: 'thursdayStore',
          data: [{"StartTimeHours":0,"StartTimeMinutes": 0,"EndTimeHours":0,"EndTimeMinutes":0}],
          autoLoad: false,
          fields: [{
            name: 'StartTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.StartTimeHours, rec.StartTimeMinutes);
              return tmpDate;
            }
          }, {
            name: 'EndTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.EndTimeHours, rec.EndTimeMinutes)
              return tmpDate;
            },
            format: 'H:i'
          }]
        }),
        cm: new Ext.grid.ColumnModel({
          defaults: {
            sortable: true
          },
          columns: [{
            header: 'Start Time',
            dataIndex: 'StartTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }, {
            header: 'End Time',
            dataIndex: 'EndTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }]
        }),
        border: false,
        clicksToEdit: 1
      })
    }, {
      title: 'Friday',
      items: new Ext.grid.EditorGridPanel({
        id: 'fridayGrid',
        xtype: 'editorgrid',
        height: 300,
        store: new Ext.data.JsonStore({
          storeId: 'fridayStore',
          data: [{"StartTimeHours":0,"StartTimeMinutes": 0,"EndTimeHours":0,"EndTimeMinutes":0}],
          autoLoad: false,
          fields: [{
            name: 'StartTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.StartTimeHours, rec.StartTimeMinutes);
              return tmpDate;
            }
          }, {
            name: 'EndTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.EndTimeHours, rec.EndTimeMinutes)
              return tmpDate;
            },
            format: 'H:i'
          }]
        }),
        cm: new Ext.grid.ColumnModel({
          defaults: {
            sortable: true
          },
          columns: [{
            header: 'Start Time',
            dataIndex: 'StartTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }, {
            header: 'End Time',
            dataIndex: 'EndTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }]
        }),
        border: false,
        clicksToEdit: 1
      })
    }, {
      title: 'Saturday',
      items: new Ext.grid.EditorGridPanel({
        id: 'saturdayGrid',
        xtype: 'editorgrid',
        height: 300,
        store: new Ext.data.JsonStore({
          storeId: 'saturdayStore',
          data: [{"StartTimeHours":0,"StartTimeMinutes": 0,"EndTimeHours":0,"EndTimeMinutes":0}],
          autoLoad: false,
          fields: [{
            name: 'StartTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.StartTimeHours, rec.StartTimeMinutes);
              return tmpDate;
            }
          }, {
            name: 'EndTime',
            type: 'date',
            convert: function(v, rec) {
              var tmpDate = createDate(rec.EndTimeHours, rec.EndTimeMinutes)
              return tmpDate;
            },
            format: 'H:i'
          }]
        }),
        cm: new Ext.grid.ColumnModel({
          defaults: {
            sortable: true
          },
          columns: [{
            header: 'Start Time',
            dataIndex: 'StartTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }, {
            header: 'End Time',
            dataIndex: 'EndTime',
            format: 'H:i',
            width: 75,
            renderer: Ext.util.Format.timefieldRenderer('H:i'),
            editor: {
              xtype: 'timefield',
              format: 'H:i',
              increment: 1
            }
          }]
        }),
        border: false,
        clicksToEdit: 1
      })
    }],
    renderTo: Ext.getBody()
  });

  Ext.getCmp('tabPanelId').setActiveTab(0);
});