Results 1 to 2 of 2

Thread: Handle Associated Data in Grid, DataView and Form

  1. #1
    Ext JS Premium Member
    Join Date
    Jul 2008
    Miami, FL
    Vote Rating

    Default Handle Associated Data in Grid, DataView and Form

    Hey all,

    I am trying out ExtJS 4.2 and figured I would put in my 2 cents regarding how associations are handled.

    I know that the data package received a major update a while back and we now have hasOne and hasMany associations for a model, however displaying them or updating has been a little tricky for me.

    For example, I have a sample case (see below) of an Employee model that has a hasOne relation to a Person model, where the employee's name is stored in the Person model. If I try to display the data in a grid panel, I can only show the fields in the Employee model, not traverse the object graph and pull the employee's name from the Person model (of course assuming the data in the association has been pre-loaded).

        enabled: true
    Ext.Loader.setPath('Ext.ux', '../ux');
        // Define our data model
        Ext.define('Person', {
            extend: '',
            fields: [
        Ext.define('Employee', {
            extend: '',
            fields: [
                { name: 'start', type: 'date', dateFormat: 'n/j/Y' },
                { name: 'salary', type: 'float' },
                { name: 'active', type: 'bool' }
            associations: [
                {type: 'hasOne', model: 'Person', name: 'person'}
        // Generate mock employee data
        var data = (function() {
            var lasts = ['Jones', 'Smith', 'Lee', 'Wilson', 'Black', 'Williams', 'Lewis', 'Johnson', 'Foot', 'Little', 'Vee', 'Train', 'Hot', 'Mutt'],
                firsts = ['Fred', 'Julie', 'Bill', 'Ted', 'Jack', 'John', 'Mark', 'Mike', 'Chris', 'Bob', 'Travis', 'Kelly', 'Sara'],
                lastLen = lasts.length,
                firstLen = firsts.length,
                usedNames = {},
                data = [],
                s = new Date(2007, 0, 1),
                eDate = Ext.Date,
                now = new Date(),
                getRandomInt = Ext.Number.randomInt,
                generateName = function() {
                    var name = firsts[getRandomInt(0, firstLen - 1)] + ' ' + lasts[getRandomInt(0, lastLen - 1)];
                    if (usedNames[name]) {
                        return generateName();
                    usedNames[name] = true;
                    return name;
            while (s.getTime() < now.getTime()) {
                var ecount = getRandomInt(0, 3);
                for (var i = 0; i < ecount; i++) {
                    var name = generateName();
                        start : eDate.add(eDate.clearTime(s, true), eDate.DAY, getRandomInt(0, 27)),
                person: {
                            name : name,
                            email: name.toLowerCase().replace(' ', '.') + ''
                        active: getRandomInt(0, 1),
                        salary: Math.floor(getRandomInt(35000, 85000) / 1000) * 1000
                s = eDate.add(s, eDate.MONTH, 1);
            return data;
        // create the Data Store
        var store = Ext.create('', {
            // destroy the store if the grid is destroyed
            autoDestroy: true,
            model: 'Employee',
            proxy: {
                type: 'memory'
            data: data,
            sorters: [{
                property: 'start',
                direction: 'ASC'
        var rowEditing = Ext.create('Ext.grid.plugin.RowEditing', {
            clicksToMoveEditor: 1,
            autoCancel: false
        // create the grid and specify what field you want
        // to use for the editor at each column.
        var grid = Ext.create('Ext.grid.Panel', {
            store: store,
            columns: [{
                header: 'Name',
                dataIndex: '',
                flex: 1,
                editor: {
                    // defaults to textfield if no xtype is supplied
                    allowBlank: false
            }, {
                header: 'Email',
                dataIndex: '',
                width: 160,
                editor: {
                    allowBlank: false,
                    vtype: 'email'
            }, {
                xtype: 'datecolumn',
                header: 'Start Date',
                dataIndex: 'start',
                width: 90,
                editor: {
                    xtype: 'datefield',
                    allowBlank: false,
                    format: 'm/d/Y',
                    minValue: '01/01/2006',
                    minText: 'Cannot have a start date before the company existed!',
                    maxValue: Ext.Date.format(new Date(), 'm/d/Y')
            }, {
                xtype: 'numbercolumn',
                header: 'Salary',
                dataIndex: 'salary',
                format: '$0,0',
                width: 90,
                editor: {
                    xtype: 'numberfield',
                    allowBlank: false,
                    minValue: 1,
                    maxValue: 150000
            }, {
                xtype: 'checkcolumn',
                header: 'Active?',
                dataIndex: 'active',
                width: 60,
                editor: {
                    xtype: 'checkbox',
                    cls: 'x-grid-checkheader-editor'
            renderTo: 'editor-grid',
            width: 600,
            height: 400,
            title: 'Employee Salaries',
            frame: true,
            tbar: [{
                text: 'Add Employee',
                iconCls: 'employee-add',
                handler : function() {
                    // Create a model instance
                    var r = Ext.create('Employee', {
                        name: 'New Guy',
                        email: '',
                        start: Ext.Date.clearTime(new Date()),
                        salary: 50000,
                        active: true
                    store.insert(0, r);
                    rowEditing.startEdit(0, 0);
            }, {
                itemId: 'removeEmployee',
                text: 'Remove Employee',
                iconCls: 'employee-remove',
                handler: function() {
                    var sm = grid.getSelectionModel();
                    if (store.getCount() > 0) {
                disabled: true
            plugins: [rowEditing],
            listeners: {
                'selectionchange': function(view, records) {
    This code is simply a small modification to the row-editing example that comes with ExtJS and should be a drop-in replacement.

    This same issue applies to DataViews and Forms. I can load records into DataViews and Forms, but not their associated records.

    There has been various workarounds that more or less address this, such as:

    It would be nice however, if this worked out of the box.

    Any thoughts?



  2. #2
    Sencha User
    Join Date
    Jan 2013
    Vote Rating

    Default Handle Associated Data in Grid, DataView and Form

    Hey all,

    I also work with ExtJS 4.2 and use the advantages of hasOne relationships and hasMany associations for a model. But my work becomes complex when fields need models that do not relate directly.

    It's very similar to what Omar says, My main model is EventRequest and has a direct relationship with Event and this one has a direct relationship with EventActivity model. All is well in relating Events with EventRequest, the problem is when I need to pull fields from ActivityEvents to RequestEvent, because I can't do it and it causes me hard job. It would be good to make this update to make it more optimal use of ExtJS 4.2. It would be a great help! Thanks, Angie

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts