Upperstage
Upperstage

Reputation: 3757

Proper technique to add listeners to DOM created via an XTemplate?

We use XTemplates - lots of XTemplates. They are great for displaying read-only content. But have you ever added (Ext JS) listeners to DOM created via a template? Would you care to share your preferred technique for creating these listeners?

Upvotes: 15

Views: 10949

Answers (4)

Jerod Venema
Jerod Venema

Reputation: 44642

Shamelessly modified version of MolecularMan's concept:

Ext.live = function (selector, event, handler) {
    Ext.getBody().on(event, function(event, target){
        handler.apply(Ext.get(target), arguments);
    }, null, {
        delegate: selector
    });
};

Usage:

Ext.live('.myclass', 'click', function () {
    this.fadeOut();
});

Upvotes: 5

Molecular Man
Molecular Man

Reputation: 22386

My preferred technique is using the analog of $.live function from jquery. F.i. let's assume you are going to use xtemplate for creating simple list like the following:

<ul class="nav">
    <li><a href="example.com">item1</a></li>
    <!-- ... -->
</ul>

To assign handler to the anchors you would do in jquery something like:

$('.nav a').live('click', function(){
    // do something on anchor click
});

The $.live function is great because it would work even if handler assignation would happen before list rendering. This fact is extremely important when you use xtemplate.

Fortunately there is analog in ExtJs - delegating events. Just look at the code:

Ext.getBody().on('click', function(event, target){
        // do something on anchor click
    }, null, {
        delegate: '.nav a'
    });

For more info take a look at docs for the Ext.Element.addListener method.

Upvotes: 25

eduardosouza
eduardosouza

Reputation: 84

The simplest approach we adopt here is the following:

// Function to be called on DOM event
var functionCallback = function () {
    console.log('hello');
}

// function to bind elements created via XTemplate and DOM events
function bind(Ext.Element element, String selector, Obj callback) {
    var els = element.query(selector);

    Ext.Array.each(els, function (item, index, allItems) {
        item.addEventListener('click', callback, false);
    });
}

And the usage:

var tpl = new Ext.XTemplate(...);
var data = [..]

var returnedEl = tpl.append(otherElem, data, true);
bind(returnedEl, 'div.my-css-class', functionCallback);

Upvotes: 3

Sergey Stolyarov
Sergey Stolyarov

Reputation: 2657

Well, you can use something like this:

  1. create id via Ext.id(), pass it to the template to some element
  2. then fetch that element using Ext.get()
  3. attach the listener to just found element

Upvotes: 0

Related Questions