Wednesday, March 5, 2014

Sencha Touch List, Different background colors for Group Header

Recently in one of my project we have a Sencha Touch list with grouped headers. We know that we can control group header styles by CSS or we can change it by overriding base css class. In this case we will have one same color for each group header, while in my case the requirement was to have different background colors for each group header. This blog is about how how I implement it, you may have better idea. Feel free to comment.

Here I added background color in each items of the list and then grouped it based in certain field. For example.

Ext.define('MyApp.model.MyModel', {
    extend: 'Ext.data.Model',
    config:{
        fields: [
            { name:'id', type:'int'},
            { name:'group_background_color', type:'string'},
            { name:'item_name', type:'auto'},
            { name: 'group', type: 'string'}
        ]
    }
})

Then we have following Store definition.

Ext.define('MyApp.store.MyStore', {
    extend: 'Ext.data.Store',
    config: {
        model: 'MyApp.model.MyModel',
        autoLoad: true,
        grouper: {
        groupFn: function (item) {
            return item.get('group');
            }
        },
        proxy: {
            type:'ajax',
            actionMethods:{
                read: 'POST'
            },
            url:'items.json',
            reader:{
                type:'json',
                rootProperty:'items'
            }
        }
    }
});

Now we have our list where we will show this data.

{
        xtype: 'list',
        id:'myList',
itemId:'myList',
scrollable: true,
grouped: true,
itemTpl:'<div>{item_name}</div>' ,
        store: 'MyStore'
}

This will create list with groups and group header. If you use default Sencha Theme the group header will have blue as background color. We have to change it to our colors dynamically. For that we will update on list refresh. List refresh event is fired when list is visible first time and there is some change in data in store or list store is loaded. Add refresh event in controller.

control:{
            '#myList':{
                refresh: 'refreshListHeaders'
            }
}

And here is the function.

refreshListHeaders: function(list){
    if(list.groups){
    var groupElements  = document.getElementsByClassName('x-list-header');
    for(var i=0;i < groupElements.length i++){     
       var firstChild = list.groups[i].children[0];
    var backGroundColor = firstChild.data.banner_background_color;
    groupElements[i+1].style.setProperty('background-color', backGroundColor, '!important');
    }
    }
    }

So our logic is very simple. We get all the elements with class name "x-list-header" . That gives us all the header elements.  Now for each group we are getting background color from the first item of the group and set it as background color to group header.

1 comment:

  1. Fantastic. And how to listen whenever the user taps the header in controller?

    ReplyDelete