Đorđe Stanivuković Đorđe Stanivuković - 1 month ago 6
HTML Question

Issue with dynamically created Javascript table

I recently started to learn Javascript. I'm currently working on some project and I ran into a problem. I'm making contact manager page, the idea is that the user enters name, email and a phone number which will be displayed in the dynamically created HTML table below. There are three buttons. The first button save's information, second clears input fields for new user and third deleteds localStorage information. When you click on a row in the table, information from that row are to be displayed in the input fields above. When you click on a row in HTML table everything is working fine, but when I click on the row in the table created using JavaScript it doesn't work. Both tables have the same structure, id's and class, but the other one doesn't work.
Information form Javascript are displayed in dvcontainer div.

Here's the code



(function (){

var Person = {
Name: "",
Email: "",
MobileNo: ""
};

var applogic = {
clearuielements: function () {
var inputs = document.getElementsByClassName("c1");
for (i = 0; i < inputs.length; i++) {
inputs[i].value = "";
}
},

saveitem: function () {
var lscount = localStorage.length;
var inputs = document.getElementsByClassName("c1");
Person.Name = inputs[0].value;
Person.Email = inputs[1].value;
Person.MobileNo = inputs[2].value;
localStorage.setItem("Person_" + lscount, JSON.stringify(Person));
location.reload();
},

loaddata: function () {
var datacount = localStorage.length;
if (datacount > 0) {
var render = "<table id='t_id' border='1'>";
render += "<tr><th>Name</th><th>Email</th><th>Phone</th></tr>";
for (i = 0; i < datacount; i++) {
var key = localStorage.key(i);
var person = localStorage.getItem(key);
var data = JSON.parse(person);

render += "<tr><td class='row_s edit_row'>" + data.Name + "</td>";
render += "<td class='row_t'>" + data.Email + "</td>";
render += "<td class='row_d'>" + data.MobileNo + "</td></tr>";
}
render+="</table>";
dvcontainer.innerHTML = render;
}
},

clearstorage: function () {
var storagecount = localStorage.length;
if (storagecount > 0) {
for (i = 0; i < storagecount; i++) {
localStorage.clear();
}
}
window.location.reload();
}
};

var btnsave = document.getElementById('btnsave');
btnsave.addEventListener('click', applogic.saveitem, false);

var btnclear = document.getElementById('btnclear');
btnclear.addEventListener('click', applogic.clearuielements, false);

var btnclearstorage = document.getElementById('btnclearstorage');
btnclearstorage.addEventListener('click', applogic.clearstorage, false);

window.onload = function () {
applogic.loaddata();
};

})();

var edit_row = document.querySelectorAll('#t_id .edit_row');
for(var i=0; i<edit_row.length; i++) {
edit_row[i].addEventListener('click', function(e){
var tr_parent = this.parentNode;
document.getElementById('e_site').value = tr_parent.querySelector('.row_s').innerHTML;
document.getElementById('e_title').value = tr_parent.querySelector('.row_t').innerHTML;
document.getElementById('e_desc').value = tr_parent.querySelector('.row_d').innerHTML;
}, false);
}

<!DOCTYPE html>
<html>
<head>
<title>nesto</title>
</head>
<body>

<form action="#" method="post" id="edit_form">
Person Name:<input name="e_site" id="e_site" type="text" class="c1" /><br/>
Email:<input name="e_title" id="e_title" type="text" class="c1" /><br/>
Mobile No:<input name="e_desc" id="e_desc" type="text" class="c1"/><br/>
</form>

<td><input id="btnsave" type="button" value="Save" /></td>
<td><input id="btnclear" type="button" value="Clear" /></td>
<td><input id="btnclearstorage" type="button" value="Clear Storage" /></td>

<div id="dvcontainer"></div>


<!--
<table id="t_id" border="1">
<tr>
<td class="row_s edit_row">yyyy</td>
<td class="row_t">yyyy</td>
<td class="row_d">yyyyy</td>
</tr>
</table>
-->


<script type="text/javascript" src="funkcije.js"></script>

</body>
</html>




Answer

You need to add the bindings when you render the table. One way to do this is by moving the binding loop you have at the end of your code into the loaddata function.

Something like this would work:

loaddata: function () { 
        var datacount = localStorage.length; 
        if (datacount > 0) { 
            var render = "<table id='t_id' border='1'>"; 
            render += "<tr><th>Name</th><th>Email</th><th>Phone</th></tr>"; 
            for (i = 0; i < datacount; i++) { 
                var key = localStorage.key(i);
                var person = localStorage.getItem(key);
                var data = JSON.parse(person);

                render += "<tr><td class='row_s edit_row'>" + data.Name + "</td>"; 
                render += "<td class='row_t'>" + data.Email + "</td>"; 
                render += "<td class='row_d'>" + data.MobileNo + "</td></tr>"; 
            } 
            render+="</table>"; 
            dvcontainer.innerHTML = render; 


            //add bindings
            var edit_row = document.querySelectorAll('#t_id .edit_row');
            for(var i=0; i<edit_row.length; i++) {
                edit_row[i].addEventListener('click', function(e){
                    var tr_parent = this.parentNode;
                    document.getElementById('e_site').value = tr_parent.querySelector('.row_s').innerHTML;
                    document.getElementById('e_title').value = tr_parent.querySelector('.row_t').innerHTML;
                    document.getElementById('e_desc').value = tr_parent.querySelector('.row_d').innerHTML;
                }, false);
            }

        } 

See a full example in this JS Fiddle: https://jsfiddle.net/9n8ecmj8/

Hope that helps!