...

View Full Version : Dynamically add row to table



nick2price
09-24-2012, 01:33 AM
Hi guys. I posted a similar question in the html forum, but realised I needed javascript for this. I have also checked out many examples of similar things online, but they all seem to clone the whole table. Basically, I have a simple table with rows like this

<table class="table1">
<tr>
<td class="title">1:</td>
<td><input type="text" placeholder="Giving" class="selector" name="giving2" autocomplete="off"/></td>
<td><input type="text" placeholder="Getting" class="selector" name="getting2" autocomplete="off"/></td>
<td><input type="text" name="popupdate2" id="popupdate2" class="popupdate" value="When" /></td>
</tr>

<tr>
<td class="title">2:</td>
<td><input type="text" placeholder="Giving" class="selector" name="giving2" autocomplete="off"/></td>
<td><input type="text" placeholder="Getting" class="selector" name="getting2" autocomplete="off"/></td>
<td><input type="text" name="popupdate2" id="popupdate2" class="popupdate" value="When" /></td>
</tr>
</table>

What I will do is add a button to add a new row. When clicked, I am not looking to add the whole table, just the tr and whats inside of it e.g.

<tr>
<td class="title">2:</td>
<td><input type="text" placeholder="Giving" class="selector" name="giving2" autocomplete="off"/></td>
<td><input type="text" placeholder="Getting" class="selector" name="getting2" autocomplete="off"/></td>
<td><input type="text" name="popupdate2" id="popupdate2" class="popupdate" value="When" /></td>
</tr>

Is something like this possible? As I say, the examples I have seen so far tend to clone a table rather than a row. Any advise appreciated.

Cheers

AndrewGSW
09-24-2012, 02:07 AM
Cloning and/or dynamically creating the row, tds, inputs, etc., is possible, but because there is quite a lot of content it will be more efficient to make use of innerHTML. I threw this together:


var stdContent = "<td class='title'>xx:</td>" +
"<td><input type='text' placeholder='Giving' class='selector' name='givingxx' autocomplete='off'/></td>" +
"<td><input type='text' placeholder='Getting' class='selector' name='gettingxx' autocomplete='off'/></td>" +
"<td><input type='text' name='popupdatexx' id='popupdatexx' class='popupdate' value='When' /></td>";

var newrow = document.createElement('tr');
// give your table an id..
var theTable = document.getElementById('tableid');
var newno;
newno = 3; // increment at some point
theTable.appendChild(newrow);
var newcontent = stdContent.replace('xx', newno);
newrow.innerHTML = newcontent;

AndrewGSW
09-24-2012, 02:12 AM
You might (scrub that, will!) need


var newcontent = stdContent.replace(/xx/g, newno);
to perform a global replace: it's late at night and I can't recall if replace() only replaces the first occurrence by default.

AndrewGSW
09-24-2012, 02:18 AM
You can include line breaks if you want the HTML to look presentable:


var stdContent = "<td class='title'>xx:</td>\n" +
"<td><input type='text' placeholder='Giving' class='selector' name='givingxx' autocomplete='off'/></td>\n" +
"<td><input type='text' placeholder='Getting' class='selector' name='gettingxx' autocomplete='off'/></td>\n" +
"<td><input type='text' name='popupdatexx' id='popupdatexx' class='popupdate' value='When' /></td>\n";

nick2price
09-24-2012, 02:51 AM
Kool, thanks for the replies. To neaten things up, I have placed the code into a function. I then placed the global replace at the top of the function is it just a case of passing the function the variable e.g.


function addTableRow(var newno){
var newcontent = stdContent.replace(/xx/g, newno);

var stdContent = "<td class='title'>xx:</td>" +
"<td><input type='text' placeholder='Giving' class='selector' name='givingxx' autocomplete='off'/></td>" +
"<td><input type='text' placeholder='Getting' class='selector' name='gettingxx' autocomplete='off'/></td>" +
"<td><input type='text' name='popupdatexx' id='popupdatexx' class='popupdate' value='When' /></td>";

var newrow = document.createElement('tr');
// give your table an id..
var theTable = document.getElementById('tableid');
var newno;
newno = 3; // increment at some point
theTable.appendChild(newrow);
var newcontent = stdContent.replace('xx', newno);
newrow.innerHTML = newcontent;

}

And then where I have the original table, if I have a button for instance, just call the function like so?

