Table Add More Row using javascript - javascript

I am adding dynamic row to table. But when adding new row, I want to replace some string on new row. But it is not working.
<table id="testTable">
<tr id="row_1">
<td>
<select onchange="changeCustomCategory(this.value,'1');" id="_cid" name="_cid[0]" >
<option value="">--Select Product--</option>
<option value="test">Test</option>
</select>
<input type="text" onchange="_doVariation(1);" value="1" id="_qty" name="_qty[0]"/>
<input type="text" class="textfield" value="0.00" id="item1_total" name="item1_total" readonly>
</td>
</tr>
</table>
<input type="hidden" value="1" id="total_row">
<input type="button" onclick="addRow()" value="Add Row">
This is my HTML code.
function addRow(){
var total_row = document.getElementById("total_row").value;
var _previousId = parseInt(total_row);
var new_id = parseInt(total_row) + 1;
document.getElementById("total_row").value = new_id;
var table = document.getElementById("testTable");
jQuery("#"+ table.rows[0].id).clone().appendTo("#testTable");
var totalTableRow = table.rows.length;
var currentRow = table.rows[totalTableRow-1];
currentRow.id = "row_"+new_id;
currentRow.innerHTML = currentRow.innerHTML.replace('_cid\['+ new_id-1 +'\]','_cid['+new_id+']');
currentRow.innerHTML = currentRow.innerHTML.replace(new RegExp("changeCustomCategory(this.value,'"+_previousId+"')","g"),'changeCustomCategory(this.value,'+new_id+')');
currentRow.innerHTML = currentRow.innerHTML.replace('_doVariation('+_previousId+')','_doVariation('+new_id+')');
}

You can perform your changes as the following:
//....
var newRow = jQuery("#"+ table.rows[0].id).clone().appendTo("#testTable");
//Change1
newRow.attr('name', '_cid['+new_id+']');
//Change2:
newRow.find('select').removeAttr('onchange').change(function() {
changeCustomCategory(this.value, new_id);
});
//Change3:
newRow.find('input:first').removeAttr('onchange').change(function() {
_doVariation(new_id);
});
//....
Demo: https://jsfiddle.net/4c0v2d50/

I would suggest sticking to jquery functions and not mixing too much with plain javascript. It makes it easier to code and follow.
I believe this is what your trying to do:
change HTML
id="_cid" name="_cid[0]"//change in select to
class="_cid" name="_cid[]"//_cid[] will automatically increment
id="_qty" name="_qty[0]"//same in input
class="_qty" name="_qty[]"
//you should also change
id="item1_total"
class="item1_total"
Javascript
function addRow(){
var new_id = $("#total_row").val() + 1;
$("#total_row").val(new_id);
var $currentRow = $("#testTable tr:first").clone();
$("#testTable").append(currentRow);
$currentRow.attr(id,"row_"+new_id);
$currentRow.find('select').attr('onclick',"changeCustomCategory(this.value,'"+new_id+"')");
$currentRow.find('._qty').attr('onchange','_doVariation('+new_id+')');
}

