1. #1
    Sencha User
    Join Date
    Jun 2009
    Posts
    58
    Vote Rating
    0
    vivendi is on a distinguished road

      0  

    Default button in itemTpl impossible to handle?

    button in itemTpl impossible to handle?


    Hi,

    I'm creating a list and also using the itemTpl to add some custom html.
    I also added an <input type="button" /> to the itemTpl. So whenever i see my list i also see a button at the right of the item list.

    But whenever i press this button then the event of the items list (itemtab) is fired too. Is there a way to avoid this??

    So that when i select an item somewhere in my list that the event 'itemtab' gets fired (like it should), but NOT when i press on the button inside of an item. That i only want to use the event of the button. Right now the itemtab gets fired aswell eventhough i clicked on the button and not really on the item itself.

    Anyone any idea how to do that??

  2. #2
    Sencha Premium Member
    Join Date
    May 2008
    Location
    Pasadena, California
    Posts
    172
    Vote Rating
    2
    NickT is on a distinguished road

      0  

    Default


    what if you return false in the onclick event handler for the button by adding that event handler to your input html element

    Code:
    onclick="return false;"
    

  3. #3
    Sencha User
    Join Date
    Jun 2009
    Posts
    58
    Vote Rating
    0
    vivendi is on a distinguished road

      0  

    Default


    Quote Originally Posted by NickT View Post
    what if you return false in the onclick event handler for the button by adding that event handler to your input html element

    Code:
    onclick="return false;"
    
    Sorry, i'm not sure what you mean...?

    Just to make sure i'll try to clarify my problem.

    I have a list with 4 items. In each item i have an <input type="button" onclick="alert('aaa');" /> element.

    I can select an item from the list, after that i use the "itemtab" event to see what item got selected in the list.

    I can also click on one of the buttons and do something (by using onclick() for example). The only problem is, whenever i click on a button, the item from the list also gets selected.
    When i click on the button again, the item gets deselected.

    But i don't want that to happen because i'm not really clicking on a list-item, i'm clicking on a button INSIDE the list-item...

    And besides, because of this its not only triggering the onclick() event from the button, but also the click event of the list-item everytime i click on the button! I dont want that.\

    When i click on the button, the only event that should be triggered is the onclick() event.

    But it seems that this isn't possible...??

  4. #4
    Sencha Premium Member
    Join Date
    May 2008
    Location
    Pasadena, California
    Posts
    172
    Vote Rating
    2
    NickT is on a distinguished road

      0  

    Default


    What I would suggest you consider is extending List and add in buttons similar to the onItemDisclosure feature. With the item disclosure, you can have a button dropped in along the right edge of the list item and trap that event. You may wish to have your own custom button, or even an array of buttons. I am including an extension that I did of list to add an array of 2 extra buttons in addition to the itemDisclosure button, giving me a set of 3 buttons that i can trap independently of the item click itself.


    Screen shot 2011-09-12 at 12.14.03 PM.jpg
    Example extension: so, what i have added is an analyze button and a statuschange button that raises those events....
    Code:
    Ext.namespace('Ext.ux');
    
    /**
     * @class Ext.form.SpecialsList
     * @extends Ext.List
     * <p>Specialized list for specials that includes analytics link as well as status change link {@link Ext.SpecialsList}.</p>
     * @xtype datepickerfield
     */
    Ext.ux.SpecialsList = Ext.extend(Ext.List, {
        preventSelectionOnStatusChange: true,
        preventSelectionOnAnalysis: true,
        // @private
        initComponent : function() {
    
    
    
    
    
    
            var memberFnsCombo = {};
    
    
            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>';
            this.tpl += '<div class="x-list-status"></div>';
            this.tpl += '<div class="x-list-analysis"></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);
                }
            }
            else {
                this.indexBar = false;
            }
    
    
            if (this.scroll !== false) {
                this.scroll = {
                    direction: 'vertical',
                    useIndicators: !this.indexBar
                };
            }
    
    
            Ext.List.superclass.initComponent.call(this);
    
    
            if (this.onItemDisclosure) {
                // disclosure can be a function that will be called when
                // you tap the disclosure button
                if (Ext.isFunction(this.onItemDisclosure)) {
                    this.onItemDisclosure = {
                        scope: this,
                        handler: this.onItemDisclosure
                    };
                }
            }
    
    
            this.on('deactivate', this.onDeactivate, this);
    
    
            this.addEvents(
                 /**
                  * @event disclose
                  * Fires when the user taps the disclosure icon on an item
                  * @param {Ext.data.Record} record The record associated with the item
                  * @param {Ext.Element} node The wrapping element of this node
                  * @param {Number} index The index of this list item
                  * @param {Ext.util.Event} e The tap event that caused this disclose to fire
                  */
                 'disclose',
    
    
                 /**
                  * @event update
                  * Fires whenever the contents of the List is updated.
                  * @param {Ext.List} list This list
                  */
                 'update',
    
    
                 'analyze',
    
    
                 'statuschange'
             );
        },
        afterRender : function() {
            Ext.ux.SpecialsList.superclass.afterRender.call(this);
    
    
            this.mon(this.getTargetEl(), 'singletap', this.handleStatusChange, this, {delegate: '.x-list-status'});
            this.mon(this.getTargetEl(), 'singletap', this.handleAnalysis, this, {delegate: '.x-list-analysis'});
            if (this.onItemDisclosure) {
                this.mon(this.getTargetEl(), 'doubletap', this.handleItemDisclosure, this);
            }
        },
        //@private
        handleStatusChange : function(e, t) {
            var node = this.findItemByChild(t),
                record, index;
    
    
            if (node) {
                record = this.getRecord(node);
                index  = this.indexOf(node);
                if (this.preventSelectionOnStatusChange) {
                    e.stopEvent();
                }
                this.fireEvent('statuschange', record, node, index, e);
            }
        },
        //@private
        handleAnalysis : function(e, t) {
            var node = this.findItemByChild(t),
                record, index;
    
    
            if (node) {
                record = this.getRecord(node);
                index  = this.indexOf(node);
                if (this.preventSelectionOnAnalysis) {
                    e.stopEvent();
                }
                this.fireEvent('analyze', record, node, index, e);
            }
        }
    });
    // register xtype
    Ext.reg('specialslist', Ext.ux.SpecialsList);
    So, here is an example of using this extension inline... Notice my itemTpl has no buttons in it, Those are created by the control extension and the events that are raised are done from that extension as well.

    Code:
    {                cls: 'ts-list',
                    xtype: 'specialslist',
                    width: '100%',
                    scroll: 'vertical',
                    itemTpl: '<table class="ts-list-specials-row-text">' +
                            '<tr>' +
                            '<td rowspan="5">' +
                            '<img class="ts-list-specials-row-image" src="{image}" />' +
                            '</td>' +
                            '<td class="ts-list-specials-row-label">' +
                            '{title}' +
                            '</td>' +
                            '</tr>' +
                            '<tr>' +
                            '<td><p>' +
                            '{venueName}' +
                            '</p></td>' +
                            '</tr>' +
                            '<tr>' +
                            '<td><p>' +
                            '{subtitle}' +
                            '</p></td>' +
                            '</tr>' +
                            '<tr>' +
                            '<td><p>' +
                            '{detail}' +
                            '</p></td>' +
                            '</tr>' +
                            '<tr valign="bottom">' +
                            '<td>' +
                            '{startTime} - {endTime}' +
                            '</td>' +
                            '</tr>' +
                            '<tr>' +
                            '<td class="ts-list-specials-status-{status}" rowspan="2"><p>' +
                            '{status}' +
                            '</p></td>' +
                            '<td>' +
                            '{startDate} - {endDate}' +
                            '</td>' +
                            '</tr>' +
                            '</table>',
                    cls: 'ts-list',
                    onItemDisclosure: function(record, btn, index) {
                        vm.activateItem('Detail');
                        Ext.getCmp('Detail').load(record);
                        // this would be uncommented in lieu of the form.load call if we activate the bindContext logic
                        // select the record in the store, and load the detail view
    {modelPropName: field.name});
                    },
                    // bind to places store
                    store: '${specials}',
                    listeners: {
                        'update': function(list) {
                            list.setLoading(false);
                        },
                        'analyze': function(record, node, index, evt) {
    console.log('analyze button clicked');
                        },
                        'statuschange': function(record, node, index, evt) {
                            console.log('statuschange clicked');
                        }
                    }
                }
            ]
        }

  5. #5
    Sencha User
    Join Date
    Jun 2009
    Posts
    58
    Vote Rating
    0
    vivendi is on a distinguished road

      0  

    Default


    Excellent! Thanks alot for sharing that.

  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


    To give you another approach, here's how I handle it:

    Create a button with a css class in your template:

    Code:
    <button class="detailsButton">Details</button>
    Then in the list's itemtap event, do this:

    Code:
    function listItemTapped(list, index, item, evt) {
      if (evt.getTarget('.detailsButton'))
        handleDetailsButtonClicked(item);
    }
    That way you know the button was clicked and on which item without having to do some coding gymnastics to find out.

  7. #7
    Sencha User
    Join Date
    Jun 2009
    Posts
    58
    Vote Rating
    0
    vivendi is on a distinguished road

      0  

    Default


    Quote Originally Posted by jep View Post
    To give you another approach, here's how I handle it:

    Create a button with a css class in your template:

    Code:
    <button class="detailsButton">Details</button>
    Then in the list's itemtap event, do this:

    Code:
    function listItemTapped(list, index, item, evt) {
      if (evt.getTarget('.detailsButton'))
        handleDetailsButtonClicked(item);
    }
    That way you know the button was clicked and on which item without having to do some coding gymnastics to find out.
    I tried your solution. It would indeed be better if this could be done with much less code. But unfortunately i couldn't get it to work.

    The list-item still gets selected after i clicked on the button.
    PHP Code:
                listeners: {
                    
    itemtap: function ( list, indexitem) {
                        if ( 
    e.getTarget('.mybutton') )
                        {
                            
    alert('aaa');
                            
    //return;
                        
    }
                        else
                        {
                            
    alert('bbb');
                            
    //return;
                        
    }
                    }
                } 
    I do get to see the alert. I also tried to return false. But that didn't fo the trick either.

    Any idea what i'm doing wrong?

  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


    Yeah, a bit of a pickle if you don't want the selection to happen. What you'd probably need to do is set the list's selectedItemCls (and probably pressedCls, if you didn't want that happening) to some a non-existent CSS class. Then in the itemTap, you'd need to manually set/unset x-item-selected if it wasn't the button being clicked on. Does this example make sense?

    Code:
    Ext.regModel('example', {
        fields: ['title']
    });
    
    Ext.setup({
      onReady: function() {
        var lastItem;
        
        var list = new Ext.List({
            fullscreen:true,
            itemTpl: '<div>{title}<button class="detailsButton">Button</button></div>',
            selectedItemCls:'noselect',
            pressedCls:'nopress',
            store:{
              xtype:'jsonstore',
              model:'example',
              data:[
                {title:'Item 1'},
                {title:'Item 2'},
                {title:'Item 3'}
              ]
            },      
            listeners:{
              itemtap:function(list, index, item, e) {
                if (e.getTarget('.detailsButton')) {
                  alert('button clicked: ' + list.store.getAt(index).data.title);
                }
                else {
                  if (lastItem) {
                    lastItem.setAttribute('class', 'x-list-item');
                  }
                  
                  lastItem = item;
                  
                  item.setAttribute('class', 'x-list-item x-item-selected');
                }
              }    
            }
        });
      }
    });
    I didn't do anything with x-item-pressed other than turn it off. So you'll have to add some more code to make that happen. You might even need to override onTapStart/onTapEnd/onTapCancel to get in the right place.

  9. #9
    Sencha - Community Support Team edspencer's Avatar
    Join Date
    Jan 2009
    Location
    Palo Alto, California
    Posts
    1,939
    Vote Rating
    7
    edspencer is a jewel in the rough edspencer is a jewel in the rough edspencer is a jewel in the rough

      0  

    Default


    This has been asked for a great deal, very happy to say that it's baked into the framework in Sencha Touch 2
    Ext JS Senior Software Architect
    Personal Blog: http://edspencer.net
    Twitter: http://twitter.com/edspencer
    Github: http://github.com/edspencer

  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


    Great to hear!

    Care to give any details beyond that? Is it simply for buttons, or can you easily embed various objects like Lists, Buttons, etc.?

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