Show multiple item in horizontal list

user998405 picture user998405 · Dec 24, 2012 · Viewed 7.1k times · Source

i am new for sencha touch. Here I got a problem, how can I show each row only contain 3 or 4 item?

Please see my screen shoot below enter image description here

I need to show the list like example below enter image description here

Here is my view js file

        Ext.define('bluebutton.view.BlueButton.CouponList', {
        extend: 'Ext.dataview.DataView',
        xtype: 'couponlist',
        requires: [
            'Ext.field.Select',
            'Ext.field.Search',
            'bluebutton.view.BlueButton.MemberDetail',
             'Ext.plugin.ListPaging',
            'Ext.plugin.PullRefresh'

        ],
        config: {

            styleHtmlContent: true,
            scrollable: 'vertical',

             store : { xclass : 'bluebutton.store.BlueButton.MemberList'},
            grouped: true,
            indexBar: true,
             autoLoad: false,
           disclosure: true,
           cls:'customHeader',

            id :'memberlist',
            items: [
                {



                }

            ],
inline: { wrap: false },
            emptyText: '<p class="no-search-results">No member record found matching that search</p>',
            itemTpl: Ext.create(
                'Ext.XTemplate',


    //             '<div class="image" style="background-image:url(http://resources.shopstyle.com/static/mobile/image2-iPad/{urlId}.png)"></div>',
    //            '<div class="name">{memberId}</div>'


                   '<div class="demo-weather">',
                                '<tpl for=".">',
                                    '<div class="day">',
                                        '<div class="date">{memberId}</div>',
                                        '<tpl for="weatherIconUrl">',
                                            '<img src="{value}">',
                                        '</tpl>',
                                        '<span class="temp">{memberId}&deg;<span class="temp_low">{memberId}&deg;</span></span>',
                                    '</div>',
                                '</tpl>',
                            '</div>'





            ),



        },


    });


