Friday, February 24, 2012

Sencha touch Error - TypeError: 'undefined' is not an object (evaluating 'o.id')

Hello,

If you are working with Sencha touch 2 or earlier versions you might had below mentioned error while working with list or selectfield

TypeError: 'undefined' is not an object (evaluating 'o.id')


Normally this error displayed when you are trying to select some old records in list or selectefield. For example you have a list on the form or a panel to select some records which you are saving in database and in case of edit you want to show last selected records. So we normally add code to select records on refresh. Something like below.


myList.on('refresh', function () {
                for (var i = 0; i < userSelectedRecords.getCount(); i++) {
                    var record =  userSelectedRecords .getAt(i);
                        var recordIndex =  myList .store.find('idField',  record.get('idField'));
                         myList .getSelectionModel().select(recordIndex, true, false);
                }
        },
        this,
        { single: true }
);


In above code last selected records are stored in userSelectedRecords and we are fetching records from it and selecting respective record in list. Now above refresh method fired two times. First when the list container like panel is rendered and second time when list store loaded with data. And as we all know sencha touch store load is asyc method so if you simply adding following line just above the refresh event handler this error is likely to come. Because by the time refresh event fired store load is still going on. Particularly this happens if you are loading store using Ajax proxy. Some time this error breaks your layout and freezes the panel. You don't have other option than reloading the app. To prevent this you can simply add store count check in refresh so first time when panel is rendered if store load it not complete, it will not try to select data. It will select it when store load completes.

Following is the code.


myList.on('refresh', function () {
               if(myList.store.getCount()>0)
                       for (var i = 0; i < userSelectedRecords.getCount(); i++) {
                            var record =  userSelectedRecords .getAt(i);
                             var recordIndex =  myList .store.find('idField',  record.get('idField'));
                             myList .getSelectionModel().select(recordIndex, true, false);
                       }
                }
        },
        this,
        { single: true }
);

Please note above code will work for sencha touch 1.1 and earlier version. For later versions you can do that check in controllers action.

Hope this helps you.

Friday, February 10, 2012

Sencha touch 2.0 Panel Align Button Left and Right

Hello,

Recently I was working with Sencha touch 2.0 and I had a requirement to align buttons in panel. One button should be left side and other should be on right side. Something like image below.


This is easily possible if we use toolbar. check the following code.


{
   xtype: 'panel',
   dockedItems: [{
                             xtype: 'toolbar',
                             docked: 'bottom',
                             items: [{
                                           xtype: 'button',
                                           text: 'Multiple Choice',
                                           ui: 'confirm'
                                        }, {
                                           xtype:'spacer'
                                        }, {
                                           xtype: 'button',
                                           text: 'Sort and Match',
                                           ui: 'confirm'
                              }]
              }]
}

But what if you have to use panel. You can use hbox layout to align buttons horizontally but how can we have gap between them because spacer will not work in panel. You can use flex property here. Check the following code.


{
    xtype: 'panel',
    layout: 'hbox',
    title: 'Play Game',
    items: [{
                  xtype: 'button',
                  text: 'Multiple Choice',
                  ui: 'confirm',
                  flex: 0.3
                }, {
                  xtype:'panel',
                  flex: 0.4
                }, {
                  xtype: 'button',
                  text: 'Sort and Match',
                  ui: 'confirm',
                  flex: 0.3
        }]
}

It will give you following output.


That's it and you have desired output.