mehdi
mehdi

Reputation: 1755

bind function to an element that created by javascript

i want to create a calendar with javascript:

i'm create elements by this function:

createElem : function (name, attrs){
     var el = document.createElement(name);
     for(var key in attrs) {
        el.setAttribute(key, attrs[key]);
     }
     return el;
}

table :

var tb=this.createElem("table", {"class":"p-calendar", id: "p-calendar"});

rows and cells :

for(var i=2; i<to; i++){
    tb.insertRow(i);
    for(var j=0; j < 7; j++){
       tb.rows[i].insertCell(j);
       .
       .

so in my loop:

tb.rows[i].cells[j].className="day"; // it's work

but :

tb.rows[i].cells[j].onclick = function(){
    tb.rows[i].cells[j].id = "today";
}  // Unable to set property 'id' of undefined or null reference 
  1. Why does the error?!
  2. what is best way to bind function to an element that created by javascript?

Thanks in advance.

Upvotes: 0

Views: 554

Answers (1)

Tanzeel Kazi
Tanzeel Kazi

Reputation: 3827

Short answer: You need a closure for your onclick handler.

Long answer: Your indices i and j are incremented in a for loop. Your onclick handlers are called way later when you actually click on the element. Guess what's the value of i and j then. They are out of bounds of the element arrays of rows and cells. That means every element is using the same values of i and j and none of them are getting values within the bounds of the element array. You can verify this by logging the values of i and j within your current onclick handler.

Solution:

Replace the block:

tb.rows[i].cells[j].onclick = function(){ ... }

with:

var getOnclickMethod = function (i, j) {
    var cur_i = i * 1;
    var cur_j = j * 1;
    var callback = function(){
        tb.rows[cur_i].cells[cur_j].id = "today";
    };
    return callback;
};

tb.rows[i].cells[j].onclick = getOnclickMethod(i, j);

Upvotes: 1

Related Questions