Removed the inline binding and bound to the element in the logic. Started changing the first thing you were trying to do with a regex. You can see how you like this approach.
jQuery(function($) {
//cache selectors
var $total_row = $("#total_row"),
$table = $("#testTable");
$(".addRow").on('click', function addRow() {
var total_row = $total_row.val(),
_previousId = parseInt(total_row),
new_id = _previousId + 1;
$total_row.val(new_id);
var $new_row = $table.find("tr").eq(0).clone();
$new_row.attr("id", "row_"+ new_id);
$new_row.find("select").attr("name", "_cid["+ (new_id - 1) +"]");
$table.append($new_row);
// currentRow.innerHTML = currentRow.innerHTML.replace('_cid\[' + new_id - 1 + '\]', '_cid[' + new_id + ']');
// currentRow.innerHTML = currentRow.innerHTML.replace(new RegExp("changeCustomCategory(this.value,'" + _previousId + "')", "g"), 'changeCustomCategory(this.value,' + new_id + ')');
// currentRow.innerHTML = currentRow.innerHTML.replace('_doVariation(' + _previousId + ')', '_doVariation(' + new_id + ')');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="testTable">
<tr id="row_1">
<td>
<select onchange="changeCustomCategory(this.value,'1');" id="_cid" name="_cid[0]">
<option value="">--Select Product--</option>
<option value="test">Test</option>
</select>
<input type="text" onchange="_doVariation(1);" value="1" id="_qty" name="_qty[0]" />
<input type="text" class="textfield" value="0.00" id="item1_total" name="item1_total" readonly>
</td>
</tr>
</table>
<input type="hidden" value="1" id="total_row">
<input type="button" value="Add Row" class="addRow">

function addRow(){
var total_row = parseInt(document.getElementById("total_row").value);
var _previousId = parseInt(total_row);
var new_id = parseInt(total_row) + 1;
var total_row = $("#total_row").val();
var _previousId = parseInt(total_row);
var new_id = parseInt(total_row) + 1;
$("#total_row").val(new_id);
var currentRow = $("#testTable tr:first").clone();
$("#testTable").append(currentRow);
$(currentRow).find('#_cid').attr("name","_cid["+new_id+"]");
$(currentRow).find('#_qty').attr("name","_qty["+new_id+"]");
$(currentRow).attr("id","row_"+new_id);
$(currentRow).find('#_cid').attr('onclick',"changeCustomCategory(this.value,'"+new_id+"')");
$(currentRow).find('#_qty').attr('onclick','_doVariation('+new_id+')');}

Working fiddle.
The id attribute should be unique so you could replace the duplicate ones by class attributen example :
<select class="_cid" name="_cid[0]" >
<input type="text" value="1" class="_qty" name="_qty[0]"/>
Better if you could avoid the inline-event onclick() and the overriding of parameters in every clone and define a general event one time and it will work for all the element, example :
$('body').on('change','._cid', function(){
//You code here
})
You don't need to increment the names you have just to leave the array signs empty [] and it will be incremented automatically, example :
<select class="_cid" name="_cid[]" >
<input type="text" value="1" class="_qty" name="_qty[]"/>
Hope this helps.
$(function(){
$('body').on('change','._cid', function(){
var id_number = $(this).parents('tr').attr('id').split('_')[1];
changeCustomCategory($(this).val(),id_number);
})
$('body').on('change','._qty', function(){
var id_number = $(this).parents('tr').attr('id').split('_')[1];
_doVariation(id_number);
})
})
function addRow()
{
var new_id = $('.row').length + 1;
var new_row = $("#testTable tr:first").clone().attr('id','row_'+new_id);
$("#testTable").append(new_row);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="testTable">
<tr id="row_1" class="row">
<td>
<select class="_cid" name="_cid[]" >
<option value="">--Select Product--</option>
<option value="test">Test</option>
</select>
<input type="text" value="1" class="_qty" name="_qty[]"/>
<input type="text" class="textfield" value="0.00" class="item1_total" name="item1_total" readonly>
</td>
</tr>
</table>
<input type="button" onclick="addRow()" value="Add Row">

Related

Save input data to table on same page? HTML and Javascript

I am brand new to JavaScript and HTML, and am trying to make a rehersal booking app which collects the info needed and displays it in a table on the same page.
I have been trying for hours on end to get it to work with various methods and I feel like it's just getting worse. I have probably made some silly mistakes but I cant seem to work out what I need to change to make it work.
Here is my HTML:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/html" xmlns="http://www.w3.org/1999/html">
<head>
<meta charset="UTF-8">
<title>White Noise Studios - Home</title>
<script type="text/javascript" src="Homepage.js"></script>
<style>
body, html
{
height: 100%;
background: url(Media/background.png);
background-size: cover;
}
</style>
</head>
<body>
<header style="color:white;font-family:'Calibri'">
<h1> Rehearsal Bookings</h1>
<p>Please let us know what gear you require in order for us to have the room ready for you. Leave the equipment section blank if you wish to bring your own gear. </p>
</header>
<form name="booking" id="booking">
<table style="color:white;font-family:'Yu Gothic UI Semibold'">
<tr>
<td><form action="Homepage.html"><input type="image" src="Media/homebutton.png"></form></td>
<td><form action="Homepage.html"><input type="submit" value="Book My Rehearsal"></form></td>
<td>Artist Name:</td><td><input type="text" name="Artist" size="50" id="Artist" /></td>
<td>Contact Number:</td><td><input type="text" name="Contact" size="50" id="Contact" /></td>
</tr>
<td>Equipment Needed:</td>
<td><label>Microphone</label>
<select id = "Microphone" name="Microphone">
<option value = "0">0</option>
<option value = "1">1</option>
<option value = "2">2</option>
<option value = "3">3</option>
</select></td>
<td><label>Guitars</label>
<select id = "Guitar" name="Guitar">
<option value = "0">0</option>
<option value = "1">1</option>
<option value = "2">2</option>
<option value = "3">3</option>
</select></td>
<td><label>Bass</label>
<select id = "Bass" name="Bass">
<option value = "0">0</option>
<option value = "1">1</option>
<option value = "2">2</option>
</select></td>
<td><label>Drums</label>
<select id = "Drums" name="Drums">
<option value = "0">None</option>
<option value = "1">Mapex Mars 5 Piece Full Kit</option>
<option value = "2">Ludwig LC17611 5 Piece Acoustic Kit</option>
<option value = "3">Roland TD 25KV V-Drums Kit</option>
</select></td>
<td><label>Amp</label>
<select id = "Amp" name="Amp">
<option value = "0">None</option>
<option value = "1">Marshall DSL100H</option>
<option value = "2">Marshall MG100GFX</option>
<option value = "3">Mesa Boogie triple Rectifier 100w</option>
</select></td> </tr>
<tr>
<td>Date:</td><td><input type="date" name="Date" id="Date" /></td>
</tr>
<tr>
<td>Time:</td><td><input type="time" name="Time" id="Time" /></td>
</tr>
</table>
</form>
<input type="submit" name="Book" value="Book my Rehearsal">
<button id="cancel" name="Cancel" onclick="myFunction()" value="Reset form">Cancel</button>
<hr/>
<div id="table">
</div>
<body>
<body style=”font-family:”arial black”; >
And my JavaScript:
var ArtistField, ContactField, MicrophoneSelect, GuitarSelect, BassSelect, DrumsSelect, AmpSelect, DateSelect, TimeSelect, BookSelect, CancelSelect;
var Booking = function (Artist, Contact, Microphone, Guitar, Bass, Drums, Amp, Date, Time ) {
this.Artist = Artist;
this.Contact = Contact;
this.Microphone = Microphone;
this.Guitar = Guitar;
this.Bass = Bass;
this.Drums = Drums;
this.Amp = Amp;
this.Date = new Date ;
this.Time = Time;
};
function myFunction() {
document.getElementById("booking").reset();
}
var Bookings = []
Booking.prototype.tableRow = function(){
var tr = "<tr><td>" + this.Artist + "</td><td>" +
this.Contact + "</td><td>" + this.Microphone +
"<tr><td>" + this.Guitar + "<tr><td>" + this.Bass + "<tr><td>" + this.Drums + "<tr><td>" + this.Amp +"<tr><td>"
+ this.getDate() + "</td><td>" + this.Time+ "</td><td>" + "</td></tr> ";
return tr;
};
Booking.prototype.getDate = function(){
return this.Date.toDateString();
};
var clickBook = function() {
addbooking(ArtistField, ContactField, MicrophoneSelect, GuitarSelect, BassSelect, DrumsSelect, AmpSelect, DateSelect, TimeSelect,);
showTable();
};
var showTable = function(){
var tableDiv = document.getElementById("table"), table = "<table border='1'>" +
"<thead><th>Artist</th><th>Contact</th><th>Microphone</th><th>Guitar</th><th>Bass</th><th>Drums</th><th>Amp</th</thead>";
for(var i=0, j=Bookings.length; i<j; i++){
var appt = Bookings[i];
table += appt.tableRow();
}
table+="</table>";
tableDiv.innerHTML = table;
};
window.onload = function(){
ArtistField = document.getElementById("Artist");
ContactField = document.getElementById("Contact");
MicrophoneSelect = document.getElementById("Microphone");
GuitarSelect = document.getElementById("Guitar");
BassSelect = document.getElementById("Bass");
DrumsSelect = document.getElementById("Drums");
AmpSelect = document.getElementById("Amp");
DateSelect = document.getElementById("Date");
TimeSelect = document.getElementById("Time");
//var roleChoice = roleField.options[roleField.selectedIndex].text;
Book = document.getElementById("Book");
Book.onclick = clickBook();
showTable();
};

How to remove dynamically generated fields from div level?

My concept is to create maximum 20 blocks( it contains some input field) on button click "Add", If you tap on "Add" button then new block could be added, that was successfully done. Now i want to remove the block which is created on "Add" button click.
Eg: If user is create 5 block by using in "ADD" button. If user taps on "Minus" button, in Block 2, then Block 2 should be removed from the list and count of the block should be updated correspondingly.
http://www.w3schools.com/code/tryit.asp?filename=FADO51NINJMD
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
var i = 1;
$(document).ready(function () {
$("#commentForm").validate();
});
function add()
{
var objTo = document.getElementById('room_fileds')
var divtest = document.createElement("div");
var label = document.createElement('label');
label.innerHTML = '<h5 class="label">Block '+i+'<input type="button" value="Minus" onclick="minus()"></h5>';
divtest.appendChild(label);
var length = $('#Length').clone().attr('id', 'Length' + i).attr('name', 'Length' + i);
var attribute = $('#Attribute').clone().attr('id', 'Attribute' + i).attr('name', 'Attribute' + i);
var column = $('#Column').clone().attr('id', 'Column' + i).attr('name', 'Column' + i);
length.appendTo(divtest);
attribute.appendTo(divtest);
column.appendTo(divtest);
objTo.appendChild(divtest);
i++
}
function minus()
{
}
</script>
</head>
<body>
<form id="commentForm" method="post" action="">
<div id="room_fileds">
Static Field
<input type="text" name="Length" maxlength="2" id="Length" onkeypress="return isNumberKey(event);" placeholder="Field 1 Length" class="form-control required">
<input type="text" name="Attribute" id="Attribute" placeholder="Field 1 Attribute" class="form-control" required>
<select name="Column" id="Column" class="required" >
<option selected value="">Field Column </option>
<option value="1">YES</option>
<option value="2">NO</option>
</select>
</div>
<br><br>
<input class="submit" type="submit" value="Submit1">
<input type="button" value="Add" onclick="add()">
</form>
</body>
</html>
Set id while creating div node
divtest.setAttribute("id", "div" + i);
For minus function pass created id number in onclick
label.innerHTML = '<h5 class="label">Block '+i+'<input type="button" onclick="minus('+i+')" value="Minus"></h5>';
And set minus function as
function minus(_id)
{
var _div_id = "div" + _id;
var _div_elem = document.getElementById(_div_id);
_div_elem.parentNode.removeChild(_div_elem);
}
var i = 1;
$(document).ready(function () {
//$("#commentForm").validate();
});
function add()
{
var objTo = document.getElementById('room_fileds')
var divtest = document.createElement("div");
divtest.setAttribute("id","div" + i);
var label = document.createElement('label');
label.innerHTML = '<h5 class="label">Block '+i+'<input type="button" onclick="minus('+i+')" value="Minus"></h5>';
divtest.appendChild(label);
var length = $('#Length').clone().attr('id', 'Length' + i).attr('name', 'Length' + i);
var attribute = $('#Attribute').clone().attr('id', 'Attribute' + i).attr('name', 'Attribute' + i);
var column = $('#Column').clone().attr('id', 'Column' + i).attr('name', 'Column' + i);
length.appendTo(divtest);
attribute.appendTo(divtest);
column.appendTo(divtest);
objTo.appendChild(divtest);
i++
}
function minus(_id)
{
var _div_id = "div" + _id;
var _div_elem = document.getElementById(_div_id);
_div_elem.parentNode.removeChild(_div_elem);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<form id="commentForm" method="post" action="">
<div id="room_fileds">Static Field
<input type="text" name="Length" maxlength="2" id="Length" onkeypress="return isNumberKey(event);" placeholder="Field 1 Length" class="form-control required">
<input type="text" name="Attribute" id="Attribute" placeholder="Field 1 Attribute" class="form-control" required>
<select name="Column" id="Column" class="required" >
<option selected value="">Field Column </option>
<option value="1">YES</option>
<option value="2">NO</option>
</select>
</div><br><br>
<input class="submit" type="submit" value="Submit1">
<input type="button" value="Add" onclick="add()">
</form>
You can just remove the label parent on click. See the minus function content.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
var i = 1;
$(document).ready(function () {
$("#commentForm").validate();
});
function add()
{
var objTo = document.getElementById('room_fileds')
var divtest = document.createElement("div");
var label = document.createElement('label');
label.innerHTML = '<h5 class="label">Block '+i+'<input type="button" value="Minus" onclick="minus()"></h5>';
divtest.appendChild(label);
var length = $('#Length').clone().attr('id', 'Length' + i).attr('name', 'Length' + i);
var attribute = $('#Attribute').clone().attr('id', 'Attribute' + i).attr('name', 'Attribute' + i);
var column = $('#Column').clone().attr('id', 'Column' + i).attr('name', 'Column' + i);
length.appendTo(divtest);
attribute.appendTo(divtest);
column.appendTo(divtest);
objTo.appendChild(divtest);
i++
}
function minus()
{
//This is the clicked label, so we remove the parent (the div)
$(this).parent().remove();
}
</script>
</head>
<body>
<form id="commentForm" method="post" action="">
<div id="room_fileds">
Static Field
<input type="text" name="Length" maxlength="2" id="Length" onkeypress="return isNumberKey(event);" placeholder="Field 1 Length" class="form-control required">
<input type="text" name="Attribute" id="Attribute" placeholder="Field 1 Attribute" class="form-control" required>
<select name="Column" id="Column" class="required" >
<option selected value="">Field Column </option>
<option value="1">YES</option>
<option value="2">NO</option>
</select>
</div>
<br><br>
<input class="submit" type="submit" value="Submit1">
<input type="button" value="Add" onclick="add()">
</form>
</body>
</html>
<div class="removePhoneDiv">
<input type="button" value="Add Text Field" id="add_button" >
<ul style="list-style:none;" id="phoneNumberList">
<li class='Textbox1' style="float:left;width:100%;">
<div style=" margin-top: 2%; " class='form-group' id='answerdiv'>
<input type='text' class='input_phone form-control1'>
<img style="float:left;" src="images/close.png" class="remove_phone_number">
</div>
</li>
</ul>
</div>
<script>
var wrapper = $(".form-group");
$("#add_button").click(function (e) {
e.preventDefault();
$("#phoneNumberList").append("<li class='Textbox1'><div class='form-group' id='answerdiv'><input type='text' class='form-control1' ><img src=\"images/close.png\" class=\"remove_phone_number\"></div></li>");
});
$(".removePhoneDiv").on("click", ".remove_phone_number", function (e) {
e.preventDefault();
$(this).parent('div').parent('li').remove();
})
</script>

Issue Cloning Form Fields Within Table with Javascript

In the code below it works great to clone the table, but it doesn't go deep enough to rename the inputs of each form field in the table. For example Attendee1, Attendee2, Attendee3 etc.
Is there a way instead of just grabbing NewEl.children a way to just find all the input elements within the table then rename them?
I am not trying to add a row, I need to clone the entire table.
Any help you all out there in cyberland can give will be greatly appreciated.
<form name="EditRoster" method="post" action="DoRoster.php">
<table id="RosterTbl" cellspacing="0" cellpadding="2">
<tr style="text-align:left;vertical-align:top;">
<td><b>Name</b>:</td>
<td>
<input type="text" name="Attendee" value="" size="25" onclick="alert(this.name)">
</td>
<td><b>Paid</b>:</td>
<td>
<input type="checkbox" name="Paid" value="Yes" size="25">
</td>
</tr>
<tr style="text-align:left;vertical-align:top;">
<td><b>Email</b>:</td>
<td>
<input type="text" name="Email" value="" size="25">
</td>
<td><b>Paid When</b>:</td>
<td>
<input type="text" name="PaidWhen" value="" size="10">
</td>
</tr>
</table>
<div style="padding:5px;">
<input type="hidden" name="NumStudents" value="0">
<input type="button" name="AddPersonButton" value="Add Person" onclick="CloneElement('RosterTbl','NumStudents');">
</div>
</form>
<script language="javascript">
var TheForm = document.forms.EditRoster;
function CloneElement(ElToCloneId, CounterEl) {
var CloneCount = TheForm[CounterEl].value;
CloneCount++;
TheForm[CounterEl].value = CloneCount;
var ElToClone = document.getElementById(ElToCloneId);
var NewEl = ElToClone.cloneNode(true);
NewEl.id = ElToCloneId + CloneCount;
NewEl.style.display = "block";
var NewField = NewEl.children;
for (var i = 0; i < NewField.length; i++) {
var InputName = NewField[i].name;
if (InputName) {
NewField[i].name = InputName + CloneCount;
}
var insertHere = document.getElementById(ElToCloneId);
insertHere.parentNode.insertBefore(NewEl, insertHere);
}
}
</script>
Looked like you were on the right track, but I think you were taking a few extra steps, so I think I simplified it ;)
One thing you were missing was that the value of NumStudents is returned as a string so you have to call parseInt() on it.
var theForm = document.forms.EditRoster;
function insertAfter(referenceNode, newNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function CloneElement(cloneID, counterName) {
var clone = document.getElementById(cloneID);
var newClone = clone.cloneNode(true);
var counter = theForm[counterName].value = parseInt(theForm[counterName].value) + 1;
// Update the form ID
newClone.id = newClone.id + counter;
// Update the child Names
var items = newClone.getElementsByTagName("*");
for (var i = 0; i < items.length; i++) {
if (items[i].name != null)
items[i].name = items[i].name + counter;
}
insertAfter(clone, newClone);
}
Here's a working copy on jsFiddle.
P.s. I wasn't sure if you wanted the new fields clearing so I left them.

Autosum with generated fields JS

I'm a bit stuck with javascript again. Basically when you click a button a new row of fields will appear, giving them a new name just a different number.
I now need these fields to be able to auto sum by themself, i can do this with the first row I just don't know how to do them with the new generated ones.
The Javascript code:
<script language="javascript" type="text/javascript">
var i=2;
function addRow()
{
var tbl = document.getElementById('customersAdd');
var lastRow = tbl.rows.length;
var iteration = lastRow - 1;
var row = tbl.insertRow(lastRow);
var firstCell = row.insertCell(0);
var el = document.createElement('input');
el.placeholder = 'Quantity';
el.type = 'text';
el.name = 'quantity' + i;
el.id = 'quantity' + i;
firstCell.appendChild(el);
var secondCell = row.insertCell(1);
var el2 = document.createElement('input');
el2.placeholder = 'Description';
el2.type = 'text';
el2.name = 'description' + i;
el2.id = 'description' + i;
secondCell.appendChild(el2);
var thirdCell = row.insertCell(2);
var el3 = document.createElement('input');
el3.placeholder = 'Rate';
el3.type = 'text';
el3.name = 'rate' + i;
el3.id = 'rate' + i;
thirdCell.appendChild(el3);
var forthCell = row.insertCell(3);
var el4 = document.createElement('input');
el4.placeholder = 'Amount';
el4.type = 'text';
el4.name = 'amount' + i;
el4.id = 'amount' + i;
forthCell.appendChild(el4);
// alert(i);
i++;
// alert(i);
}
function startCalc(){
interval = setInterval("calc()",1);
}
function calc(){
one = document.main.quantity1.value;
two = document.main.rate1.value;
document.main.amount1.value = (one * 1) * (two * 1);
}
function stopCalc(){
clearInterval(interval);
}
</script>
The HTML code:
<form action="submit.php" name="main" method="post">
<table style="border-collapse: collapse;" border="0" align="center" width="50%" class="horiz" id="customersAdd">
<tr>
<td align="center"><br/>
<input class="text" style="width:100%" type="button" align="middle"value="Add Aditional Row" onClick="addRow()" /></td>
</tr>
<tr align="center">
<td>
<br />
<input placeholder="Quantity" type="text" name="quantity1" id="quantity1" onFocus="startCalc();" onBlur="stopCalc();" />
<br /></td>
<td>
<br />
<input placeholder="Description" type="text" name="description1" id="description1"/>
<br /></td>
<td>
<br />
<input placeholder="Rate" type="text" name="rate1" id="rate1" onFocus="startCalc();" onBlur="stopCalc();"/>
<br /></td>
<td>
<br />
<input placeholder="Amount" type="text" name="amount1" id="amount1" onBlur="stopCalc();" onFocus="startCalc();" readonly="true" />
<br /></td>
</tr>
</table></form>
To make things easier for anyone who could help me I have made this in JSBin to see it easier of what i want to do. Any suggestions are appreciated.
http://jsbin.com/atabaz/1/edit
Thanks
In the end I managed to find a way on how to do this myself, if anyone is interested take a look at this:
http://jsfiddle.net/2sYgE/
var currentItem = 1;
$('#customersAdd').on('keyup', '.quantity, .rate, .amount', calculateRow);
$('#addnew').click(function() {
currentItem++;
$('#customersAdd').append('<tr><td><input placeholder="Quantity" type="text" name="quantity' + currentItem +'" id="quantity' + currentItem +'" class="qty form-input-rate" /></td><td><input placeholder="Description" type="text" name="description' + currentItem +'" id="description' + currentItem +'" class="form-input-rate"/></td><td><input placeholder="Rate" type="text" name="rate' + currentItem +'" id="rate' + currentItem +'" class="rate form-input-rate"/></td><td><input placeholder="Amount" type="text" name="amount' + currentItem +'" id="amount' + currentItem +'" class="cal form-input-rate"/></td></tr>'
);
});
function calculateSum() {
var sum = 0;
$(".cal").each(function () {
if (!isNaN(this.value) && this.value.length != 0) {
sum += parseFloat(this.value);
}
});
}
function calculateRow() {
var cost = 0;
var $row = $(this).closest("tr");
var qty = parseFloat($row.find('.qty').val());
// changed the following line to only look within the current row
var rate = parseFloat($row.find('.rate').val());
cost = qty * rate;
if (isNaN(cost)) {
$row.find('.cal').val("0");
} else {
$row.find('.cal').val(cost);
}
calculateSum();
}
Polling for changes is a very inefficient and error–prone way to do form updates. Listening for change events is a better way to go as it uses fewer resources and waits until the user has finished updating the control before doing anything. There is also an input event that can be used, but it's not suitable here as it will update the form as the user enters values. Much better to wait for the user to finish entering values, then do the update.
I've re–factored your code below, it's not ready for production but it should give you some idea of how to go about it. Table rows are cloned as it's much faster than creating all the elements from scratch. Then names are modified, though this isn't really necessary. There is no need for ID attributes.
Cloning only works reliably here if inline listeners are used on the form controls. If the initial listeners are dynamically attached, you'll have to add them each time a row is added as listeners added using addEventListener are not cloned.
I haven't included any input validation, if the user puts in junk, they get junk back. You should validate input to check that appropriate values are being entered, and also format the displayed values for presentation.
<script type="text/javascript">
function addRow(element) {
var form = element.form;
var table = form.getElementsByTagName('table')[0];
var tbody = table.tBodies[0];
var num = tbody.rows.length - 1;
var row = table.rows[1].cloneNode(true);
var input, inputs = row.getElementsByTagName('input')
// Update input names
for (var i=0, iLen=inputs.length; i<iLen; i++) {
input = inputs[i];
input.name = input.name.replace(/\d+$/,num);
input.value = '';
}
tbody.insertBefore(row, tbody.rows[tbody.rows.length - 1]);
}
function updateRow(element) {
var form = element.form;
var num = element.name.replace(/^\D+/,'');
var value = form['quantity' + num].value * form['rate' + num].value;
form['amount' + num].value = (value == 0)? '' : value;
updateTotal(form);
}
function updateTotal(form) {
var elements = form.elements;
var name = /^amount/;
var total = 0;
var value;
for (var i=0, iLen=elements.length; i<iLen; i++) {
if (name.test(elements[i].name)) {
total += parseFloat(elements[i].value);
}
}
form.total.value = total;
}
</script>
<form action="submit.php" name="main" method="post">
<table style="border-collapse: collapse;" border="0" align="center"
width="50%" class="horiz" id="customersAdd">
<tr>
<td><br>
<input class="text" style="width:100%" type="button"
align="middle"value="Add Aditional Row" onclick="addRow(this)">
</td>
</tr>
<tr>
<td>
<input placeholder="Quantity" name="quantity1" onblur="updateRow(this);">
</td>
<td>
<input placeholder="Description" type="text" name="description1">
</td>
<td>
<input placeholder="Rate" name="rate1" onchange="updateRow(this);">
</td>
<td>
<input placeholder="Amount" name="amount1" readonly>
</td>
</tr>
<tr>
<td colspan="3" style="text-align: right">Total
<td><input name="total" readonly>
</tr>
</table>
<input type="reset">
</form>

JavaScript Renaming Form Image Input Name

I am developing this for use in Internet Explorer 8 (because at work we have to use it). I have a page that has a table withing a form. The table has a button to "clone" rows, "AddScheduleRow()". That part works good. Each row has a button to delete that row "DeleteRow(r)". That part works well too. I also have a script to rename/renumber each row, "RenumberRows()". It almost works good. I can rename the text fields (for example what was previously StartDate3 now becomes StartDate2). However, in each row is an input that is type="image" and it is named like you should with any input. The name of it is "StartDateCal". The problem is that during the renaming process, when it hits the image input (TheForm.StartDateCal[i].name = "StartDateCal" + TempCounter;), I get a JavaScript error "'TheForm.StartDateCal' is null or not an object". I cannot figure this one out and it's standing in the way of moving on.
What can I do to try to rename an < input type = image /> ?
Below is the necessary code:
HTML
<html>
<head>
</head>
<body>
<form name="UpdateSchedule" method="post" action="DoSchedule.asp">
<input type="hidden" name="NumRows" value="0">
<input type="hidden" name="RowsAdded" value="0">
<table id="ClassScheduleTable">
<tr id="ScheduleRow" style="display:none;">
<td>
<input type="text" name="RowNum" value="0" size="1" onclick="alert(this.name)">
</td>
<td>
<b>Start Date</b> <input type="text" name="StartDate" value="" onclick="alert(this.name);" size="8">
<input type="image" name="StartDateCal" src="http://www.CumminsNorthwest.com/ATT/Img/Calendar3.png" style="border-style:none;" onClick="alert('name = ' + this.name);return false;">
</td>
<td>
<input type="button" value="Del." name="DelRow" class="subbuttonb" onclick="DeleteRow(this);">
</td>
</tr>
<tr>
<td colspan="3" style="text-align:right">
<input type="button" value="Add Class Date" class="SubButton" onclick="AddScheduleRow();">
</td>
</tr>
</table>
</form>
</body>
<script language="JavaScript">
JS
var TheForm = document.forms.UpdateSchedule;
var NumRows =0;
var RowsAdded =0;
function AddScheduleRow(){
NumRows++;
TheForm.NumRows.value = NumRows;
RowsAdded++;
TheForm.RowsAdded.value = RowsAdded;
var TableRowId = "ScheduleRow";
var RowToClone = document.getElementById(TableRowId);
var NewTableRow = RowToClone.cloneNode(true);
NewTableRow.id = TableRowId + NumRows ;
NewTableRow.style.display = "table-row";
var NewField = NewTableRow.children;
for (var i=0;i<NewField.length;i++){
var TheInputFields = NewField[i].children;
for (var x=0;x<TheInputFields.length;x++){
var InputName = TheInputFields[x].name;
if (InputName){
TheInputFields[x].name = InputName + NumRows;
//alert(TheInputFields[x].name);
}
var InputId = TheInputFields[x].id;
if (InputId){
TheInputFields[x].id = InputId + NumRows;
//alert(TheInputFields[x].id);
}
}
}
var insertHere = document.getElementById(TableRowId);
insertHere.parentNode.insertBefore(NewTableRow,insertHere);
RenumberRows();
}
AddScheduleRow();
function DeleteRow(r){
var i=r.parentNode.parentNode.rowIndex;
document.getElementById("ClassScheduleTable").deleteRow(i);
NumRows--;
TheForm.NumRows.value = NumRows;
RenumberRows();
}
function RenumberRows(){
var TempCounter = 0;
for (var i=0;i<=RowsAdded;i++){
if (TheForm.RowNum[i]){
TempCounter++;
TheForm.RowNum[i].name = "RowNum" + TempCounter;
TheForm.RowNum[i].value = TempCounter;
TheForm.StartDate[i].name = "StartDate" + TempCounter;
TheForm.StartDateCal[i].name = "StartDateCal" + TempCounter;
}
}
}
</script>
</html>
might be to do with your DTD,
try HTML4 Strict:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
You can use
document.getElementsByName('StartDateCal')[i].name = "StartDateCal" + TempCounter;
instead of
TheForm.StartDateCal[i].name = "StartDateCal" + TempCounter;

Categories