Javascript appendChild(td) works one place, not another - javascript

Consider this HTML (part of a table in a form):
<tr id="EnterForRow">
<td>Entered for</td>
<td><input type="radio" name="enterfor" value "0" checked>Myself
<input type="radio" name="enterfor" value "1">Someone Else </td>
</tr>
<tr id="PrayerForRow">
<td>Prayer for </td>
<td> <input type="radio" name="prayerfor" value="0" checked>Myself
<input type="radio" name="prayerfor" value="1">Someone Else </td>
</tr>
When users click Someone Else, I have Javascript to make a new text input box appear on the row. The Javascript for PrayerForRow works but the Javascript for EnterForRow does not work. I can't see any obvious differences. I think I have been staring at it too long..
This works:
var prayforRad = document.getElementsByName('prayerfor');
for(var i = 0; i < prayforRad.length; i++)
{
prayforRad[i].onclick = function()
{
var theValue = radioValue(document.getElementsByName('prayerfor'));
if (theValue == "1")
{
if (!document.getElementById("pfor"))
{
var newTd = document.createElement("td");
newTd.setAttribute("id", "pfor");
var pforRow = document.getElementById("PrayerForRow");
pforRow.appendChild(newTd);
newTd.innerHTML = '<td>For: <input type="text" name="PrayFor" id="PrayFor" size="25"></td>';
}
}
else
{
if (document.getElementById("pfor"))
{
var pforRow = document.getElementById("PrayerForRow");
var pf = document.getElementById("pfor");
pforRow.removeChild(pf);
}
}
}
}
This does not:
var enterforRad = document.getElementsByName('enterfor');
for(var j = 0; j < enterforRad.length; j++)
{
enterforRad[j].onclick = function()
{
var theValue2 = radioValue(document.getElementsByName('enterfor'));
if (theValue2 == "1")
{
if (!document.getElementById("efor"))
{
var newTD2 = document.createElement("td");
newTD2.setAttribute("id", "efor");
var eforRow = document.getElementById("EnterForRow");
eforRow.appendChild(newTD2);
newTD2.innerHTML = '<td>For: <input type="text" name="EntFor" id="EntFor" size="25"></td>';
}
}
else
{
if (document.getElementById("efor"))
{
var eforRow = document.getElementById("EnterForRow");
var ef = document.getElementById("efor");
eforRow.removeChild(ef);
}
}
}
}
Any pointers are appreciated.

<td><input type="radio" name="enterfor" value "0" checked>Myself
<input type="radio" name="enterfor" value "1">Someone Else </td>
i think you have lost two "="

As I suggested in the comment, it is better to hide/display an existing element than creating those optional elements based on the condition like
<tr id="EnterForRow">
<td>Entered for</td>
<td>
<input type="radio" name="enterfor" value="0" checked />Myself
<input type="radio" name="enterfor" value="1" />Someone Else
</td>
<td id="efor" style="display: none">For:
<input type="text" name="EntFor" id="EntFor" size="25" />
</td>
</tr>
<tr id="PrayerForRow">
<td>Prayer for</td>
<td>
<input type="radio" name="prayerfor" value="0" checked />Myself
<input type="radio" name="prayerfor" value="1" />Someone Else
</td>
<td id="pfor" style="display: none">For:
<input type="text" name="PrayFor" id="PrayFor" size="25" />
</td>
</tr>
then
var prayforRad = document.getElementsByName('prayerfor');
for (var i = 0; i < prayforRad.length; i++) {
prayforRad[i].onclick = function () {
var theValue = radioValue(document.getElementsByName('prayerfor'));
var pf = document.getElementById("pfor");
pf.style.display = theValue == '1' ? '' : 'none'
}
}
var enterforRad = document.getElementsByName('enterfor');
for (var j = 0; j < enterforRad.length; j++) {
enterforRad[j].onclick = function () {
var theValue2 = radioValue(document.getElementsByName('enterfor'));
var ef = document.getElementById("efor");
ef.style.display = theValue2 == '1' ? '' : 'none'
}
}
Demo: Fiddle
Also I would recommend using addEventListener() to add the listener instead of using onclick property