My sass file


    .demo-weather {
      text-align: center;
    }
    .day {
      display: inline-block;
      background-color: #f9f9f9;
      color: rgba(0, 0, 0, .6);
      text-shadow: #fff 0 1px 0;
      width: 8em;
      text-align: center;
      @include border-radius(15px);
      @include box-shadow(inset 0 0 4px #888);
      box-shadow: inset 0 0 4px #888;
      padding: 1em;
      margin: .5em;

      .x-android & {
        @include box-shadow(none);
      }
    }
    .date {
      font-size: .8em;
    }
    .icon img {
      @include border-radius(10px);
      margin: .6em;
      width: 3.5em;
    }
    .temp {
      margin-top: .2em;
      display: block;
      font-size: 2.2em;
      line-height: .5em;
    }
    .temp_low {
      display: inline;
      font-size: .5em;
      color: rgba(30, 30, 30, .5);
    }

Please guild me solution. Thanks in advance

Answer

ThinkFloyd picture ThinkFloyd · Jan 1, 2013

I had similar problem and each of my image has few handlers attached to it, so basically this is what I wanted to do:

  1. List in my case was actually carousel.
  2. Each page of carousel contains 4-8 images based on screen size.
  3. Each image is actually a panel with image and few more things like toolbars & text. Tap on these images should open a modal details window with more details about that item.

Here is what I did:

  1. Defined a view, ListItemView, which is a panel with image & toolbars as items. On tap of image showDetails event is fired which opens up the view. This can be instantiated with data object passed in constructor.

    Ext.define('myshop.view.ListItemView', {
        extend : 'Ext.Panel',
        alias : 'widget.listitemview',
        xtype : 'listitemview',
        config : {
            layout : 'fit'
        },
        initialize : function() {
            var me = this;
            var data = me.config.data;
            var w = Ext.Viewport.getWindowWidth()/2;
            var pHtml = data.price;
            var pi = [{
                xtype : 'toolbar',
                title : data.styleName,
                top : 0,
                left : 0,
                width : w,
                cls : 'x-toolbar-transparent-top'
            },{
                xtype: 'image',
                layout: 'fit',
                flex : 1,
                rec : me.config.data,
                src : data.searchImage,
                width : w,
                listeners: {
                    tap: function (self, e, eOpts, einfo)
                    {
                        me.fireEvent('loadDetailsCommand', me.parent.parent.parent, data);
                    }
                }
            },{
                xtype : 'toolbar',
                html : pHtml,
                bottom : 40,
                left : 0,
                width : w,
                cls : 'x-toolbar-transparent-top'
            }];
            this.setItems(pi);
            this.callParent(arguments);
        }
    });
    
  2. Defined another view for page, ListPage, which is us again a panel and initialized with array of data objects. Based on this array in initialize function, items(ListItemView) are added to this panel's items.

    Ext.define('myshop.view.ListPage', {
        extend : 'Ext.Panel',
        requires : [ 'myshop.view.ListItemView' ],
        alias : 'widget.listpage',
        xtype : 'listpage',
        config : {
            layout : 'fit',
            width : '100%'
        },
        initialize : function() {
            var me = this;
            var data = me.config.data;
            var items = {
                    xtype : 'panel',
                    layout: 'hbox',
                    items : [{
                        xtype : 'panel',
                        layout: 'vbox',
                        flex: 1,
                        items : [{
                            xtype : 'listitemview',
                            data : data[0],
                            detailsView : Properties.details_view_type_CATALOG,
                            container : hccontainer,
                            flex : 1
                        }, {
                            xtype : 'listitemview',
                            data : data[1],
                            detailsView : Properties.details_view_type_CATALOG,
                            container : hccontainer,
                            flex : 1
                        }]
                    }, {
                        xtype : 'panel',
                        layout: 'vbox',
                        flex: 1,
                        items : [{
                            xtype : 'listitemview',
                            data : data[2],
                            detailsView : Properties.details_view_type_CATALOG,
                            container : hccontainer,
                            flex : 1
                        }, {
                            xtype : 'listitemview',
                            data : data[3],
                            detailsView : Properties.details_view_type_CATALOG,
                            container : hccontainer,
                            flex : 1
                        }]
                    }]
                };
            this.setItems(items);
            this.callParent(arguments);
        }
    });
    
  3. Defined a store which would load paginated data from remote service and on load it would create/use carousel view and pass records to it.

    Ext.define('myshop.store.CatalogListStore',{
        extend:'Ext.data.Store',
        requires: [
                   'myshop.model.CatalogListItem',
                   'Ext.data.proxy.JsonP'
               ],
        config:{
            model:'myshop.model.CatalogListItem',
            storeId: 'catalogListStore',
            autoLoad :false,
            listeners : {
                load: function( me, records, successful, operation, eOpts ){ 
                    console.log(operation.getRequest().getUrl());
                    if(successful){
                        var itemsList = Ext.getCmp("ilid");
                        if(itemsList == undefined || itemsList == null){
                            bossController.createCatalogList(records, me);
                        } else {
                            bossController.setMaskOnSearchList();
                            bossController.fillCatalogList(records, itemsList);
                        }
                    }
                }
            }
        },
        filterParam: undefined,
    
        initialize: function() {
            console.log("CatalogListStore Initializing");
            var me = this;
            var qstring = this.config.q;
            if(qstring != undefined){
                qstring = qstring.replace(/ /g,"-");
            }
            this.setProxy({
                type: 'jsonp',
                url: Properties.PORTAL_SERVICE_BASE_URL+'test/catalog/list',
                callbackKey: 'callback',
                startParam: false, //to remove param "start"
                limitParam: false, //to remove param "limit"
                pageParam: 'page',
                extraParams: {
                    limit : 20,
                    start : 0,
                    _type : 'json',
                    q : qstring,
                    filter : this.config.f
                },
                reader: {
                    type: 'json',
                    rootProperty: 'catalogSearchResponse.data'
                }
            });
            this.load();
            this.callParent();
        }
    });
    
  4. Defined the carousel view which uses records array and breaks it into chunk of 4 records each and create ListPage with each of these chunks and add it to the carousel items. The view:

    Ext.define('myshop.view.CatalogList', {
    extend : 'Ext.carousel.Carousel',
    alias : 'widget.cataloglistview',
    xtype : 'cataloglistview',
    config : {
        id : 'ilid',
        masked: {
            xtype: 'loadmask',
            message: 'Loading'
        },
        directionLock : true,
        indicator : false
    },
    listeners: {
        activeitemchange: function(container, value, oldValue, eOpts) {
            var activeItemIndex = container.getActiveIndex();
            var galleryTotal = container.getInnerItems() ? container.getInnerItems().length : 0;
            if ((activeItemIndex + 1 == galleryTotal)) {
                var store = this.config.store;
                store.nextPage({ addRecords: true });
            }
        }
    }
    });
    

    From Controller:

    createCatalogList : function(records, store){
        console.log("createCatalogList called");
        var hccontainer = Ext.getCmp('hccontainer');
        var itemsList = Ext.create('myshop.view.CatalogList', {
            store : store
        });
    
            //itemsList.setItems(panels);
            itemsList = this.fillCatalogList(records,itemsList);
            hccontainer.setItems([itemsList]);
    },
    fillCatalogList : function(records, list){
        var hccontainer = Ext.getCmp('hccontainer');
        console.log("filling started");
        var datas = [];
        if(list == undefined || list == null){
            list = Ext.getCmp("ilid");
        }
            for(var i=0; i<records.length; i++){
                datas.push(records[i].getData());
            }
            var panels = [];
            while(datas.length){
                panels.push({
                    xtype : 'listpage',
                    data : datas.splice(0,4),
                    detailsView : Properties.details_view_type_CATALOG,
                    container : hccontainer
                });
            }
            list.add(panels);
            this.removeMaskFromSearchList();
            return list;
    },
    
  5. To support pagination, activeitemchange listener is used in carousel.

    listeners : {
        activeitemchange: function(container, value, oldValue, eOpts) {
            var activeItemIndex = container.getActiveIndex();
            var galleryTotal = container.getInnerItems() ? container.getInnerItems().length : 0;
            if ((activeItemIndex + 1 == galleryTotal)) {
                var store = this.config.store;
                store.nextPage({ addRecords: true });
            }
        }
    }