Dynamic row addition at the bottom of Table in IE - javascript

Based on the button click event, I want to add rows dynamically at the bottom of an existing table.
I had done the same using Javascript which is given below. It is working fine in Chrome browser whereas in IE the rows are getting added at the top rather than at the bottom.
If I click the button multiple times then could see that all the rows are getting added at the top one after the other in IE.
function addRow(tableID) {
var table = document.getElementById(tableID);
var tbody = table.getElementsByTagName('tbody')[0];
var rowCount = table.querySelectorAll("tbody tr").length;
var row = tbody.insertRow(-1);
var cell1 = row.insertCell(0);
cell1.classList.add("PadLeft10");
cell1.classList.add("PadBottom5");
cell1.classList.add("textcenter");
cell1.width = "2%";
var element1 = document.createElement("input");
element1.type = "checkbox";
element1.name = "element1[" + index + "].selected";
element1.id = "element1[" + index + "].selected";
cell1.appendChild(element1);
[...]
}
I could see in the docs that tbody.insertRow(-1) should append row at the last in both IE and Chrome, but for me in IE it is getting added at the top. I tried many ways but in all it works fine in Chrome but not in IE.
Any help?

If the insertRow part is the problem, you can do this to reliably add to the end instead:
var row = document.createElement("tr");
tbody.appendChild(row);
Similarly, var cell1 = row.insertCell(0); (if it is also a problem) can be:
var cell1 = document.createElement("tr");
row.insertBefore(cell1, row.firstChild);
Finally, MDN says that IE has long supported insertAdjacentHTML (all the way back to IE4), so that entire method could be replaced with the following if you like:
function addRow(tableID) {
var table = document.getElementById(tableID);
var tbody = table.querySelector("tbody");
var rowCount = table.querySelectorAll("tr").length; // Or: `= table.rows.length;`
// ***Where does `index` come from? Did you mean `rowCount`?
var name = "element1[" + index + "].selected";
var html =
'<tr>' +
'<td class="PadLeft10 PadBottom5 textcenter" width="2%">' +
'<input type="checkbox" name="' + name + '" id="' + name + '">' +
'</td>' +
'</tr>';
tbody.insertAdjacentHTML("beforeend", html);
// ...
}

Related

adding row and then deleting causes duplicate rows