<INPUT type="button" value="Add Row" onclick="addTableRow('4')" />

nick2price
09-24-2012, 05:00 PM
Hi guys. Still havnt managed to work out why this isnt working. I dont pass it a variable anymore, just call then function onclick, but no row seems to be added.

AndrewGSW
09-24-2012, 07:18 PM
<!DOCTYPE html>
<html lang="en-GB">
<head>
<meta charset="utf-8">
<meta name="keywords" content="key, words">
<meta name="description" content="description">
<title>Some Title</title>
<style type="text/css">
</style>
</head>
<body>
<input type="button" value="Add Row" onclick="addTableRow()">
<table id="tableid">
<tr><td>Hello</td><td>Hello</td><td>Hello</td><td>Hello</td></tr>
</table>
<script type="text/javascript">
var stdContent = "<td class='title'>xx:</td>\n" +
"<td><input type='text' placeholder='Giving' class='selector' name='givingxx' autocomplete='off'/></td>\n" +
"<td><input type='text' placeholder='Getting' class='selector' name='gettingxx' autocomplete='off'/></td>\n" +
"<td><input type='text' name='popupdatexx' id='popupdatexx' class='popupdate' value='When' /></td>\n";
var newno = 3;
function addTableRow() {
var newrow = document.createElement('tr');
// give your table an id..
var theTable = document.getElementById('tableid');

theTable.appendChild(newrow);
var newcontent = stdContent.replace('xx', newno);
newrow.innerHTML = newcontent;
newno++;
}

</script>
</body>
</html>

nick2price
09-24-2012, 10:36 PM
Brilliant, exactly what I was looking for. I have discovered a new problem though which hopefully you can advise on. This form is loaded through a link

<a href="#login-box" class="login-window">More</a>

What this does is call the following javascript


$(document).ready(function() {
$('a.login-window').click(function() {
//Getting the variable's value from a link
var loginBox = $(this).attr('href');
//Fade in the Popup
$(loginBox).fadeIn(300);
//Set the center alignment padding + border see css style
var popMargTop = ($(loginBox).height() + 24) / 2;
var popMargLeft = ($(loginBox).width() + 24) / 2;

$(loginBox).css({
'margin-top' : -popMargTop,
'margin-left' : -popMargLeft
});

// Add the mask to body
$('body').append('<div id="mask"></div>');
$('#mask').fadeIn(300);

return false;
});

// When clicking on the button close or the mask layer the popup closed
$('a.close, #mask').live('click', function() {
$('#mask , .login-popup').fadeOut(300 , function() {
$('#mask').remove();
});
return false;
});
});

Essentially, it darkens out the background and displays the table in the foreground, just like a modal display. The problem I am having relates to the new rows. When new rows are added, I cant scroll down to see them. If I use the browsers scrollbar, it scrolls my website, not the table. I would imagine this happens because the rows are added after the modal display is created, therefore the height becomes messed up. Is there any way to add a scrollbar or something to the table, or to get it to automatically update the modal display?

Cheers

AndrewGSW
09-24-2012, 11:17 PM
Without further information I assume you can just add the css-rule overflow:scroll or overflow:auto to the box: I'm assuming it has a fixed height. auto is probably preferable.

nick2price
09-25-2012, 12:04 AM
Think you are right. The css for the table is

.login-popup{
display:none;
padding: 10px;
float: left;
font-size: 1.2em;
position: fixed;
top: 50%; left: 50%;
z-index: 99999;
}


So the fixed position is causing the problem. Adding an overflow:auto or scroll doesnt seem to work, but I can probably come up with a solution by changing the position type.

nick2price
09-25-2012, 01:54 AM
Hey, one last quick thing. To remove rows, I added the following code

var rws;
function deleteTableRow(obj){
obj=document.getElementById(obj);
rws=obj.getElementsByTagName('tr');
obj.removeChild(rws[rws.length-1]);
}

It seems to work, does it look ok? For some reason, it only deletes the dynamically added rows, and wont delete the ones in the table from the beginning. This is fine, but I wouldnt mind knowing why this is the case though.

Cheers

