views:

197

answers:

2

Hi this question is more a consulting of best practice, Sometimes when I'm building a complete ajax application I usually add elements dynamically for example. When you'r adding a list of items, I do something like:

var template = new Template("<li id='list#{id}'>#{value}</li>");
var arrayTemplate = [];
arrayOfItem.each(function(item, index){
   arrayTemplate.push(template.evaluate( id : index, value : item))
});

after this two options add the list via "update" or "insert"

----- $("elementToUpdate").update("<ul>" + arrayTemplate.join("") + "</ul">);

the question is

how can I add the event handler without repeat the process of read the array, this is because if you try add a Event before the update or insert you will get an Error because the element isn't still on the DOM.

so what I'm doing by now is after insert or update:

arrayOfItem.each(function(item, index){
   $("list" + index).observe("click", function(){
     alert("I see the world");
   })
});

so the question is exist a better way to doing this??????

+1  A: 

I won't do $("list" + index).

There are two ways I would consider:

1) Let the click-event bubble up and catch in in $("elementToUpdate"):

$("elementToUpdate").observe("click", function(evt){
     alert("I see the world");
});

You can find which li is clicked in the evt-object.

2) Don't do repeatetly $("list" + index), but just

$("elementToUpdate").find("li").each(...);

(Presuming you're using jQuery. Prototype has something similar).

edwin
it really depends on the task of the event handler. if you need to do something with the current event target (e.g. reading a value), this won't suffice, since there is no guarantee that Event.target equals the current element.
Dormilich
yes exactly, and the find("li") is to read the array again, so I suppose is kind the same way... but different sintax..
nahum
thanks for the answer =)
nahum
+1 *"Prototype has something similar"* Indeed: `Event#findElement` (http://api.prototypejs.org/dom/event/findelement/)
T.J. Crowder
A: 

Hi I post this question in Prototype Mail list and this is the answer

Hi, If you really want to watch each individual li directly, then what you have seems perfectly straightforward. But in that situation, barring a really good reason to do it that way, I wouldn't use a handler on each li; I'd listen for clicks on the elementToUpdate (or the ul within it) instead with just a single handler:

    $("elementToUpdate").observe("click", function(event) { 
        var li; 
        // Find out which `li` was clicked: 
        li = event.findElement("li"); 
        if (li) { 
            // Do something with the `li` 
        } 
    }); 
Prototype 1.7 has a new feature to simplify that a bit: 
    $("elementToUpdate").on("click", "li", function(event, li) { 
        // Do something with the `li`;  note it's given as the second 
        // argument to the function 
    }); 

...where behind the scenes, Prototype is basically doing what I did above. You'll want the first version if you're still using 1.6 (and since 1.7 is still at RC1, I expect you probably are).

HTH,

T.J. Crowder Independent Software Consultant tj / crowder software / com www.crowdersoftware.com

the link is :http://groups.google.com/group/prototype-scriptaculous/browse_thread/thread/fec98641d72f6fea#

nahum
LOL I'm flattered to be quoted. :-) But actually, I think edwin had the answer.
T.J. Crowder