PDA

View Full Version : Adding listener to an element in a XTemplate



mrduck
15 Sep 2011, 9:45 AM
Good day,

I'm using XTemplates, it works great. I want to bind a listener to respond to touch events to a specific DIV-element, identified by an "id" value (like <div id='details'> ). The API documentation doesn't reveal how to do this, so I'm hoping that someone is able to help me.

This is a copy and paste from the API documentation.


new Ext.Panel({ width: 400,
height: 200,
dockedItems: [{
xtype: 'toolbar'
}],
listeners: {
click: {
element: 'el', //bind to the underlying el property on the panel
fn: function(){ console.log('click el'); }
},
dblclick: {
element: 'body', //bind to the underlying body property on the panel
fn: function(){ console.log('dblclick body'); }
}
}
});

As you can see, you can bind it to a element, but I can't see a way to specify this. Can anyone give me a hand? Thanks.

I'm also wondering, what does "itemSelector" exactly do? It's apart of the DataView and it's required. But what does it actually do?

NickT
15 Sep 2011, 3:27 PM
This may help you along...This example is using an html attribute as opposed to a tpl, but the point is the same in that you are defining the content of the panel and want an event attached to an element defined in that content. The event is attached after the panel is rendered.


{ width: 400, height: 200,
xtype:'panel',
html: '<div id="divpanel" >hello </div>',
dockedItems: [
{
xtype: 'toolbar'
}
],
listeners: {
'afterrender': function(panel) {
var el = Ext.get('divpanel');
el.on('click', function(){
console.log(this.getAttribute('id') + ' was clicked');
}, el, {
});
}
}
},

mrduck
16 Sep 2011, 12:53 AM
Nice, that's it. I'd never thought about it to check the "ext" API page.

In the template I have a "for" loop to show a div for every record. I want that when the user touches one of this div's, the listener "knows" which record has been touched so I can pass this information to the controller. Then the controller can do an action specific for this record. Do you have a clue? Thanks doc.

I think it has to do with the itemSelector. But I can't figure out how.

NickT
16 Sep 2011, 5:51 AM
Hi,

Are you using a List or an extension of List? You are referring to itemSelector, hence I am wondering if you are or should be using a List or extension of that control. Can you paste in your code so that I can get a complete understanding of your particular case?

mrduck
16 Sep 2011, 6:01 AM
This is my viewer:



var helperFunctions = {
// ...
}

bbs.views.ProcessAction = Ext.extend(Ext.Panel, {
layout:'fit',

items: new Ext.DataView({
store: bbs.stores.ActionList,
emptyText : '<p class="no-searches">No records to show</p>',
itemSelector:'div.actionItem',
tpl: Ext.XTemplate.from('action', helperFunctions),


listeners: {
'afterrender': function(panel) {
var el = Ext.get('titleheader');
el.on('click', function(){
console.log(this.getAttribute('id') + ' was clicked');
}, el, {
});
}
}
}
&nbsp;)


});

This is my template file, it's merged by PHP info my index.html file.


<textarea id='action' class='x-hidden-display'>




<div class='actionList'>


<tpl for=".">
<div id='actionItem'>
<div id='titleheader' onClick="$('#details{actionId}').slideToggle(400)">
<p id='title'>{title}</p>
<div id='showDetails'></div>
<p id='deadline'>datum</p>
<div style="clear: both;"></div>
</div>


<div class='details' id='details{actionId}'>
<p id='object'>Object: {objectId}</p>
<fieldset id='description'>
<legend>Omschrijving</legend>
<p>{text}<p>
</fieldset>



<tpl if="childs === true">
<p id='progress'>Voortgang</p>


<tpl for="progress">
<fieldset id='progressItem'>
<legend>Toegevoegd op: {dateAdded}</legend>
<p>{text}<p>
</fieldset>
</tpl>
</tpl>
</div>
</div>
</tpl>
</div>
</textarea>


Of the "details" div gets touched, then I want to perform an action (by using the controller). And of course the controller has to know which record has been touched. Thanks.

NickT
16 Sep 2011, 8:07 AM
Try something like this. In the DataView, add listeners for itemtap and itemdoubletap. Your itemSelector is used to distinguish each item. These events will fire based on that itemSelector designation.



Ext.regModel('User', {
fields: [
{name: 'id', type: 'int'},
{name: 'name', type: 'string'},
{name: 'shortName', type: 'string'},
{name: 'url', type: 'string'},
{name: 'phone', type: 'string'}
]
});


var data = {
users: [
{
id: 1,
name: 'Ed Spencer',
shortName: 'Ed',
phone: '555 1234'
},
{
id: 2,
name: 'Abe Elias',
shortName: 'Abe',
phone: '666 1234'
}
]
};

var store = new Ext.data.Store({ autoLoad: true,
model: 'User',
data : data,
proxy: {
type: 'memory',
reader: {
type: 'json',
root: 'users'
}
}
});


var tpl = new Ext.XTemplate(
'<tpl for=".">',
'<div class="thumb-wrap" id="{name}">',
'<span class="x-editable">{shortName}</span></div>',
'</tpl>',
'<div class="x-clear"></div>'
);


var dView = new Ext.DataView({
store: store,
tpl: tpl,
autoHeight:true,
multiSelect: true,
overItemCls:'x-view-over',
itemSelector:'div.thumb-wrap',
emptyText: 'No images to display',
listeners:{
'itemtap': function(dView, index, item, e){
console.log('tap on index ' + index + '. The id is ' + item.id);
},
'itemdoubletap': function(dView, index, item, e){
console.log('double tap on index ' + index + '. The id is ' + item.id);
}
}
});



drop that data view into some simple panel...


{ width: 400,
height: 200,
xtype:'panel',
layout:'fit',
items: [dView]
}

digeridoo
20 Sep 2011, 5:58 AM
Thank you Nick, very useful post. I learnt a lot from that :-)

:-)

Si

mrduck
20 Sep 2011, 5:59 AM
Indeed mate. Thank you! You are awesome.

NickT
20 Sep 2011, 7:02 AM
you're welcome guys. glad it was useful.