Related

Looping through and storing each table row td element value as array of objects

I have a table that dynamically calculates and create new row. Here is a snippet of the:
<table>
<tr class="purchase_schedule_table">
<td><input type="text" name="purchase_place" class="purchase_place_info" style="width: 90%;" ></td>
<td><input type="text" name="main_products_purch" style="width: 90%;" class="main_products_purch_info" ></td>
<td><input type="number" name="frequency" style="width: 90%;" class="frequency" ></td>
<td><input type="number" name="low" style="width: 90%;" class="product_low" ></td>
<td><input type="number" name="high" style="width: 90%;" class="product_high" ></td>
<td><input type="number" name="average" style="width: 90%;" class="product_average" disabled ></td>
<td>
<div class = "input-group" id="addrow">
<input type="number" name="product_total" style="width: 90%;" class="product_total" disabled>
<span class = "input-group-addon" style="width:1%; background-color:#786bae;border-color:#786bae;">
<a href="#">
<span style="color:#FFFFFF;font-size:9px;line-height: 1.5;border-radius:0 !important;" class="glyphicon glyphicon-plus addrow" aria-hidden="true"></span>
</a>
</span>
</div>
</td>
</tr>
</table>
Here is a snippet of jquery code to calculate the values:
//calculate purchase schedule monthly total
function calculatePurchaseScheduleMonthlyTotal(){
var total_sum = 0;
$('.product_total').each(function () {
var value = $(this).val();
total_sum = parseInt(total_sum) + parseInt(value);
});
$('.total_sum').val(total_sum);
};
//calculate purchase schedule
function calculatePurchaseSchedule(ObjRow) {
var low = 0;
var high = 0;
var average = 0;
var frequency = 0;
var total = 0;
var total_sum = 0;
frequency = ($(ObjRow).find('.frequency').val() == "") ? 0 : $(ObjRow).find('.frequency').val();
high = ($(ObjRow).find('.product_high').val() == "") ? 0 : $(ObjRow).find('.product_high').val();
low = ($(ObjRow).find('.product_low').val() == "") ? 0 : $(ObjRow).find('.product_low').val();
average = (parseInt(high) + parseInt(low)) / 2;
total = average * frequency;
$(ObjRow).find('.product_total').val(total);
$(ObjRow).find('.product_average').val(average);
calculatePurchaseScheduleMonthlyTotal();
};
Here is also a snippet of the code that is use to trigger the calculation:
$(document).on('focusout','input[type=number]',function () {
calculatePurchaseSchedule($(this).closest('tr'));
saveData();
});
Here is the code for adding a table row dynamically:
$('#addrow').click(function (e) {
e.preventDefault();
var purchase_schedule_row = '<tr class="purchase_schedule_table"><td> <input type="text" name="purchase_place" class="purchase_place" style="width: 90%;"></td><td><input type="text" name="main_products_purch" style="width: 90%;" class="main_products_purch"></td><td><input type="number" name="frequency" style="width: 90%;" class="frequency"></td><td><input type="number" name="low" style="width: 90%;" class="product_low"></td> <td><input type="number" name="high" style="width: 90%;" class="product_high"></td> <td><input type="number" name="average" style="width: 90%;" class="product_average" disabled></td><td> <div class = "input-group" id="addrow"> <input type="number" name="total" style="width: 90%;" class="product_total" disabled><span class = "input-group-addon" style="width:1%; background-color:#ec6d65;border-color:#ec6d65;"> <span style="color:#FFFFFF;font-size:9px;line-height: 1.5;border-radius:0 !important;" class="glyphicon glyphicon-minus deleterow" aria-hidden="true"></span></span></div></td></tr>';
$('#purchaseScheduleTable').append(purchase_schedule_row);
});
What I want to do is to store each table row td element value as a array of objects. I have tried doing so in the following code:
var purchase_place;
var main_products_purch;
var frequency;
var product_low;
var product_high;
var product_average;
var product_total;
var product_total_sum;
var purchase_schedule_table = [];
var purchase_schedule_data = {};
var count = 1;
$('.purchase_schedule_table').each(function(){
$(this).find('.product_total').each(function () {
product_total = $(this).find('.product_total').val();
console.log(product_total);
purchase_schedule_data.product_total = product_total;
});
purchase_schedule_table.push(purchase_schedule_data);
});
console.log(purchase_schedule_table);
For example, the end result should be like this:
[
{purchase_place: 'purchase_place', main_products_purch : 'main_products_purch', frequency:'frequency', product_average: 'product_averager'}
{purchase_place: 'purchase_place', main_products_purch : 'main_products_purch', frequency:'frequency', product_average: 'product_averager'}
]
What am I doing wrong? Thanks in advance.
Iterate through each tr with class purchase_schedule_table and then each td in it, make an object and push it in a an array like following.
var arr = [];
$('.purchase_schedule_table').each(function () {
var obj = {};
$(this).find('td').each(function () {
var input = $(this).find('input')[0];
obj[input.name] = input.value;
});
arr.push(obj);
})
console.log(arr)

