1. #1
    Sencha User
    Join Date
    Jul 2010
    Posts
    18
    Vote Rating
    0
    shellgrit is on a distinguished road

      0  

    Smile Dynamically adding/removing 'grouped' & 'indexBar' to/from a List

    Dynamically adding/removing 'grouped' & 'indexBar' to/from a List


    Is it possible to dynamically add/remove the config items 'grouped' and/or 'indexBar' from a List.

    My list consists of shorebird species (ie. thumbnail, name & size) with toolbar buttons that the user can tap to sort the list alphabetically or by size. Grouped and an index bar would be great for the list sorted alphabetically, but not when it is sorted by size (unless it is possible to group/index it some other way).

    Neil

  2. #2
    Sencha - Ext JS Dev Team evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    16,112
    Vote Rating
    504
    evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute evant has a reputation beyond repute

      0  

    Default


    Turning off the index bar is reasonably trivial, grouping a bit less so.

    Code:
    Ext.override(Ext.List, {
        setGrouped: function(grouped){
            this.grouped = !!grouped;
            this.tpl = this.grouped ? this.groupTpl : this.itemTpl;
            if(this.rendered){
                if(!this.grouped){
                    this.el.addClass('x-list-flat');
                    if (this.indexBar) {
                        this.indexBar.hide();
                    }
                }else{
                    this.el.removeClass('x-list-flat');
                    if(this.indexBar){
                        this.indexBar.show();
                    }
                }
                this.refresh();
            }
        }    
    });
    
    Ext.setup({
        tabletStartupScreen: 'tablet_startup.png',
        phoneStartupScreen: 'phone_startup.png',
        icon: 'icon.png',
        glossOnIcon: false,
        onReady : function() {
            Ext.regModel('Contact', {
                fields: ['firstName', 'lastName']
            });
            
            var groupingBase = {
                tpl: '<tpl for="."><div class="contact"><strong>{firstName}</strong> {lastName}</div></tpl>',
                itemSelector: 'div.contact',
                
                singleSelect: true,
                grouped: true,
                indexBar: true,
                
                store: new Ext.data.Store({
                    model: 'Contact',
                    sorters: 'firstName',
                    
                    getGroupString : function(record) {
                        return record.get('firstName')[0];
                    },
                    
                    data: [
                        {firstName: 'Tommy', lastName: 'Maintz'}, 
                        {firstName: 'Ed', lastName: 'Spencer'},
                        {firstName: 'Jamie', lastName: 'Avins'},
                        {firstName: 'Aaron', lastName: 'Conran'}                  
                    ]
                })
            };
            
            var list;
            
            if (!Ext.platform.isPhone) {
                list = new Ext.List(Ext.apply(groupingBase, {
                    floating: true,
                    width: 350,
                    height: 350,
                    centered: true,
                    hideOnMaskTap: false
                })).show();
            } 
            else {
                list = new Ext.List(Ext.apply(groupingBase, {
                    fullscreen: true
                }));
            }
            new Ext.form.Toggle({
                fieldLabel: 'Index Bar',
                value: 1,
                listeners: {
                    change: function(slider, thumb, old, val){
                        list.indexBar.setVisible(val != 0);
                    }
                }
            }).show();
            new Ext.form.Toggle({
                fieldLabel: 'Grouped',
                value: 1,
                listeners: {
                    change: function(slider, thumb, old, val){
                        list.setGrouped(val);
                    }
                }
            }).show();
        }
    });
    Evan Trimboli
    Sencha Developer
    Twitter - @evantrimboli
    Don't be afraid of the source code!

  3. #3
    Sencha User
    Join Date
    Jul 2010
    Posts
    18
    Vote Rating
    0
    shellgrit is on a distinguished road

      0  

    Default


    Thanks heaps Evan - it works beautifully!

    Neil

  4. #4
    Sencha User jep's Avatar
    Join Date
    Sep 2010
    Posts
    862
    Vote Rating
    21
    jep will become famous soon enough jep will become famous soon enough

      0  

    Default


    This code doesn't really work anymore, so I've cranked out some that will. The standalone List extension code is in this thread. Here's an example with the extension included:

    Code:
    <html>
      <head>
        <title>test</title>
    
        <link rel="stylesheet" href="../sencha/resources/css/sencha-touch.css" type="text/css">
        <script type="text/javascript" src="../sencha/sencha-touch-debug.js"></script>  
    
        <script type="text/javascript">
    
    // jep @ Sencha Touch forums
    Ext.namespace("Ext.jep");
    
    
    Ext.jep.List = Ext.extend(Ext.List, {
      // Use displayIndexToRecordIndex in the list's itemTap handlers to convert between
      // the index in the handler (the display index) and the record index in the store.
      // this isn't always the same when you have a custom grouping function that causes
      // the store's to not sort identically to the display order (see bug report)
      displayIndexToRecordIndex: function (targetIndex) {
        if (this.grouped) {
          var groups = this.getStore().getGroups();
          
          for (var g = 0; g < groups.length; g++) {
            var group = groups[g].children;
            
            if (targetIndex < group.length)
              return this.getStore().indexOf(group[targetIndex]);
              
            targetIndex -= group.length;
          }  
        }
        else
          return targetIndex;
      },
    
      // Use this to convert the store's record index to the display index
      // for using the list's nodes directly via list.all.elements[i] or
      // in calls to list.getNode.
      recordIndexToDisplayIndex: function (targetIndex) {
        if (this.grouped) {
          var rec = this.getStore().getAt(targetIndex);
    
          var groups = this.getStore().getGroups();
          var currentIndex = 0;
          
          for (var g = 0; g < groups.length; g++) {
            var group = groups[g].children;
            
            for (var i = 0; i < group.length; i++)
              if (group[i] == rec)
                return currentIndex;
              else
                currentIndex++;
          }  
        }
        else
          return targetIndex;
      },
     
      // Fixes getNode so that if you pass it a store record, it will return the
      // proper node even when the grouping/sorting situations described above happen.
      getNode: function (nodeInfo) {
          if (Ext.isString(nodeInfo)) {
              return document.getElementById(nodeInfo);
          } else if (Ext.isNumber(nodeInfo)) {
              return this.all.elements[nodeInfo];
          } else if (nodeInfo instanceof Ext.data.Model) {
              var idx = this.recordIndexToDisplayIndex(this.store.indexOf(nodeInfo));
              return this.all.elements[idx];
          }
          return nodeInfo;
      },
      
      // Fixes getRecord so that it gets the proper store record even when the
      // grouping/sorting situations described above happen.
      getRecord: function(node){
        return this.store.getAt(this.displayIndexToRecordIndex(node.viewIndex));
      },
      
      // Fix for groupTpl not being able to accept an XTemplate
      initComponent : function() {
        Ext.jep.List.superclass.initComponent.apply(this);
        
        if (this.grouped && this.groupTpl && this.groupTpl.html) {
          this.tpl = new Ext.XTemplate(this.groupTpl.html, this.groupTpl.initialConfig);
        }
      },
    
      // Allows for dynamically switching between grouped/non-grouped
      setGrouped: function(grouped){
        // we have to save the itemTpl user functions first, which are in different place depending on grouping
        var memberFnsCombo = 
            (!this.grouped && this.tpl && this.tpl.initialConfig)
              ? this.tpl.initialConfig
              : ((this.grouped && this.listItemTpl && this.listItemTpl.initialConfig) ? this.listItemTpl.initialConfig : {});
    
        this.grouped = !!grouped;
    
        // the following is code copied from List.initComponent, slightly modified
        if (Ext.isArray(this.itemTpl)) {
            this.itemTpl = this.itemTpl.join('');
        } else if (this.itemTpl && this.itemTpl.html) {
            Ext.apply(memberFnsCombo, this.itemTpl.initialConfig);
            this.itemTpl = this.itemTpl.html;
        }
        
        if (!Ext.isDefined(this.itemTpl)) {
            throw new Error("Ext.List: itemTpl is a required configuration.");
        }
        // this check is not enitrely fool proof, does not account for spaces or multiple classes
        // if the check is done without "s then things like x-list-item-entity would throw exceptions that shouldn't have.
        if (this.itemTpl && this.itemTpl.indexOf("\"x-list-item\"") !== -1) {
            throw new Error("Ext.List: Using a CSS class of x-list-item within your own tpl will break Ext.Lists. Remove the x-list-item from the tpl/itemTpl");
        }
        
        this.tpl = '<tpl for="."><div class="x-list-item ' + this.itemCls + '"><div class="x-list-item-body">' + this.itemTpl + '</div>';
        if (this.onItemDisclosure) {
            this.tpl += '<div class="x-list-disclosure"></div>';
        }
        this.tpl += '</div></tpl>';
        this.tpl = new Ext.XTemplate(this.tpl, memberFnsCombo);
       
    
        if (this.grouped) {
            
            this.listItemTpl = this.tpl;
            if (Ext.isString(this.listItemTpl) || Ext.isArray(this.listItemTpl)) {
                // memberFns will go away after removal of tpl configuration for itemTpl
                // this copies memberFns by storing the original configuration.
                this.listItemTpl = new Ext.XTemplate(this.listItemTpl, memberFnsCombo);
            }
            if (Ext.isString(this.groupTpl) || Ext.isArray(this.groupTpl)) {
                this.tpl = new Ext.XTemplate(this.groupTpl);
            }
            // jep: this line added to original source
            else if (this.grouped && this.groupTpl && this.groupTpl.html) {
                this.tpl = new Ext.XTemplate(this.groupTpl.html, this.groupTpl.initialConfig);
            }
        }
        
        // jep: slightly modified
        if (this.rendered)
          this.refresh();
      }
    });
    
    Ext.reg('jeplist', Ext.jep.List);
    
    Ext.setup({
        tabletStartupScreen: 'tablet_startup.png',
        phoneStartupScreen: 'phone_startup.png',
        icon: 'icon.png',
        glossOnIcon: false,
        onReady : function() {
            Ext.regModel('Contact', {
                fields: ['firstName', 'lastName']
            });
            
            var list = new Ext.jep.List({
                groupTpl:new Ext.XTemplate(
                  '<tpl for=".">',
                      '<div class="x-list-group x-group-{id}">',
                          '<h3 class="x-list-header">{[this.formatGroup(values.group)]}</h3>',
                          '<div class="x-list-group-items">',
                              '{items}',
                          '</div>',
                      '</div>',
                  '</tpl>',
                  { formatGroup:function (group) { return '<i>' + group + '</i>' } }
                ),
                    
                itemTpl:new Ext.XTemplate(
                  '<div class="contact">{[this.formatName(values.firstName, values.lastName)]}</div>', { 
                    formatName:function (first, last) {
                      return last + ', ' + first;
                    }
                }),
                singleSelect: true,
                grouped: true,
                
                store: new Ext.data.Store({
                    model: 'Contact',
                    sorters: 'lastName',
                    
                    getGroupString : function(record) {
                        return record.get('lastName')[0];
                    },
                    
                    data: [
                        {firstName: 'Tommy', lastName: 'Maintz'}, 
                        {firstName: 'Steve', lastName: 'Apple'},
                        {firstName: 'Ed',    lastName: 'Spencer'},
                        {firstName: 'Jamie', lastName: 'Avins'},
                        {firstName: 'Aaron', lastName: 'Conran'}                  
                    ]
                })
            });
            
            var mainPnl = new Ext.Panel({
              layout:'fit',
              fullscreen: true,
              items:list,
              dockedItems:{
                xtype:'toolbar', dock:'top', 
                items:{ xtype:'button', text:'Toggle Group', handler:function () { list.setGrouped(!list.grouped) } }
              }
            });
        }
    });
    
    </script>
    
    </head>
    <body></body>
    </html>

  5. #5
    Sencha Premium Member
    Join Date
    Aug 2011
    Posts
    11
    Vote Rating
    1
    ggvPVR is on a distinguished road

      0  

    Exclamation Still a problem

    Still a problem


    Thanks for this. I've been using jeplist for my grouped list for a few weeks now.

    Just made a change in my app to use the setGrouped feature. But when you turn off Grouped and scroll up you still see the group headers appearing and trying to stick to the top of the scroll area like when the groupby is on.

    Your example here does it too. I'm getting same results on chrome desktop and iPhone.

  6. #6
    Sencha User jep's Avatar
    Join Date
    Sep 2010
    Posts
    862
    Vote Rating
    21
    jep will become famous soon enough jep will become famous soon enough

      0  

    Default


    Check the main thread for jeplist:

    http://www.sencha.com/forum/showthre...-grouping-bugs

    (I fixed the original link above - sorry about that!)

    In my testing, it doesn't do that with the current code there (the pinHeaders updates most likely fixed it). If you still run into problems, post something there to let me know and I'll check it out.

  7. #7
    Sencha User
    Join Date
    Oct 2011
    Posts
    2
    Vote Rating
    0
    kingkoczon is on a distinguished road

      0  

    Default


    Hi Jep,

    awesome code. is there any way to make the link go to a different page for each link when you click on them? like when I click on Steve Apple, it will slide right to a page on steve apple, and then you can click the back button to get back to the list. Is this possible? Thanks so much in advance. Again, awesome coding.

    - BK

  8. #8
    Sencha User jep's Avatar
    Join Date
    Sep 2010
    Posts
    862
    Vote Rating
    21
    jep will become famous soon enough jep will become famous soon enough

      0  

    Default


    Thanks for the compliment!

    Post some example code taking it as far as you can without the feature you're requesting, then detail a little what exactly you mean. I'll take a look at it later when I get a chance and see what I can do.

  9. #9
    Sencha User
    Join Date
    Oct 2011
    Posts
    2
    Vote Rating
    0
    kingkoczon is on a distinguished road

      0  

    Default Coding so far

    Coding so far


    Quote Originally Posted by jep View Post
    Thanks for the compliment!

    Post some example code taking it as far as you can without the feature you're requesting, then detail a little what exactly you mean. I'll take a look at it later when I get a chance and see what I can do.
    Hi Jep,

    Thanks for the quick response.

    Here is a link to a site with my coding on it. http://fixmysite.us/bobapp/indexnew.html.

    I basically would like to be able to click (or tap) on a name, ie bob and have it go to a page with details about bob. Kind of like the iPhone contact app or ipod app, but the next page would be read-only.

    Thanks again for checking it out. Really appreciate it.

  10. #10
    Sencha User jep's Avatar
    Join Date
    Sep 2010
    Posts
    862
    Vote Rating
    21
    jep will become famous soon enough jep will become famous soon enough

      0  

    Default


    Is this any different than just using the normal "disclosure" features of the list? Click on the "Disclosure" in the List example in the Kitchen Sink demo.

Similar Threads

  1. Dynamically adding and removing a form field
    By ProggerPete2 in forum Ext GWT: Discussion
    Replies: 3
    Last Post: 2 Jun 2010, 4:03 AM
  2. Dynamically adding and removing a form field
    By ProggerPete2 in forum Ext 2.x: Help & Discussion
    Replies: 0
    Last Post: 2 Jun 2010, 3:52 AM
  3. Adding and Removing Accordion Elements Dynamically
    By ogradyjd in forum Ext 2.x: Help & Discussion
    Replies: 16
    Last Post: 12 Dec 2008, 8:59 AM
  4. dynamically adding and removing menus
    By holli in forum Ext 1.x: Help & Discussion
    Replies: 0
    Last Post: 23 Oct 2007, 2:10 PM
  5. Dynamically adding / removing checkboxes
    By jeffita in forum Ext 1.x: Help & Discussion
    Replies: 0
    Last Post: 9 Aug 2007, 12:30 PM

Thread Participants: 4

Tags for this Thread

film izle

hd film izle

film sitesi

takipci kazanma sitesi

takipci kazanma sitesi

güzel olan herşey

takipci alma sitesi

komik eğlenceli videolar