htmlextjsdataview

How to add listeners to components that are defined within itemTpl?


How to add listeners to components that are defined within itemTpl? For example, if I have a dataview (Ext.view.View) that is bound to a store, and I have defined itempTpl that includes a button and an image, like:

itemTpl: ['<div class="card" style="padding-left: 32px;">',
'<div><button type="button" class="btn"><span>Button</span></button></div>',
'<div class="img"><img src="https://www.w3schools.com/css/paris.jpg"></div>',                
'</div>']

how can I detect that button or image of an item is clicked? I know ho to add listeners to the item, but I would like to detect click event on some inner div or span element of an item.

In addition, I found writing these templates with html very difficult. One of the main advantages of extjs framework is claimed to be exactly hiding html part from the developer. So, I am wondering if there is some better way to display these information with dataview, like including panel or container component as an dataview item.


Solution

  • You can use element delegation:

    Ext.application({
        name: 'Fiddle',
    
        launch: function () {
            Ext.define('Image', {
                extend: 'Ext.data.Model',
                fields: [{
                    name: 'src',
                    type: 'string'
                }, {
                    name: 'caption',
                    type: 'string'
                }]
            });
    
            Ext.create('Ext.data.Store', {
                id: 'imagesStore',
                model: 'Image',
                data: [{
                    src: 'http://www.sencha.com/img/20110215-feat-drawing.png',
                    caption: 'Drawing & Charts'
                }, {
                    src: 'http://www.sencha.com/img/20110215-feat-data.png',
                    caption: 'Advanced Data'
                }, {
                    src: 'http://www.sencha.com/img/20110215-feat-html5.png',
                    caption: 'Overhauled Theme'
                }, {
                    src: 'http://www.sencha.com/img/20110215-feat-perf.png',
                    caption: 'Performance Tuned'
                }]
            });
    
            Ext.create('Ext.view.View', {
                store: Ext.data.StoreManager.lookup('imagesStore'),
                itemTpl: new Ext.XTemplate(
                    '<div class="card" style="padding-left: 32px;">',
                    '<div><button type="button" class="btn"><span class="btnSpan">Button</span></button></div>',
                    '<div class="img"><img src="https://www.w3schools.com/css/paris.jpg" class="imgClass"></div>',
                    '</div>',
                ),
                itemSelector: 'div.card',
                emptyText: 'No images available',
                listeners: {
                    itemClick: function (view, record, item, index, e, eOpts) {
                        console.log(e.target);
                        const classList = e.target.classList;
                        if (classList.contains('btn')) {
                            console.log('btn is clicked');
                        } else if (classList.contains('btnSpan')) {
                            console.log('Span in Button is clicked');
                        } else if (classList.contains('imgClass')) {
                            console.log('ImgClass is clicked');
                        }
                    }
                },
                renderTo: Ext.getBody(),
            });
        }
    });