implementing quantity to update price of product and total price

i am creating a checkout page where users can purchase goods. i have managed to give each product its price but what I cant do is give them its quantity. i simply do no know how to do it. i created a quantity box for them but i can link the two.
my goal is to update the quantity and total price should be displayed on the checkout form.
since this is my homework for college, this must be done in strictly javascript if a solution arrives.
<script type="text/javascript">
function total(frm) {
var tot = 0;
for (var i = 0; i < frm.elements.length; i++) {
if (frm.elements[i].type == "checkbox") {
if (frm.elements[i].checked) tot += Number(frm.elements[i].value);
}
}
document.getElementById("totalDiv").firstChild.data = "£" + tot;
type = "text/javascript" > total(document.getElementById("theForm"));
}
</script>
<form action="nextpage" method="post" id="theForm">
<fieldset>
<legend>Choose your Products</legend>
<table style="padding:2px">
<tr>
<td>
<img src="http://placehold.it/200x200" />
</td>
<td>
<img src="http://placehold.it/200x200" />
</td>
<td>
<img src="http://placehold.it/200x200" />
</td>
<td>
<img src="http://placehold.it/200x200" />
</td>
</tr>
<tr>
<td class="buttons">
<div>
<input type="checkbox" name="r" value="25" onclick="total(this.form);" />£25</div>
<input min="0" max="5" type="number" class="quantity" name="quantity" value="1" />
</td>
<td class="buttons">
<div>
<input type="checkbox" name="7" value="50" onclick="total(this.form);" />£50</div>
<input min="0" max="5" type="number" class="quantity" name="quantity" value="1" />
</td>
<td class="buttons">
<div>
<input type="checkbox" name="asd7" value="75" onclick="total(this.form);" />£75</div>
<input min="0" max="5" type="number" class="quantity" name="quantity" value="1" />
</td>
<td class="buttons">
<div>
<input type="checkbox" name="rasd7" value="100" onclick="total(this.form);" />£100</div>
<input min="0" max="5" type="number" class="quantity" name="quantity" value="1" />
</td>
</tr>
</table>
<div id="totalDiv">£0</div>
<div>
<input type="submit" value="Place Order" />
</div>
</fieldset>
</form>
http://jsfiddle.net/isherwood/96qkr/
Simple and fast solution
Well the simplest solution would be:
Number(frm.elements[i].value) * Number(frm.elements[i+1].value);
Since the quantity element always comes AFTER the checkbox element.
The JavaScript then becomes:
function total(frm)
{
var tot = 0;
for (var i = 0; i < frm.elements.length; i++) {
if (frm.elements[i].type == "checkbox") {
if (frm.elements[i].checked) tot +=
Number(frm.elements[i].value) * Number(frm.elements[i+1].value);
}
}
document.getElementById("totalDiv").firstChild.data = "£" + tot;
}
You can see this works here.
To guarantee that the total div also gets updated when quantity is changed, you should add the onclick="total(this.form);" event to the class="quantity" input elements as well.
You can see how nicely this works here.
More advanced solution
Personally, I would use tabIndex to group the checkbox and quality inputs.
For example, for the first product:
<td class="buttons">
<div>
<input tabindex="1" name="checkbox" type="checkbox" value="25" onclick="total(this.form);" />£25</div>
<input tabindex="1" name="quantity" min="0" max="5" type="number" class="quantity" value="1" onclick="total(this.form);"/>
</td>
As you can see, I have explicitly defined the tabIndex and names.
Now for the JavaScript, I now use:
function total(frm)
{
var tot = 0;
var checkboxes = document.forms[frm.id].elements["checkbox"];
var quants = document.forms[frm.id].elements["quantity"];
for (var i = 0; i < checkboxes.length; i++)
{
if (checkboxes[i].checked)
{
// if tabIndex correctly specified
if (checkboxes[i].tabIndex == quants[i].tabIndex)
// add to total
tot += Number(checkboxes[i].value) * Number(quants[i].value);
else
// notify of bug
alert('Bug in code: tabIndex of checkbox '+i+' is not the same as tabIndex quantity '+i);
}
}
document.getElementById("totalDiv").firstChild.data = "£" + tot;
}
By doing it this way you get the following advantages:
Your HTML code makes more sense (input elements are grouped per tabIndex)
Your code is checked for bugs
You are absolutely sure that you multiply the correct input elements
You can find this code in this jsFiddle.
Good luck! I hope this helps you out!
Update
To create a sort of checkout system, you could go over all the elements again and store them in a variable.
Then make sure that the form implements a function upon submit:
action="javascript:checkout()"
so in total:
<form action="javascript:checkout()" id="theForm">
Easiest way to create the message would be to use one variable like so:
function checkout()
{
var message = "";
var checkboxes = document.forms["theForm"].elements["checkbox"];
var quants = document.forms["theForm"].elements["quantity"];
for (var i = 0; i < checkboxes.length; i++)
{
if (checkboxes[i].checked)
{
switch(checkboxes[i].tabIndex)
{
case 1: message += "iPhone"; break;
case 2: message += "Screen"; break;
case 3: message += "Laptop"; break;
case 4: message += "Coffee"; break;
default: message += "";
}
message += " Quantity: " + Number(quants[i].value) + " Price: £" + Number(checkboxes[i].value) * Number(quants[i].value) + "\n";
}
}
message += "\nTotal: " + document.getElementById("totalDiv").firstChild.data;
alert(message);
}
You can find a working implementation of this here.
Fancy solution
Or if you would like to make it a little bit more fancy, you could do the following:
Add the following HTML:
HTML
<br><br>
<div id="checkout">
<table id="myTable" border="1">
<tr>
<td>Product</td>
<td>Quantity</td>
<td>Price</td>
</tr>
</table>
</div>
Add the following JavaScript function:
JavaScript
function checkout()
{
document.getElementById("checkout").innerHTML = '<table id="myTable" border="1"><tr><td><b>Product</b></td><td><b>Quantity</b></td><td><b>Price</b></td></tr></table>';
// Find a <table> element with id="myTable":
var table = document.getElementById("myTable");
var count = 0;
var max = 0;
var checkboxes = document.forms["theForm"].elements["checkbox"];
var quants = document.forms["theForm"].elements["quantity"];
for (var i = 0; i < checkboxes.length; i++)
{
if (checkboxes[i].checked)
{
switch(checkboxes[i].tabIndex)
{
case 1: message = "iPhone"; break;
case 2: message = "Screen"; break;
case 3: message = "Laptop"; break;
case 4: message = "Coffee"; break;
}
count += Number(quants[i].value);
max += 1;
// Create an empty <tr> element and add it to the table:
var row = table.insertRow(max);
// Insert new cells (<td> elements) at the 1st, 2nd and 3rd position
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
// Add some text to the new cells:
cell1.innerHTML = message;
cell2.innerHTML = Number(quants[i].value);
cell3.innerHTML = "£" + Number(checkboxes[i].value) * Number(quants[i].value);
}
}
// Calculate total
var row = table.insertRow(max+1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
var cell3 = row.insertCell(2);
cell1.innerHTML = "<b>Total</b>";
cell2.innerHTML = count;
cell3.innerHTML = document.getElementById("totalDiv").firstChild.data;
}
The result looks like this:
You can find the corresponding jsFiddle HERE.
Hope that helps you out!

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>

Alert box shows up multiple times on javascript

This is very simple code, and similar to my other question.
When I click submit, the alert box shows up three times for option one, twice for two, and once for three.
Here is the part of the code where the problem is most probably located:
var chosen = ""
var len = document.ExamEntry.r1.length
for (var i = 0; i < len; i++) {
if (document.ExamEntry.r1[i].checked) {
chosen = document.ExamEntry.r1[i].value
}
if (chosen != "") {
confirm(chosen)
}
}
And here is my whole code. It all works fine except for this.
<!-- saved from url=(0055)file:///C:/Users/Bartek/Downloads/Exam%20entry4.1.2.htm -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"></head><body><h1>Exam Entry Form</h1>
<form name="ExamEntry" method="post" action="file:///C:/Users/Bartek/Downloads/success.html">
<input type="radio" name="r1" value="GCSE">GCSE
<input type="radio" name="r1" value="AS">AS
<input type="radio" name="r1" value="A2">A2
<table width="50%" border="0">
<tbody>
<tr>
<td id="name" style="color: black; ">Name</td>
<td>
<input type="text" name="name">
</td>
</tr>
<tr>
<td id="subject" style="color: black; ">Subject</td>
<td>
<input type="text" name="subject">
</td>
</tr>
<tr>
<td id="enumber" style="color: black; ">Examination Number</td>
<td>
<input type="text" name="enumber">
</td>
</tr>
<tr>
<td>
<input type="submit" name="Submit" value="Submit" onclick=" return validateForm();">
</td>
<td>
<input type="reset" name="Reset" value="Reset">
</td>
</tr>
</tbody></table>
</form>
<script>
function validateForm() {
var result = true;
var msg = "";
if (document.ExamEntry.name.value == "") {
msg += "You must enter your name \n";
document.ExamEntry.name.focus();
document.getElementById('name').style.color = "red";
result = false;
}
if (document.ExamEntry.subject.value == "") {
msg += "You must enter the subject \n";
document.ExamEntry.subject.focus();
document.getElementById('subject').style.color = "red";
result = false;
}
if (document.ExamEntry.enumber.value.length != 4) {
msg += "The examination number must be exactly four characters long \n";
document.ExamEntry.enumber.focus();
document.getElementById('enumber').style.color = "red";
result = false;
}
var chosen = ""
var len = document.ExamEntry.r1.length
for (var i = 0; i < len; i++) {
if (document.ExamEntry.r1[i].checked) {
chosen = document.ExamEntry.r1[i].value
}
if (chosen != "") {
confirm(chosen)
}
}
if (msg == "") {
return result;
} {
alert(msg);
return result;
}
}
</script>
</body>
</html>
This is GCSE computing coursework.
for (var i = 0; i <len; i++) {
if (document. ExamEntry.r1[i].checked) {
chosen = document. ExamEntry.r1[i].value
}
if (chosen != "") {
confirm(chosen)
}
}
chosen won't be "" if it was set before; you don't set it back to "" if the item wasn't checked, and so it'll confirm the last one that was. Just merge them.
for(var i = 0; i < document.ExamEntry.r1.length; i++) {
if(document.ExamEntry.r1[i].checked) {
confirm(document.ExamEntry.r1[i].value);
}
}
You were missing an else.
if (!msg) {
return result;
} else {
alert(msg);
return result;
}

Categories