So when I add new rows each row is given an id that increments according the number of rows already added. if I add three rows and then delete the second row, then add another row, now the new row has an id the same as the old third row.
is there an easier way to do this or a loop that i can perform to check for an existing number.
$('body').delegate('.remove', 'click', function() {
$(this).parent().parent().remove();
});
function addnewrow() {
var n = ($('.detail tr').length - 0) + 1;
var tr = '<tr>' +
'<td>' + n + '</td>' +
'<td><select id="drop' + n + '" class="select-service" name="prodService[]"> <
option value = "" > -Choose Service - < /option></select > < /td>'+
'<td id="desc' + n + '"></td>' +
'<td>Delete</td>' +
'</tr>';
Try this way...Put counter outside of the function.
$('body').on("click", '.remove', function() {
$(this).closest("tr").remove();
});
var n = 1;
$('body').on('click', '.add-new-row', function() {
var $tr = $("<tr />");
var $td1 = $("<td />").text(n).appendTo($tr);
var $td2 = $("<td />").append("<select id='drop" + n + "' class='select-service' name='prodService[]' />").appendTo($tr);
var $td3 = $("<td id='desc" + n + "' />").appendTo($tr);
var $td4 = $("<td />").append("<a href='#' class='remove'>Delete</a>").appendTo($tr);
$("table").append($tr);
n++;
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="add-new-row">Add New Row</button>
<table></table>
Using jQuery is nice because you can avoid writing these giant element strings, so I've gone ahead and rewritten your addnewrow() function to (hopefully) make it slightly cleaner.
As far as determining the IDs, while I believe what talg123 suggested in the comments would be fine - storing a global variable that just increases by 1 each time you add a new row - I personally try to avoid polluting the global scope where I can.
You can use this line to find the last drop id, and remove the "drop" text from it so you're just left with a number.
$("tr select").last().attr("id").replace("drop", "");
Unfortunately, this will break if there are no rows becuase it won't be able to find any select elements. So, first we have to check if they exist:
+$("tr select").length ? (exists) : (does not exist)
If it doesn't exist, we'll just use 1.
Put that all together, and you've got:
//If select exists Get last ID and remove "drop" from it, and add 1 Else, 1
$("tr select").length ? 1 + +$("tr select").last().attr("id").replace("drop", "") : 1;
$('body').on("click", '.remove', function() {
$(this).closest("tr").remove();
});
$('body').on('click', '.add-new-row', function() {
var nextId = $("tr select").length ? 1 + +$("tr select").last().attr("id").replace("drop", "") : 1;
//Create a new select list
var $selectList = $("<select id='drop" + nextId + "' class='select-service' name='prodService[]' />");
$selectList.append("<option> -Select Service- </option"); //Append option 1
$selectList.append("<option> Another example </option"); //Append option 2
var $tr = $("<tr />"); //Create a new table row
var $td1 = $("<td />").text(nextId).appendTo($tr); //Create first cell. Set text to nextId. Add it to the row.
var $td2 = $("<td />").append($selectList).appendTo($tr); //Create second cell. Add our select list to it. Add it to the row.
var $td3 = $("<td id='desc" + nextId + "' />").appendTo($tr); //Create third cell. Set its id to 'desc{nextId}'. Add it to the row.
var $td4 = $("<td />").append("<a href='#' class='remove'>Delete</a>").appendTo($tr); //Create fourth cell. Add link to it. Add it to the row.
$("table").append($tr); //Add the row to the table
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="add-new-row">Add New Row</button>
<table></table>

Ordering Child Table data using JQuery

I am creating dynamic data and displayed in child table using DOM object. This is the child table detail.
<table id="stdConTbl" width="135px" height="80px" class = "stdConTbl">
</table>
This is the code to create dynamic tr data.
var tbody = document.getElementById("stdConTbl").tBodies[0];
var tr = document.createElement('tr');
var td = document.createElement('td');
var att = document.createAttribute("width");
att.value = "1%";
td.setAttributeNode(att);
var td1 = document.createElement('td');
td.innerHTML = '<input type = "radio" style = "BACKGROUND-COLOR: #e1e8ee" id = "' + tmpCount + '" name = "' + radioName + '" value = "' + txtValue + '" onclick = "setTblRowId()"/>';
td1.innerHTML = '<label id = '+ tmpCount +"'>" +txtValue + '</label>';
tr.appendChild(td);
tr.appendChild(td1);
//var radioHtml = tr.innerHTML;
tbody.appendChild(tr);
Using this two button I am ordering these table data.
<img src="<%=request.getContextPath()%>/images/procseq/up.png" style="cursor: hand;" class="up" />
<img src="<%=request.getContextPath()%>/images/procseq/down.png" style="cursor: hand;" class="down" />
When i choosing this dynamically created radio button and click on "UP" button, the selected radio button label should be move one step to up and again i click on "UP" button the label should move one more step.
Same thing i follow when i click on "DOWN" button.
But I am not able to get child table row index.
This the code to order data.
$(document).ready(function(){
$(".up,.down").click(function(){
var selectedIndex = 0;
//var row = $(this).parents("tr:first"),$reindex_start;
for(var i = 0; i < document.getElementsByName('stdConRadio').length; i++){
if(document.getElementsByName('stdConRadio')[i].checked){
selectedIndex = document.getElementsByName('stdConRadio')[i].getAttribute("id");
}
}
var row = $(this).parents(".stdConTbl"),$reindex_start;
//var row_index = $(this).closest('tr').index();
if ($(this).is(".up")) {
//row.insertBefore(selectedIndex - 1);
row.insertBefore(row.prev());
$reindex_start=row;
} else {
$reindex_start=row.next();
row.insertAfter(row.next());
}
});
});
Try this : find tr of the the selected radio button and then use insertAfter or insertBefore to move tr.
$(document).ready(function(){
$(".up,.down").click(function(){
//get tr of selected radio button
var $tr = $('#stdConTbl').find('input[name="stdConRadio"]:checked').closest("tr");
//insert
if ($(this).is(".up")) {
$tr.insertBefore($tr.prev("tr"));
} else {
$tr.insertAfter($tr.next("tr"));
}
});
});

How to append tds into tableRows?

I'm trying to append different <td>-elements to corresponding tr-elements, but no matter, what I am trying: it does not work :-/ Unfortunately I'm not able to show you an complete jsfiddle, because the whole table stuff is rather complex and depends on a map and stuff like that, but I hope some code snippets are also okay.
Table-Structure (header)
var table = createElement('table');
table.className = "table";
table.id = "table";
var header = table.createTHead();
var row = header.insertRow(0);
var cell0 = row.insertCell(0);
cell0.innerHTML = "Indicator"
var cell1 = row.insertCell(1);
cell1.innerHTML = "Current value"
var cell2 = row.insertCell(2);
cell2.innerHTML = "High value"
var cell3 = row.insertCell(3);
cell3.innerHTML = "Low value"
var cell4 = row.insertCell(4);
cell4.innerHTML = "Average";
var cell5 = row.insertCell(5);
cell5.innerHTML = "Pic";
tbody = table.appendChild(document.createElement('tbody'));
Then I'm using a for-loop, where the rest of the table is created:
//"key" is the description of the "value"
for (var key in values) {
//...
//method to calculate the values
...
//append values to tbody
$(table).find(tbody).append("<tr>");
$(table).find(tbody).append( "<td>"+(indicatorValue));
$(table).find(tbody).append( "<td>"+(regionValue));
$(table).find(tbody).append( "<td>"+(bestValues));
$(table).find(tbody).append( "<td>"+(worstValues));
$(table).find(tbody).append( "<td>"+(average));
//append image to a td-element
var img = "<img src='img/green_circle.png' />";
if (picIdentifier != 'green') {
img = "<img src='img/red_circle.png' />";
}
$(table).find(tbody).append( "<td>"+ img +"</td>");
}
Using the above code, the table looks like the following jsfiddle: http://jsfiddle.net/nwd6na53/2/
As you can see, the td-elements in the tbody are not wrapped in the tr-element, but the table-rows are empty.
Do you have any tip how to put the tds into the tr-elements? Any help is much appreciated!
Within your for loop, you need something more like this:
for (var i = 0; i <= 10; i++) {
var row = $('<tr></tr>');
$(row).append('<td>row ' + i + ', column1</td>');
$(row).append('<td>row ' + i + ', column2</td>');
$(row).append('<td>row ' + i + ', column3</td>');
$('#mytable').find('tbody').append(row);
}
Here's a fiddle with a code example:
https://jsfiddle.net/u2enny6o/3/
Note that I include complete tags in the append().
Better yet would be to use the insertRow() and insertCell() approach you use for the header section.
The answer of #Marc doesn't run well. See this
jsfiddle fail.
I think you should create a variable for an element tr. And append this tr to the tbody. For example, see this jsfiddle success :
var row = '<tr>' + '<td>' + indicatorValue + '</td><td>' + regionValue + '</td>' + '<td>' + bestValues + '</td></tr>';
$('table').find('tbody').append(row);

Dynamic adding input fields into columns

I had this block of code in javascript which does add dynamic input fields. Every thing works fine at this point. My question is how would I add more input fields within the table in other cell respectively with the village name input fields? When user Add Village 1/Remove Village 1, either of the action should add/remove aligning input field on column named:Type of participatory forest management, Year participatory management process started and Size of forest. The input fields increment of the columns mentioned above should reflect the increment of dynamic input field of village name column. Later I will use the dynamic input fields with Php on sending the values to database. Thanks for your time!
Below is script:
script code:
<script language="JavaScript" type="text/javascript">
function getById(e){return document.getElementById(e);}
function newElement(tag){return document.createElement(tag);}
function newTxt(txt){return document.createTextNode(txt);}
function addForestName()
{
var tbl = getById('tblSample'); //note the single line generic functions written above
var lastRow = tbl.rows.length;
// if there's no header row in the table, then iteration = lastRow + 1
var iteration = lastRow;
var row = tbl.insertRow(lastRow);
// Column which has iteration count
var cell_no = row.insertCell(0);
var textNode = newTxt(iteration);
cell_no.appendChild(textNode);
// Column which has the forest name
var frstNameCell = row.insertCell(1);
var el_input = newElement('input'); //create forest name input
el_input.type = 'text';
el_input.name = 'forest_text_' + iteration;
el_input.id = 'forest_text_' + iteration;
el_input.size = 40;
frstNameCell.appendChild(el_input);
// Column which has the village name
var villageNameCell = row.insertCell(2);
var el_label = newElement('label');
el_label.for = 'village_text_' + iteration + '_1';
var el_labelValue = '1.';
textNode = newTxt(el_labelValue);
el_label.appendChild(textNode);
villageNameCell.appendChild(el_label);
el_input = newElement('input');
el_input.type = 'text';
el_input.name = 'village_text_' + iteration + '_1';
el_input.id = 'village_text_' + iteration + '_1';
el_input.size = 40;
villageNameCell.appendChild(el_input);
el_btn = newElement('input'); //create village name add button
el_btn.type = 'button';
el_btn.name = 'village_btn_' + iteration;
el_btn.id = 'village_btn_' + iteration;
el_btn.value = 'Add Village Forest ' + iteration;
el_btn.addEventListener('click',addMoreVillageNames, false);
villageNameCell.appendChild(el_btn);
el_btn = newElement('input'); //create village name remove button
el_btn.type = 'button';
el_btn.name = 'village_rembtn_' + iteration;
el_btn.id = 'village_rembtn_' + iteration;
el_btn.value = 'Remove Village Forest ' + iteration;
el_btn.addEventListener('click',removeVillageName, false);
villageNameCell.appendChild(el_btn);
var frstManagCell = row.insertCell(3); // create forest management input
el_input = newElement('input');
el_input.type = 'text';
el_input.name = 'frstManage_text_' + iteration + '_1';
el_input.id = 'frstManage_text_' + iteration + '_1';
el_input.size = 40;
frstManagCell.appendChild(el_input);
var yerPartCell = row.insertCell(4); // create year participatory input
el_input = newElement('input');
el_input.type = 'text';
el_input.name = 'yrPart_text_' + iteration + '_1';
el_input.id = 'yrPart_text_' + iteration + '_1';
el_input.size = 40;
yerPartCell.appendChild(el_input);
var frstSizeCell = row.insertCell(5); // create forest size input
el_input = newElement('input');
el_input.type = 'text';
el_input.name = 'frstSize_text_' + iteration + '_1';
el_input.id = 'frstSize_text_' + iteration + '_1';
el_input.size = 40;
frstSizeCell.appendChild(el_input);
}
function addMoreVillageNames(){
rowNumber = (this.id).substring((this.id.length)-1, this.id.length); //to get Row Number where one more input needs to be added.
var childElCount;
var parentCell = this.parentNode;
var inputCount = parentCell.getElementsByTagName('label').length; //to get the count of input fields present already
var newFieldNo = inputCount + 1; //input current count by 1 to dynamically set next number for the new field
//temporarily remove the add and remove buttons to insert the new field before it.we are doing this loop only twice because we know the last 2 input elements are always the two buttons
for (var i=0; i<2; i++){
childElCount = parentCell.getElementsByTagName('input').length; //get count of child input elements (including text boxes);
parentCell.removeChild(parentCell.getElementsByTagName('input')[childElCount-1]);
}
var lineBreak = newElement('br');
parentCell.appendChild(lineBreak); //add a line break after the first field
var el_label = newElement('label');
el_label.for = 'village_text_' + rowNumber + '_' + newFieldNo;
var el_labelValue = newFieldNo + '.';
var textNode = newTxt(el_labelValue);
el_label.appendChild(textNode);
parentCell.appendChild(el_label); //create and add label
var el_input = newElement('input');
el_input.type = 'text';
el_input.name = 'village_text_' + rowNumber + '_' + newFieldNo;
el_input.id = 'village_text_' + rowNumber + '_' + newFieldNo;
el_input.size = 40;
parentCell.appendChild(el_input); //create and add input field
var el_btn = newElement('input'); //add the village name add button again
el_btn.type = 'button';
el_btn.name = 'village_btn_' + rowNumber;
el_btn.id = 'village_btn_' + rowNumber;
el_btn.value = 'Add Village ' + rowNumber;
el_btn.addEventListener('click',addMoreVillageNames, false);
parentCell.appendChild(el_btn);
el_btn = newElement('input'); //create village name remove button
el_btn.type = 'button';
el_btn.name = 'village_rembtn_' + rowNumber;
el_btn.id = 'village_rembtn_' + rowNumber;
el_btn.value = 'Remove Village ' + rowNumber;
el_btn.addEventListener('click',removeVillageName, false);
parentCell.appendChild(el_btn);
}
function removeForestName()
{
var tbl = document.getElementById('tblSample');
var lastRow = tbl.rows.length;
if (lastRow > 2) tbl.deleteRow(lastRow - 1);
}
function removeVillageName()
{
var rowNumber = (this.id).substring((this.id.length)-1, this.id.length); //to get Row Number where one more input needs to be added.
var parentCell = this.parentNode;
var lblCount = parentCell.getElementsByTagName('label').length;
var inputCount = parentCell.getElementsByTagName('input').length;
var brCount = parentCell.getElementsByTagName('br').length;
//Remove will not happen if there is only one label-input combo left.
if(lblCount>1)
parentCell.removeChild(parentCell.getElementsByTagName('label')[lblCount-1]);
if(inputCount>3)
parentCell.removeChild(parentCell.getElementsByTagName('input')[inputCount-3]); //Delete the third last element because the last two are always the two buttons.
parentCell.removeChild(parentCell.getElementsByTagName('br')[brCount-1]);
}
window.onload = addForestName;
</script>
<form action="tableaddrow_nw.html" method="get">
<table width="640" border="1" id="tblSample">
<tr>
<td>No.</td>
<td>Forest Name</td>
<td width="40">Name of the villages <br />participating in managing</td>
<td>Type of participatory forest management</td>
<td>Year participatory management process started</td>
<td>Size of forest</td>
</tr>
</table>
</form>
<p>
<input type="button" value="Add" onclick="addForestName();" />
<input type="button" value="Remove" onclick="removeForestName();" />
</p>
If I understood your question correctly, the below is what you are looking for. Using the following method you can get hold of the required table column (Column Number is hard coded because this is just a sample). Once you have got hold of the required column, adding/removing fields should be straight-forward. Check out this Fiddle for a working sample.
var tbl = document.getElementById('tblSample');
var frstMgmtCell = tbl.rows[rowNumber].cells[3]; //Get hold of the Forest Mgmt Column of that specific row.
On a side note, there are a lot of repeated items which you might want to convert into separate functions for better maintainability.

parenNode.replaceChild not working in IE6

I had a table element in my Html file of FCK editor which i tried to replace with new table element using parentNode.replaceChild method.Though it works fine in Internet Explore 8 but gives me error in IE 6 as well as IE 7.The error i get is "property does not support this object or method".Here is my snippet of code:
var eSelected = FCK.Selection.MoveToAncestorNode( 'TABLE' );
var myTable = document.createElement('TABLE');
var temp1= '<span><strong>' + Title.value + '</strong></span>'; //title.value is value retrieved from a text box
var temp2= '<a onBlur="window.status=' + ';return true"
onMouseOver="window.status=' + ';return true" ' + 'onFocus="window.status=' + ';return true" onMouseOut="window.status=' + ';return true" ' +'href="javascript:pdfPopup('+'\'' + Name.value + '\''+');">'+Name.value+'</a><span>[' + Size.value + ']</span>'; //name.value is also retrieved from a text box
var row1 = myTable.insertRow(0); //create new rows in the table
var cell1= row1.insertCell(0);
cell1.innerHTML=temp1;
var row2 = myTable.insertRow(1);
var cell2= row2.insertCell(0);
cell2.innerHTML=temp2;
var row3 = myTable.insertRow(2);
var cell3= row3.insertCell(0);
cell3.innerHTML=' ';
eSelected.parentNode.replaceChild(myTable,eSelected); // I m getting error at this line`
Do you have a <tbody> tag enclosing the rows?
<table><tbody><tr></tr><tr></tr></tbody></table>
(Sorry, that I can't write this as a comment. I don't have the privileges to do so…)

Categories