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.
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(),
});
}
});