3

I want to create my Model fields dynamically (in ExtJS 4). For instance, sometimes it is 0 to 3 and sometimes it is 0 to 7. This data comes from a JSON file (and store). This is my Model:

Ext.define('MyApp.model.User', {
    extend: 'Ext.data.Model',
    fields: ['0','1','2','3','4','5']
});

I tried many ways to get Model manually and create fields, but when it comes to a grid, I have empty rows of data without any errors. For example 8 empty rows in a grid.

Any help would be appreciated

Vahid
  • 3,384
  • 2
  • 35
  • 69
  • And what fields are coming from the server? And why exactly are they different each time? – sha Mar 23 '12 at 10:50
  • Thank you sha. JSON file contains Arrays of data and these are Array Indexes. They are different each time, because it is user define. – Vahid Mar 25 '12 at 15:13
  • [**Here's**](http://stackoverflow.com/a/10588523/1062992) an example of doing this following the MVC pattern with ExtJS 4.1 – egerardus May 14 '12 at 18:00

4 Answers4

6

I generate my model dynamically using the records returned by a store load callback. Here's how I create fields dynamically using the records.

roomTypesStore_Loaded: function (records) {
    var roomType;
    var fields = [
        { name: 'Id', type: 'int' },
        { name: 'Date', type: 'date' }
    ];

    for (var i = 0; i < records.length; i++) {
        roomType = records[i].data;
        fields[2 + (3 * i) + 0] = { name: roomType.Name + 'Rates', type: 'string' };
        fields[2 + (3 * i) + 1] = { name: roomType.Name + 'Selling', type: 'string' };
        fields[2 + (3 * i) + 2] = { name: roomType.Name + 'Booked', type: 'string' };
    }

    var model = {
        extend: 'Ext.data.Model',
        fields: fields
    };
    Ext.define('HEB.store.Schedule', model);
    var scheduleGrid = this.getScheduleGrid();
    var scheduleStore = this.getScheduleStore();
    if (scheduleGrid != null && scheduleStore != null) {
        scheduleGrid.reconfigure(scheduleStore, columns);
    }
},
JeeShen Lee
  • 3,476
  • 5
  • 39
  • 59
0

If you only need to set up the grid once, this appears to be working for me.

Define an array with column data first. Then define the grid. Assume that the input parameter columnData is an array with meta-data in it.

function createGrid(columnData) {
    var columns = [{
        header: 'Period',
        dataIndex: 'period'
    }];
    for (var i = 0; i < columnData.length; ++i) {
        var column = {
            header: columnData[i].headerLabel,
            dataIndex: columnData[i].fieldName
        };
        columns[columns.length] = column; //or `columns.push(column);`
    }

    workGrid = Ext.create('Ext.grid.Panel', {
        title: 'Scheduled Driver Work',
        store: workStore,
        columns: columns,
        height: 600,
        renderTo: Ext.getBody()
    });
}
jeremy
  • 9,965
  • 4
  • 39
  • 59
0
Ext.Loader.setConfig({
    enabled: true
});
Ext.Loader.setPath('Ext.ux', 'http://dev.sencha.com/deploy/ext-4.0.1/examples/ux');
Ext.require([
    'Ext.form.*',
    'Ext.data.*',
    'Ext.grid.*',
    'Ext.ux.grid.FiltersFeature',
    'Ext.layout.container.Column'
    ]);

// This data can be pulled off a back-end database
// Used to generate a model and a data grid
var records = [{
    data:{
        "dataIndex":"first",
        "name":"First Name",
        "type":"string"
    }
},{
    data:{
        "dataIndex":"last",
        "name":"Last Name",
        "type":"String"
    }
},{
    data:{
        "dataIndex":"email",
        "name":"Email",
        "type":"string"
    }
}];

// Lookup table (type => xtype)
var type_lookup = new Object;
type_lookup['int'] = 'numberfield';
type_lookup['float'] = 'numberfield';
type_lookup['string'] = 'textfield';
type_lookup['date'] = 'datefield';
type_lookup['boolean'] = 'checkbox';

// Skeleton store
var store_template = {
    autoLoad: true,
    autoSync: true,
    remoteFilter: false,

    // DATA is inserted here for the example to work on local drive (use proxy below)
    data:[{id:1,first:"Fred",last:"Flintstone",email:"fred@flintstone.com"},
          {id:2,first:"Wilma",last:"Flintstone",email:"wilma@flintstone.com"},
          {id:3,first:"Pebbles",last:"Flintstone",email:"pebbles@flintstone.com"},
          {id:4,first:"Barney",last:"Rubble",email:"barney@rubble.com"},
          {id:5,first:"Betty",last:"Rubble",email:"betty@rubble.com"},
          {id:6,first:"BamBam",last:"Rubble",email:"bambam@rubble.com"}],
    proxy: {
        type: 'rest',
        url: 'http://dev.sencha.com/deploy/ext-4.0.1/examples/restful/app.php/users',
        reader: {
            type: 'json',
            root: 'data'
        },
        writer: {
            type: 'json'
        }
    }
};

// Skeleton grid (_PLUGINS_ & _STORE_, are placeholders)
var grid_template = {
    columnWidth: 1,
    plugins: '_PLUGINS_',
    height: 300,
    store: '_STORE_'
}

// Skeleton window (_ITEMS_ is a placeholder)
var window_template = {
    title: 'Dynamic Model / Window',
    height: 400,
    width: 750,
    layout: 'fit',
    items: '_ITEMS_'
}

// Generate a model dynamically, provide fields
function modelFactory(name,fields){
    model =  {
        extend: 'Ext.data.Model',
        fields: fields
    };
    eval("Ext.define('"+name+"',"+Ext.encode(model)+");");
}

// Generate a dynamic store
function storeFactory(name,template,model){
    template.model = model;
    eval(name+" = Ext.create('Ext.data.Store',"+Ext.encode(template)+");");
}

// Generate a dynamic grid, .. store name is appended as a string because otherwise, Ext.encode
// will cause 'too much recursion' error (same for plugins)
function gridFactory(name,template,store,plugins){
    script =  name+" = Ext.create('Ext.grid.Panel', "+Ext.encode(template)+");";
    script = script.replace("\"_STORE_\"", store);
    script = script.replace("\"_PLUGINS_\"", plugins);
    eval(script);
}
// Generate a dynamic window, .. items are appended as a string to avoid Ext.encode error
function windowFactory(winName,winTemp,items){
    script += winName+" = Ext.create('Ext.window.Window',"+Ext.encode(winTemp)+").show();";
    script = script.replace("\"_ITEMS_\"", items);
    eval(script);
}

// Generate a model, a store a grid and a window dynamically from a record list!
function generateDynamicModel(records){

    fields = [{
        name: 'id',
        type: 'int',
        useNull:true
    }];

    columns = [{
        text: 'ID',
        sortable: true,
        dataIndex: 'id'
    }];

    for (var i = 0; i < records.length; i++) {

        fields[i+1] =  {
            name: records[i].data.dataIndex,
            type: records[i].data.type
        };

        columns[i+1] = {
            text: records[i].data.name,
            sortable: true,
            dataIndex: records[i].data.dataIndex,
            field:  {
                xtype: type_lookup[records[i].data.type]
            }
        };
    }

    grid_template.columns = columns;

    modelFactory('myModel',fields);
    storeFactory('myStore',store_template,'myModel');
    gridFactory('myGrid',grid_template,'myStore','[rowEditing]');
    windowFactory('myWindow',window_template,'[myGrid]');

    // Direct access to the store created above 
    myStore.load();
}

Ext.onReady(function(){
    rowEditing = Ext.create('Ext.grid.plugin.RowEditing');
    generateDynamicModel(records);
});

please See http://www.sencha.com/forum/showthread.php?136362-Extjs-4-Dynamic-Model

Akhil
  • 1,421
  • 1
  • 16
  • 21
0

Create a model with maximum number of fields (say from 0 to 15 if you know that 15 will be the max you will receive from the server).

ExtJs is very forgivable when model doesn't match server response exactly. You should still got records created, just some fields will be null.

sha
  • 17,824
  • 5
  • 63
  • 98