Dynamically Loading Ext.NestedList

After developing the USGS earthquake for mobile, I want to extend it to display more information. One of the challenge I faced was how to dynamically load data into the nested list. I did a bit reading in the forum and someone suggested to implement the following.

var nestedList = new Ext.NestedList({
items: []
});

var list = [
{
text: 'Test'
},{
text: 'Test 2'
}];

nestedList.setList(list, true);

I did try out to use setList(), however I noticed a problem when I clicked the back button. The nested list still remember the original “items” which was set to blank or []. It is correct that setList() will rebuild the entire list, however in this instance it is not the right method to use. One thing to highlight is the setList() is called when item is tapped and when we click back button, however everytime it is called the new list is appended to the end of the collection as shown in the code below. As we tap the item and click back, the index counter become wrong.

if (!this.lists.contains(list)) {
this.lists.push(this.add(list));
}

I will cover 2 scenarios related to this topic:

  1. Dynamically load nested list after the UI is launched.
  2. Dynamically load list when item is tapped.

The alternative solution to dynamically set the nested list is to extend the original object and implement a new method “reset” as shown below. Perform exactly as It is in setList() but instead of joining the list, reset it. This will address scenario 1.

Ext.ws.NestedList = Ext.extend(Ext.NestedList, {
resetList : function(list, init) {
//...
if (!this.lists.contains(list)) {
this.lists[0] = this.add(list);
}
//...
},

onItemTap : function(item) {
//...
}
});

In order to address scenario 2, override the onItemTap() as shown below. In this example, I added a new attribute “fid” into the item which helps to decide what data to load. In your implementation you might call JSONP request to load the data.

Ext.ws.NestedList = Ext.extend(Ext.NestedList, {
resetList : function(list, init) {
//...
},

onItemTap : function(item) {
item.el.radioClass('x-item-selected');
if (item.items) {
this.backButton.show();
if (item.fid == 'A') item.items = [ {text: 'List Z.1'} ];
this.setList(item);
this.listIndex++;
}
this.fireEvent('listchange', this, item);
}
});

The following is the full source code used to demonstrate the 2 scenarios. If you have alternative solution to the above, do drop me comment and share it. 🙂

<script type="text/javascript">

Ext.ns('Ext.ws');

Ext.ws.NestedList = Ext.extend(Ext.NestedList, {
resetList : function(list, init) {
var items = init ? list : list.items;
if (!list.isList) {
list = new Ext.Container({
isList: true,
baseCls: 'x-list',
cls: 'x-list-flat',
defaults: {
xtype: 'button',
baseCls: 'x-list-item',
pressedCls: 'x-item-pressed',
ui: null,
pressedDelay: true
},
listeners: {
afterrender: function() {
this.getContentTarget().addClass('x-list-parent');
}
},
scroll: 'vertical',
items: items,
text: list.text
});
}

this.lists = this.lists || [];
if (!this.lists.contains(list)) {
this.lists[0] = this.add(list);
}

var isBack = (this.lists.indexOf(list) < this.lists.indexOf(this.activeItem));
if (this.rendered) {
this.setCard(list, init ? false : {
type: this.animation,
reverse: isBack
});
}
this.activeItem = list;
},

onItemTap : function(item) {
item.el.radioClass('x-item-selected');
if (item.items) {
this.backButton.show();
if (item.fid == 'A') item.items = [ {text: 'List Z.1'} ];
this.setList(item);
this.listIndex++;
}
this.fireEvent('listchange', this, item);
}
});

Ext.setup({
onReady: function() {

var list = [ {text: 'List A', fid: 'A', items: [] },
{text: 'List B', fid: 'B', items: [ {text: 'List B.1'} ] },
{text: 'List C', fid: 'C', items: [ {text: 'List C.1'} ] }
];

var nestedList = new Ext.ws.NestedList({
items: [],
fullscreen: true
});

nestedList.resetList(list, true);

} // end onReady
}); // end ext.setup

</script>

Update: the example above was based on Sencha Touch 0.91

Advertisements

2 thoughts on “Dynamically Loading Ext.NestedList”

  1. Thanks for posting this!

    I’m having a problem loading json data, here’s test.json:

    [ {“text”: ‘List A’, fid: ‘A’, items: [] } ]

    And the lines I changed:

    var makeAjaxRequest = function() {
    Ext.Ajax.request({
    url: ‘test.json’,
    success: function(response, opts) {
    nestedList.setList(response.responseText);
    }
    })
    };

    Ext.setup({
    onReady: function() {

    var list = [ {“text”: ‘List A’, fid: ‘A’, items: [] },
    {text: ‘List B’, fid: ‘B’, items: [ {text: ‘List B.1’} ] },
    {text: ‘List C’, fid: ‘C’, items: [ {text: ‘List C.1’} ] }
    ];

    var nestedList = new Ext.ws.NestedList({
    items: [],
    fullscreen: true
    });
    makeAjaxRequest();
    //nestedList.resetList(list, true);

    } // end onReady
    }); // end ext.setup

    Any help would be great, Thanks!

    1. hi Andrew,
      Did checkout the code and here is my feedback
      1. the content in test.json is not valid. try this {"result": [ {"text": "List A", "fid": "A", "items": [] } ]}
      2. made modification in the makeAjaxRequest, i added the nested list as param. i modified the test.json to test.js coz IIS block it.

      var makeAjaxRequest = function(nestedList) {
      Ext.Ajax.request({
      url: 'http://localhost/prototype/test.js',
      method: 'GET',
      success: function(response, opts) {
      var obj = Ext.decode(response.responseText);
      nestedList.resetList(obj.result, true);
      },
      failure: function(response, opts) {
      console.log('server-side failure with status code ' + response.status);
      }
      })
      };

      it should looks like

      var makeAjaxRequest = function(nestedList) {
      Ext.Ajax.request({
      url: 'http://localhost/prototype/test.js',
      method: 'GET',
      success: function(response, opts) {
      var obj = Ext.decode(response.responseText);
      nestedList.resetList(obj.result, true);
      },
      failure: function(response, opts) {
      console.log('server-side failure with status code ' + response.status);
      }
      })
      };

      Ext.setup({
      onReady: function() {

      var list = [ {text: 'List A', fid: 'A', items: [] },
      {text: 'List B', fid: 'B', items: [ {text: 'List B.1'} ] },
      {text: 'List C', fid: 'C', items: [ {text: 'List C.1'} ] }
      ];

      var nestedList = new Ext.ws.NestedList({
      items: [],
      fullscreen: true
      });

      makeAjaxRequest(nestedList);
      //nestedList.resetList(list, true);

      } // end onReady
      }); // end ext.setup

      Hopefully that help.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s