attaching JS functions to dynamically created object events - javascript

I use following code to dynamically add rows to my ASP.NET table. I create a span, then fill it with an html textbox code to create some textboxes in my row, now I'm going to attach some functions to my textbox events, for instant blur or keypress event:
var TR = document.createElement('tr');
TR.style.textAlign = 'center';
//mission end date
var TD = document.createElement('td');
var span = document.createElement("span");
span.innerHTML = "<input maxlength='5' type='text' width='50px' style='width:50px;' value=''/>";
TD.appendChild(span);
TR.appendChild(TD);
.......
TR.appendChild(TD);
document.getElementById('<%=tblData.ClientID %>').appendChild(TR);
I've create some other javascript functions that I'd like to attach them to these dynamically created textbox events, for instance:
function onBlur(){
.....
}
how can I attach onBlur to onblur event of these dynamically created objects?
thanks

replace
span.innerHTML = "<input maxlength='5' type='text' width='50px' style='width:50px;' value=''/>";
with
var input = document.createElement("input");
input.style.width="50px";
input.type="text";
input.onblur = your_function_handler;
span.appendChild(input);

Related

Add button with function call for generatet table

I´m filling a table with jquery from a JSON data source
var data = dataJSONMOV,
fragment = document.createDocumentFragment(),
tr, td, i, il, key;
for(i=0, il=data.length;i<il;i++) {
tr = document.createElement('tr');
for(key in data[i]) {
td = document.createElement('td');
td.appendChild( document.createTextNode( data[i][key] ) );
tr.appendChild( td );
}
//Button generation code should go here (see below)
fragment.appendChild( tr );
}
$('#mytable tbody').append( fragment.cloneNode(true) );
I want to add a button in the end of each row which calls a function displayInformation(string ID) with a parameter from the first coloumn of that row.
How can I accomplish that?
I tried it with this code but it doesn`t show me any buttons
//Button generation code
var btn = document.createElement('input');
btn.type = "button";
btn.className = "btn";
btn.value = data[i][0];
btn.onclick = (getTestAlert(data[i][0]));
tr.appendChild(btn);
You are on right direction on how add the button. You can add it and them add an event listener to the table:
$('#mytable').on("click", "input", function() {
});
// Or
$('#mytable').on("click", "input", getTestAlert);
So, to know what id it belongs, add a data attribute:
var btn = document.createElement('input');
btn.dataset.id = data.id;
And how to retrieve it:
$('#mytable').on("click", "button", function() {
var id = $(this).data("id"); // For jQuery
id = this.dataset.id; // For vanilla
});
Your loop would probably end like this:
for(i=0, il=data.length;i<il;i++) {
tr = document.createElement('tr');
for(key in data[i]) {
td = document.createElement('td');
td.appendChild( document.createTextNode( data[i][key] ) );
tr.appendChild( td );
}
// Add button in last column
var btn = document.createElement('input');
btn.type = "button";
btn.className = "btn";
btn.value = data[i][0];
btn.onclick = (getTestAlert(data[i][0]));
tr.appendChild(btn);
fragment.appendChild( tr );
}
Working demo
Besides, I don't know if its some kind of a requirement, but if you're using jQuery, you should use it for your entire code, like the elements creating as well. Creating elements may be odd in some browsers and jQuery takes care of it. If you're interested, your code should became something like:
var data = dataJSONMOV,
fragment = document.createDocumentFragment(),
key, html = "";
for(var i=0, il=data.length;i<il;i++) {
html+= "<tr>";
for(key in data[i]) {
html+= "<td>" + data[i][key] + "</td>";
}
html+= "<td><input type='button' class='btn' value='Click me' data-id='" + data[i].id + "' /></td></tr>";
}
$("#mytable").append(html);
Pretty short, huh ?
Because you're populating the table dynamically, you need to add a click listener based on some parent defined in the html. Assuming this is the case for '#myTable tbody' and that the parameter from the first column of that row that you need for displayInformation() is accessible via .text(), you could use
$(document).ready(function() {
$('#myTable tbody').on('click', 'input[type="button"]', function() {
displayInformation($('td:first-child', $(this).parents('tr')).text());
});
});
to create the click listener for the row's button.

link a checkbox to an object in Javascript

Suppose I have a table which is populated by filling out a form on a page and clicking the submit button.
The last column of the table is a Completed section with a checkbox on each row. On clicking on the checkbox I want to change the .completed property from false to true on that object.
How can I distinguish which checkbox was clicked and change the property from that row?
this.addRowToTable = function() {
return "<tr id='tableRow'><td>" + this.app + "</td><td>" + this.priority + "</td><td>" + this.date + "</td><td>" + this.additionalNotes + "</td><td>" + "<input type='checkbox' class='checkApp[]' value='" + this.completed + "' />" + "</td></tr>";
};
I have all the checkboxes in the checkApp array, but Im not sure where to go from there?.
This is called when the form is submitted:
function addAppointment() {
if (txtApp.value == "" || txtPriority.value == "" || txtDate.value == "" || {
alert("Please fill all text fields");
} else {
var app = new Appointment(txtApp.value, txtPriority.value, txtDate.value, txtNotes.value, false);
apps.push(app);
localStorage.setItem("apps", JSON.stringify(apps));
clearUI();
}
updateTable();
updateTable() loops through all objects in my array and adds them between table tags:
for (var i = 0; i < apps.length; i++) {
var app = new Appointment(apps[i].app, apps[i].priority, expenses[i].date, apps[i].notes, false);
tblHTML += app.addRowToTable();
}
My Appointment Object:
function Appointment(app, priority, date, notes, completed) {
this.app = app;
this.priority = priority;
this.date = date;
this.additionalNotes = notes;
this.completed = completed;
this.addRowToTable = function { ... };
}
First of all, in HTML, id attributes should be unique. So, make sure table rows have unique IDs. At the moment, all of them have the identical ID of tableRow.
Besides, you should consider using a framework/library such as jQuery for real-world scenarios rather than creating the DOM elements, etc. manually.
Now back to the original problem: if you use the DOM API rather than string concatenation to create the table rows, you can add custom fields to the DOM objects representing the table rows. So, from each table row, you can have a reference back to its corresponding Appointment object:
var row = document.createElement("tr");
row.appointment = this;
Similarly, you can use the DOM API to create the table cells as well as the checkbox:
addTd(row, this.app);
addTd(row, this.priority);
addTd(row, this.date);
addTd(row, this.additionalNotes);
var input = document.createElement("input");
var td = document.createElement("td");
td.appendChild(input);
row.appendChild(td);
input.setAttribute("type", "checkbox");
input.setAttribute("class","checkApp[]"); // Why checkApp[]? checkApp or check-app make more sense
input.setAttribute("value", this.completed);
where addTd is the following function:
function addTd(row, innerHTML) {
var td = document.createElement("td");
td.innerHTML = innerHTML;
row.appendChild(td);
}
Now that you are using the DOM APIs, you can easily attach event listeners to each checkbox object as well.
Then inside the event listener you can get a reference back to the Appointment corresponding to the row you
have changed its checkbox:
var row = document.createElement("tr");
row.appointment = this;
addTd(row, this.app);
addTd(row, this.priority);
addTd(row, this.date);
addTd(row, this.additionalNotes);
var input = document.createElement("input");
var td = document.createElement("td");
td.appendChild(input);
row.appendChild(td);
input.setAttribute("type", "checkbox");
input.setAttribute("class","checkApp[]"); // Why checkApp[]? checkApp or check-app make more sense
input.setAttribute("value", this.completed);
input.addEventListener("change", function(event) {
var row = this.parentNode.parentNode,
appointment = row.appointment;
// change appointment however you like
});

Bind jquery datepicker to dynamic row Textfield

In HTML table, there is a text field on which I have binded Jquery datepicker control:
$("#CreatedOnValue").datepicker();
It works fine. The table is dynamic and user can add as many rows as he wants by clicking on add button adjacent to each row. I am trying to bind datepicker control to dynamic rows as well and it is not working. Here is function which is executed when user clicks on row add button:
function addGroupRow(e) {
var rowId = e.parentNode.parentNode.id;
var newindex = getConditionPlacementIndex(rowId);
var row = document.getElementById("advancedSearch").insertRow(newindex);
...
// create table cell of datetime textbox
var cell3 = row.insertCell(3);
cell3.id = row.id+"_cell3";
var strHtml3 = "<INPUT class=\"textbox\" TYPE=\"text\">";
cell3.innerHTML = strHtml3.replace(/!count!/g, count);
$("#" + cell3.id).datepicker();
}
Its not working and datepicker does not appear on dynamic text field. Any suggestion?
Thanks.
Use class instead of id(Give dynamically generated textboxes a class say 'textbox') and do as :
$('body').on('focus',".textbox", function(){
$(this).datepicker();
});​
Working Demo
I have resolved this issue by following code modification:
var cell3 = row.insertCell(3);
var cell3Id = row.id+"_cell3";
var strHtml3 = "<INPUT class=\"textbox\" TYPE=\"text\" id=" + cell3Id + ">";
cell3.innerHTML = strHtml3.replace(/!count!/g, count);
$("#" + cell3Id).datepicker();

JavaScript Add Textbox Dynamically when Button onClick

I am trying to add a new textbox when add button is onclick using JavaScript. Here is my HTML:
htmlStr += "<div id='filterContent' style='width:100%;text-align:center;'>";
htmlStr += "<input id='startLoc' type='text' />";
htmlStr += "<input id='endLoc' type='text' />";
htmlStr += "<input id='addLoc' type='button' value='Add' onClick='addTextBox()' />";
htmlStr += "</div><br/>";
And here is my JavaScript to add a new textbox when button is onClick:
function addTextBox(){
var element = document.createElement("input");
element.setAttribute("type", "text");
element.setAttribute("value", "");
element.setAttribute("name", "Test Name");
//element.setAttribute("style", "width:200px");
var foo = document.getElementById("filterContent");
foo.appendChild(element);
}
It works perfectly to add as many textbox as I want. But somehow the textbox created share the same id. I wonder is that possible to add many textbox with different ID each time when the button is onClick?
Thanks in advance.
var aa=Math.random();
<input id='addLoc"+aa+"' type='text' />
User math.random to generate random id's for a textbox
Using your current setup you could keep track of an id increment in a global:
//outside function
var idIndex = 1;
function addTextBox(){
var element = document.createElement("input");
element.setAttribute("type", "text");
element.setAttribute("value", "");
element.setAttribute("name", "Test Name");
element.setAttribute("id", "addLoc" + idIndex++);
element.setAttribute("style", "width:200px");
element.onclick = function()
{
//do something
}
var foo = document.getElementById("filterContent");
foo.appendChild(element);
}
EDIT: To answer the question in this answer's comments. It is certainly possible to add a different onclick handler for every new textbox (although you're probably better off designing your handlers so you can use a single handler for all but if you wanted for some reason to use a different one you could bind an anonymous function to the handler, I have added an approach above).
EDIT2: Regarding the second question in the path there are two approaches you could use. Instead of calling the separate functions getFirstPath() getSecondPath() etc. individually, you could have a single function called getPath() and pass the index to it as a parameter:
var getPath = function(index) {
switch(index)
{
case 1:
return getFirstPath();
break;
case 2:
return getSecondPath();
break; //and so on.
}
}
And then your onclick would look like this:
element.onclick = function()
{
getPath(index);
}

Get value of dynamically created textbox using JavaScript

I'm using JavaScript to dynamically add rows to a table, I create some textboxes in each row, I've added an onkeyup event to one of my textboxes:
var myTotal = "1";
var spanTotal = document.createElement("span");
spanTotal.innerHTML = "<input style=\"width:50px\" type=\"text\" name=\"total\" value=" + myTotal + ">";
spanCount.onkeyup = function ()
{
alert(spanTotal.innerHTML);
};
then I add this span (which is rendered as an HTML textbox) to my table row. I want to have value of my dynamically created textbox, but whenever I change this textbox, initial value of this textbox is displayed in alert box (i.e. 1). Initial value of this textbox is "1", but when I change it (for instance type a 0 in textbox), again "1" is displyaed in alert box. I want to have value of my dynamically created textbox, should I give an ID to my span? how should I define spanCount.onkeyup function? where should it be defined so that I can have exact value of this textbox?
I created a jsFiddle. You can get value of input box using childNodes. There are other problems in code you were using spanCount istead of spanTotal.
Modified code:
var myTotal = "1";
var spanTotal = document.createElement("span");
spanTotal.innerHTML = "<input style=\"width:50px\" type=\"text\" name=\"total\" value=" + myTotal + ">";
document.body.appendChild(spanTotal);
spanTotal.onkeyup = function() {
alert(spanTotal.childNodes[0].value);
};​
Below modified code maybe can solve your problem:
var myTotal = 1;
/* object creation */
var span = document.createElement('span');
var input = document.createElement('input');
input.setAttribute('type', 'text');
input.setAttribute('name', 'total');
input.setAttribute('style', 'width:50px;');
input.setAttribute('value', myTotal);
// append each object to respective container
span.appendChild(input);
document.appendChild(span);
/* event handler */
input.onkeyup = function(){
alert(this.value);
}

Categories

Resources