Reputation: 384
I have a script where I'm appending elements to a list. I would need that when I click the element a function is called, and for this function the value of a variable when creating the li is needed (it's the li
content).
I've checked solutions like adding newLi.onclick = function(){...}
.
The problem with this solution is that I'm not getting the right value in the function, I get the value of another element in the list.
Right now this is how I'm creating the elements:
var ULlist = document.getElementById('ULid');
for(i=0;i<data.length;i++){
var Value = data[i] //function to get data
var newLi = document.createElement('li');
newLi.appendChild(elements.createTextNode(Value));
newLi.onclick = function(){alert(Value)} //not displaying the right value
ULlist.appendChild(newLi);
}
So the question is, is there any way to create te onclick event giving to the element the right value of the variable?
Edit: I've added a portion more of code.
Li's are being created, and information displayed correctly, the only problem is when trying to create the event that it's not giving the right value, that should be the value cointained at the li
Upvotes: 1
Views: 12611
Reputation: 3566
When I experienced this problem, I solved it like this:
var ULlist = document.getElementById('ULid');
for(var i=0; i<data.length; i++){
var index = i;
(function() {
var Value = data[index] //function to get data
var newLi = document.createElement('li');
newLi.appendChild(elements.createTextNode(Value));
newLi.onclick = function() { ... };
ULlist.appendChild(newLi);
}());
}
Edit: Today, I remember another thing about for scope. It is another solution to send parameter 'i' to function inside the loop:
var ULlist = document.getElementById('ULid');
for(var i=0; i<data.length; i++){
(function(index) {
var Value = data[index] //function to get data
var newLi = document.createElement('li');
newLi.appendChild(elements.createTextNode(Value));
newLi.onclick = function() { ... };
ULlist.appendChild(newLi);
}(i));
}
Try this and let me know if it works.
Upvotes: 3
Reputation: 25135
You can achieve this by creating function inside and keeping the value in the scope of that function.
var data = [10, 20, 30, 40, 50, 60, 70];
addItems = function() {
var list = document.getElementById("list");
for (var i = 0; i < data.length; i++) {
var newLi = document.createElement("li");
newLi.innerHTML = i + 1;
list.appendChild(newLi);
(function(value){
newLi.addEventListener("click", function() {
alert(value);
}, false);})(data[i]);
}
}
jsfiddle : http://jsfiddle.net/Qf5JZ/1/
Upvotes: 6
Reputation: 32286
Use DOM2 event listeners, in particular the element.addEventListener API:
function clickHandlerFor(data) {
return function(event) {
var li = event.target;
// do something with data and li.
};
}
for (...) {
var Data = ... //function to get data
var newLi = elements.createElement('li');
newLi.appendChild(elements.createTextNode(Data));
newLi.addEventListener("click", clickHandlerFor(Data), false);
ULlist.appendChild(newLi);
}
Another option is much simpler: use the TextNode value in your handler:
function handler(event) {
var dataValue = event.target.firstChild.nodeValue; // value of TextNode created by elements.createTextNode(Data)
// handle dataValue
}
newLi.addEventListener("click", handler, false);
Upvotes: 3