You found a bug! We've classified it as TOUCH-3894 . We encourage you to continue the discussion and to find an acceptable workaround while we work on a permanent fix.
  1. #1
    Sencha User
    Join Date
    Jan 2013
    Posts
    8
    Vote Rating
    0
    hosokaws is on a distinguished road

      0  

    Default List with useComponents:true dosen't fire the itemtap event

    List with useComponents:true dosen't fire the itemtap event


    REQUIRED INFORMATION


    Ext version tested:
    • Sencha Touch 2.1
    Browser versions tested against:
    • Chrome 23.0
    Description:
    • As this thread, on Sencha Touch 2.1 I think that Ext.dataview.List can handle ListItem with components. So I tried to use ListItem, then it showed records in components. But the item tap event were not fired. It seems that components interrupt touch events.
    Steps to reproduce the problem:
    • Define a class extended from Ext.dataview.List with configuration set as useComponents:true, defaultType:[correspond ListItem's xtype].
    • Define a class extended from Ext.dataview.component.ListItem.
    • Create a instance of the List class and add it as a main view.
    The result that was expected:
    • Click a list item.
    • The itemtap event is fired.
    The result that occurs instead:
    • Click a list item.
    • The itemtap event is never fired except a area around right end of each items.
    Test Case:

    List.js
    Code:
    Ext.define('WSChat.view.List', {
        extend: 'Ext.dataview.List',
        xtype: 'list',
        requires: [
            'Ext.data.Store',
            'WSChat.view.ListItem',
        ],
        config: {
            title: 'Names',
            store: {
                fields: ['name', 'age'],
                data: [
                    {name: 'Jamie',  age: 100},
                    {name: 'Rob',   age: 21},
                    {name: 'Tommy', age: 24},
                    {name: 'Jacky', age: 24},
                    {name: 'Ed',   age: 26}
                ]
            },
    
    
            //itemTpl: '{name}:{age}',
            
            useComponents: true,
            defaultType: 'listitem',
            
            listeners: {
                itemtap: function( list, index, item, record){
                    console.log(record);
                    console.log('Item tapped:' + record.get('name'));
                },
            },
        }
    });
    ListItem.js
    Code:
    Ext.define('WSChat.view.ListItem', {
        extend: 'Ext.dataview.component.ListItem',
        xtype: 'listitem',
        requires: [
            'Ext.Panel',
            'Ext.Label',
        ],
        config: {
            layout: 'hbox',
            items: [
                {xtype: 'panel', itemId:'name', flex: 1, width: "100%", height: "100%"},
                {xtype: 'label', itemId:'age', docked: 'bottom', style: 'font-size: 75%'},
            ],
            listeners: {
                updatedata: function( listItem, newData, eOpts ){
                    if(newData != null){
                        listItem.getComponent('name').setHtml(newData.name);
                        listItem.getComponent('age').setHtml(newData.age);
                    }
                }
            }        
        },
    });
    HELPFUL INFORMATION


    Debugging already done:
    • none
    Possible fix:
    • not provided
    Additional CSS used:
    • only default ext-all.css
    Operating System:
    • Mac OS X 10.7.4

  2. #2
    Sencha - Senior Forum Manager mitchellsimoens's Avatar
    Join Date
    Mar 2007
    Location
    Gainesville, FL
    Posts
    37,227
    Vote Rating
    859
    mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute mitchellsimoens has a reputation beyond repute

      0  

    Default


    First issue I see is you are overriding xtypes, you use list and listitem which is being used by framework components. So below I fixed that.

    Also, I changed the listitem you used to be a more proper list item.

    Code:
    Ext.define('WSChat.view.List', {
        extend   : 'Ext.dataview.List',
        xtype    : 'wschat-list',
    
        requires : [
            'Ext.data.Store'
        ],
    
        config   : {
            store : {
                fields : ['name', 'age'],
                data   : [
                    { name : 'Jamie', age : 100 },
                    { name : 'Rob',   age : 21  },
                    { name : 'Tommy', age : 24  },
                    { name : 'Jacky', age : 24  },
                    { name : 'Ed',    age : 26  }
                ]
            },
    
            useComponents : true,
            defaultType   : 'wschat-listitem',
    
            listeners : {
                itemtap : function (list, index, item, record) {
                    console.log(record);
                    console.log('Item tapped:' + record.get('name'));
                }
            }
        }
    });
    
    Ext.define('WSChat.view.ListItem', {
        extend   : 'Ext.dataview.component.ListItem',
        xtype    : 'wschat-listitem',
    
        requires : [
            'Ext.Panel',
            'Ext.Label'
        ],
    
        config   : {
            dataMap : {
                getName : {
                    setHtml : 'name'
                },
                getAge : {
                    setHtml : 'age'
                }
            },
            layout    : 'hbox',
    
            name : {
                cls : 'name'
            },
            age  : {
                cls : 'age'
            }
        },
    
        applyName : function (config) {
            return Ext.factory(config, Ext.Component, this.getName());
        },
    
        updateName : function (newName) {
            if (newName) {
                this.add(newName);
            }
        },
    
        applyAge : function (config) {
            return Ext.factory(config, Ext.Component, this.getAge());
        },
    
        updateAge : function (newAge) {
            if (newAge) {
                this.add(newAge);
            }
        }
    });
    This being said the itemtap should fire and if you tap on the left part (there is some padding between the left and the name) it will fire so there is a bug there.
    Mitchell Simoens @SenchaMitch
    Sencha Inc, Senior Forum Manager
    ________________
    Check out my GitHub, lots of nice things for Ext JS 4 and Sencha Touch 2
    https://github.com/mitchellsimoens

    Think my support is good? Get more personalized support via a support subscription. https://www.sencha.com/store/

    Need more help with your app? Hire Sencha Services services@sencha.com

    Want to learn Sencha Touch 2? Check out Sencha Touch in Action that is in print!

    When posting code, please use BBCode's CODE tags.

  3. #3
    Sencha User
    Join Date
    Jan 2013
    Posts
    8
    Vote Rating
    0
    hosokaws is on a distinguished road

      0  

    Default


    Thanks mitchellsimoens for fixing my code.
    I wanted to make simple my test code, but overriding xtypes was wrong.

    Does using "dataupdate" event to reflect the record into components cause any problems?
    About a way to reflect updated record into components, I applied a method to handling "updatedata" event. I know a example for DataView that uses dataMap. It works nice to reflect a record to components in a simple case. But in other case like reflecting a processed value instead of a raw value from the record, I guess that it requires to add a method for mapping the field instead of component's method.
    Code:
        .......
        config   : {
            dataMap : {
                //Mapping a method instead of getter for the 'name' property. 
                getRecordReflecter : {
                    setHtmlForName : 'name'
                },
                getAge : {
                    setHtml : 'age'
                }
            },
            layout    : 'hbox',
    
    
            name : {
                cls : 'name'
            },
            age  : {
                cls : 'age'
            }
        },
        
        //To return 'this' instance to map this method to a record modified 
        getRecordReflecter: function (){
            return this;
        }
    
        //A method to reflect a processed field.
        setHtmlForName: function ( name){
            var component = this.query(".panel");
            component.setHtml( '<span>'+name+'</span>');
        }
        ......
    And I consider that sometimes we need to refer some fields in the record to describe the item. In this case, it's more complicated. This is the reason why I would like to use the way to handle the dataupdate event.

  4. #4
    Sencha Premium Member
    Join Date
    Nov 2012
    Posts
    11
    Vote Rating
    0
    cdamon is on a distinguished road

      0  

    Default Layout bug?

    Layout bug?


    This might be a layout bug. That's what it looks like for my component-based List. In the normal List layout without useComponents, a "list item body" component with class "x-list-item-body" acts as a container for each item's content, and a selector used to catch the tap event is tied to that CSS class.

    What I'm seeing is that the "list item body" component does not contain the entirety of my List component; instead, it is inserted in between two of my sub-components, and it has a height of 46px. Tapping my sub-components does not trigger a tap event. Tapping the empty "list item body" does trigger the tap event.

    Here's how configure my custom List item:

    Code:
    ListItem
        Component 1
        Component 2
        Toolbar
    Here's what I see in the DOM:

    Code:
    ListItem
        (container element)
            Component 1
            Component 2
            (list item body)
        Toolbar
    I would expect the "list item body" to contain my three sub-components.

    My workaround is to hide the empty 46px-high "list item body" using CSS, and to add a delegate to my List class to capture taps on Component 1:

    Code:
        initialize: function() {
    
            this.callParent(arguments);
    
            // Add a delegate here so we can catch a tap on a msg header.
            // Note: Adding this listener via config does not work.
            this.on({
                tap: function() {
                    console.log('TAP via delegate');
                },
                element: 'element',
                delegate: '.component1',
                scope: this
            });
        }

Thread Participants: 2