VIPStephan
09-25-2012, 09:24 AM
Nick, I see that you are using jQuery. If you’re already loading such a lot of code then at least make full use of it. jQuery has a clone() (http://api.jquery.com/clone/) function to easily clone nodes (and modify them before reinserting them into the document). And also, it’s terribly easy to remove nodes.

css-quest
09-25-2012, 10:31 AM
This is just what I've been looking for! Thanks :-)

However (using AndrewGSW's latest code), does anyone know how to do the following:

1: Show 3 rows (with form fields) by default.
2: Only permit a maximum of 10 rows to be added.

AndrewGSW
09-26-2012, 07:35 PM
1. Just have three rows to start with.
2.


var tbl = document.getElementById('yourtableid');
if (tbl.rows.length < 10) {
// adjust the number 10 to account for any header row
// and perhaps the additional row containing the Add button
// code to add a new row here
}
You asked a third question by PM about having the Add button in a last row. In which case you need to use insertBefore to insert the new row(s) before this last one:


tbl.insertBefore(newrow, tbl.rows[tbl.rows.length-1]);

nick2price
09-26-2012, 07:50 PM
I realised that I needed to limit the amount of rows which could be added, but I done it slightly differently. I took the count variable and done


if(newno>20){
alert("Max row limit");
return;
}

It seems to work, is it ok doing this? (I have it in the addRow function).

Another question I have relates to automation. This may be slightly more difficult. As you can see, the last field in each row is a calander. What I would like to attempt is to have a row added automatically if the calander of the last row has a value. So, on the original table, the calandar in the fourth row will be trigger. If new rows are added, the new last row's calandar would become the new trigger. Is something like this possible?

Nick

AndrewGSW
09-26-2012, 08:05 PM
@nick2price. I was responding to css-quest's questions; but, yes, you can refer to newno as it is a global value - it's actually more efficient than counting the number of rows each time.

Presumably your calendar is a JS or jQuery plug-in. If you refer to its documentation then there will, presumably, be an event such as change or select that you can tap into to create the new row; that is, to call your existing function addTableRow().

css-quest
09-27-2012, 12:03 PM
Hi Andrew

Thanks for the script - I've tried your suggestion to limit the number of rows however it doesn't seem to be working?! My code is:


<input type="button" value="Add Row" onclick="addTableRow()">
<table id="mytable">
<tr><td>Hello</td><td>Hello</td><td>Hello</td><td>Hello</td></tr>
</table>
<script type="text/javascript">
var stdContent = "<td class='title'>xx:</td>\n" +
"<td><input type='text' placeholder='Giving' class='selector' name='givingxx' autocomplete='off'/></td>\n" +
"<td><input type='text' placeholder='Getting' class='selector' name='gettingxx' autocomplete='off'/></td>\n" +
"<td><input type='text' name='popupdatexx' id='popupdatexx' class='popupdate' value='When' /></td>\n";
var newno = 1;
var tbl = document.getElementById('mytable');
var tbl = tbl.rows.length < 10;
// adjust the number 10 to account for any header row
// and perhaps the additional row containing the Add button
// code to add a new row here


function addTableRow() {
var newrow = document.createElement('tr');
// give your table an id..
var theTable = document.getElementById('mytable');

theTable.appendChild(newrow);
var newcontent = stdContent.replace('xx', newno);
newrow.innerHTML = newcontent;
newno++;
}
}
</script>

Thanks in advance! :-)

nick2price
09-27-2012, 12:31 PM
Just do what I showed in my last post, and use newno to break out of the function. So in your addTableRow function, at the top place

if(newno>10){
alert("Max row limit");
return;
}

css-quest
09-27-2012, 04:17 PM
Thanks Nick - that did the trick quite nicely.

The one thing I'm struggling with is getting "<select>" drop-down boxes in one of the cells, I inserted the following:

<select name='itemA[]' style='width:100px;' class='selectbox'>

with appropriate <option></option> tags and </select> tag at the end. However, it doesn't seem to like name='itemA[]' style='width:100px;' class='selectbox' as when I press "Add Row" button, nothing happens!

Can anyone suggest why?

css-quest
10-01-2012, 11:56 AM
Bump.

AndrewGSW
10-01-2012, 01:59 PM
Bump.

This is confusing as you piggy-backed someone else's thread. I suggest you start a new thread (with an appropriate title) and post the relevant code and other details.

css-quest
10-10-2012, 10:54 AM
This is confusing as you piggy-backed someone else's thread. I suggest you start a new thread (with an appropriate title) and post the relevant code and other details.Thanks - I only posted within this thread as my issue might help others trying to do the same thing with the same script. However, I managed to resolve the issue myself. I will post a new thread for assistance on how to post the form field values.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum