RyanP13
RyanP13

Reputation: 7753

ExtJS 4: rendering a custom view from a grouped store with a title for the grouping

I am grouping a store with a custom field added to my JSON data records in the model:

Ext.define('SCB.RMWB.InfoBar.Model.Message', {
    extend: 'Ext.data.Model',
    idProperty: 'Message',
    fields: [
        {name: 'id',                type: 'int'},
        {name: 'source',            type: 'string'},
        {name: 'target',            type: 'string'},
        {name: 'sourceType',        type: 'string'},
        {name: 'redirectUrl',       type: 'string'},
        {name: 'message',           type: 'string'},
        {name: 'targetType',        type: 'string'},
        {name: 'messageType',       type: 'string'},
        {name: 'sentDate',          type: 'int'},
        {name: 'notificationType',  type: 'string'},
        {name: 'parameters',        type: 'string'},
        {name: 'read',              type: 'boolean'},
        {name: 'readDate',          type: 'int'},
        {
            name: 'dateGroup',
            type: 'string',
            convert: function(value, record) {   

                var formattedSentDate =  dateHelpers.format(record.get('sentDate')),
                    str = '';

                if (formattedSentDate === dateHelpers.today()) {
                    str = 'Today';
                } else if (formattedSentDate === dateHelpers.yesterday()) {
                    str = 'Yesterday';
                } else {
                    str = 'Last week';
                }

                return str;

            }
        }

    ],
    validations: [
        {type: 'presence',          field: 'id'},
        {type: 'presence',          field: 'source'},
        {type: 'presence',          field: 'target'},
        {type: 'presence',          field: 'sourceType'},
        {type: 'presence',          field: 'redirectUrl'},
        {type: 'presence',          field: 'message'},
        {type: 'presence',          field: 'targetType'},
        {type: 'presence',          field: 'messageType'},
        {type: 'presence',          field: 'sentDate'},
        {type: 'presence',          field: 'notificationType'},
        {type: 'presence',          field: 'parameters'},
        {type: 'presence',          field: 'read'},
        {type: 'presence',          field: 'readDate'},
        {type: 'presence',          field: 'dateGroup'}
    ]
});

So it should be apparent that the desired grouping are today, yesterday and last week.

This appears to be working fine but i need to render the groupings in an accordion fashion with a title denoting the grouping.

Currently the template outputs the date grouping every time and i need the grouping title once then those records that belong to that grouping.

This is the current template:

    '<tpl for=".">',
        '<li class="view-all-details">',
            '<h3>{dateGroup}</h3>',
            '<div>',
                '<p>{[ Ext.util.Format.ellipsis(values.message, 100, true) ]}</p>', 
                '<span class="time-frame">{[ SCB.RMWB.Infobar.utils.dateRangeMsg(values.sentDate) ]}</span>',
            '</div>',
        '</li>',                        
    '</tpl>'    

I know the template will not currently output what i need but am unsure how to group the records in the view with a title.

Upvotes: 1

Views: 1383

Answers (1)

Narendra Jadhav
Narendra Jadhav

Reputation: 10262

I know question is 5 years old but I have got same requirement. So I have worked around for the same and got solution from my end so I am sharing here.

For this inside of XTemplate you need to check if condition to show common header for date group and handle one variable to check type of date-group.

How to check if condition check tpl? see below example:-

'<tpl for="kids">',
        '<tpl if="age &gt; 1">',
            '<p>{name}</p>',
            '<p>Dad: {parent.name}</p>',
        '</tpl>',
    '</tpl></p>'

In this FIDDLE, I have created a demo using Ext.view.View, store, model and panel. I hope this will help or guide to you/other folks to achieve your requirement.

Code Snippet

Ext.application({
    name: 'Fiddle',

    launch: function () {

        var message = [],
            date,
            date1;
        /*
         * function will calculate diffrence b/w 2 dates
         * @param{Date} min
         * @param{Date} max
         * @return number
         */
        function dayDiff(min, max) {
            return Math.round((max - min) / (1000 * 60 * 60 * 24))
        }

        //createing demo message for testing
        for (var i = 0; i < 12; i++) {
            if (i < 4) {
                date = Date.now();
            } else if (i >= 4 && i < 8) {
                date1 = new Date();
                date = date1.setDate(date1.getDate() - 1);
            } else {
                date1 = new Date();
                date = date1.setDate(date1.getDate() - 2);
            }
            message.push({
                text: `Hello I am message ${i+1}`,
                sentdate: Ext.Date.clearTime(new Date(date)),
                id: i + 1
            })
        }

        //Create Message model
        Ext.define('Message', {
            extend: 'Ext.data.Model',
            fields: ['id', 'text', {
                    name: 'sentdate',
                    type: 'date'
                }, {
                    name: 'dateGroup',
                    type: 'string',
                    convert: function (value, record) {
                        var sentDate = record.get('sentdate'),
                            str,
                            diff = dayDiff(new Date(sentDate), Ext.Date.clearTime(new Date()));
                        if (diff == 0) {
                            str = 'Today';
                        } else if (diff == 1) {
                            str = 'Yesterday';
                        } else {
                            str = 'Last week';
                        }
                        return str;
                    }
                }
                /*, {
                                    name: 'group',
                                    type: 'int',
                                    mapping: 'dateGroup',
                                    convert: function (value, rec) {
                                        switch (rec.get('dateGroup')) {
                                        case 'Today':
                                            value = 0;
                                            break;
                                        case 'Yesterday':
                                            value = 1;
                                            break;
                                        default:
                                            value = 2
                                        }
                                        return value;
                                    }
                                }*/

            ],
            // sort: 'group'
        });
        //create message store
        Ext.create('Ext.data.Store', {
            storeId: 'message',
            model: 'Message'
        });

        //Create data view
        //we can also use using xtype:'dataview' inside of items
        var view = Ext.create('Ext.view.View', {
            height: window.innerHeight,
            //overflowY: 'auto',
            store: 'message',
            tpl: new Ext.create('Ext.XTemplate',
                '<tpl for=".">',
                '<tpl if="this.isSameGroup(values.dateGroup)"><div class="x-group-header"><b>{[this.doShowGroup(values.dateGroup)]}</div></b></tpl>',
                '<div class="x-message-item ">{text} <span>{[Ext.Date.format(values.sentdate,"d M y")]}<span></div>',
                '</tpl>', {
                    isSameGroup: function (group) {
                        return this.currentGroup != group;
                    },
                    doShowGroup: function (group) {
                        this.currentGroup = group;
                        return group;
                    }
                }),
            itemSelector: '.x-message-item',
            emptyText: 'No data available',
            renderTo: Ext.getBody()
        });
        //create panel
        Ext.create('Ext.panel.Panel', {
            title: 'Rendering a custom view from a grouped store with a title for the grouping',
            items: [view],
            renderTo: Ext.getBody(),
            listeners: {
                afterrender: function () {
                    this.down('dataview').getStore().loadData(message);
                }
            }
        });

    }
});

Upvotes: 2

Related Questions