javascriptfirefoxdom-eventsfirefox-addon-sdkfirefox-addon-webextensions

HTML onclick event not working with innerHTML syntax for creating the button in the cell


I have this code which should insert a button in a table cell. The button has action so I add onclick. However, the syntax for onclick='function_name' is with single quotes. I used single quotes with/without backslash, but nothing solved the error I'm getting. I get editRow is not defined and pressing the button has no effect. I also found that the HTML is interpreting the single quote I entered in the text of the cell as double quotes. I do not know what is the source of the problem.

var info = [{
  "firstName": "aaa",
  "lastName": "A"
}, {
  "firstName": "bbb",
  "lastName": "B"
}, {
  "firstName": "ccc",
  "lastName": "C"
}];
function display(info) {
var table=document.getElementById("table");
var Length=info.length;

for(var i=0; i<info.length; i++)
{
    var row = table.insertRow(i+1);
    var cell1 = row.insertCell(0);
    var cell2 = row.insertCell(1);
    var cell3 = row.insertCell(2);
                            
    cell1.innerHTML = info.[i].firstName;
    cell2.innerHTML = info.[i].lastName;
    
    var editButtonHTML = "<input type=button value=Edit class=edit id=edit-button"+(i+1)+" onclick=\'editRow("+(i+1)+")\'>";
    
    cell3.innerHTML=editButtonHTML;
}//end for  

function editRow()
{
    console.log("inside editRow "+(i+1));
}

//console.log(table.innerHTML);
}//end display

The solution provided by @Rohit Kumar works when running the code in Firefox browser. But when running it in the addon extension using jpm, it gives:

ReferenceError: editRow is not defined

Also, when I print the HTML code in the table, I see double quotation not single.

I also tried this after the button but did not work. The getElement returns null.

butId="edit-button"+(i+1);
    console.log("button id is: "+butId);
    
    document.getElementById(butId).addEventListener('click',editRow);

Solution

  • In your example when you are adding DOM element as a string, on click you are calling 'editRow' function in global (window) context.

    What you should do is to create element, bind context with needed parameters and append it as a child DOM element:

    var editButtonHTML = document.createElement('input');
    editButtonHTML.type = 'button';
    editButtonHTML.value = 'Edit';
    editButtonHTML.className = 'edit';
    editButtonHTML.id = 'edit-button' + (i+1);
    editButtonHTML.onclick = editRow.bind(this, i + 1);
    cell3.appendChild(editButtonHTML);
    

    Here is full solution:

    var info = [{
      "firstName": "aaa",
      "lastName": "A"
    }, {
      "firstName": "bbb",
      "lastName": "B"
    }, {
      "firstName": "ccc",
      "lastName": "C"
    }];
    
    function display(info) {
      var table = document.getElementById("table");
      var Length = info.length;
    
      for(var i = 0; i < info.length; i++){
          var row = table.insertRow(i);
          var cell1 = row.insertCell(0);
          var cell2 = row.insertCell(1);
          var cell3 = row.insertCell(2);
    
          cell1.innerHTML = info[i].firstName;
          cell2.innerHTML = info[i].lastName;
    
          var editButtonHTML = document.createElement('input');
          editButtonHTML.type = 'button';
          editButtonHTML.value = 'Edit';
          editButtonHTML.className = 'edit';
          editButtonHTML.id = 'edit-button' + (i + 1);
          editButtonHTML.onclick = editRow.bind(this, i + 1);
          cell3.appendChild(editButtonHTML);
      }
    
      function editRow(num){
          console.log('inside editRow ' + num);
      }
    }
    
    display(info);