So we've been struggling with a project the past few weeks, and the simple idea is to create a website for our school to use to send and receive forms. At this point we are trying to create the page where admins can dynamically create forms, akin to Google Forms. Right now our HTML looks like so:
<HTML>
<HEAD>
<TITLE>Create Form</TITLE>
<link rel="stylesheet" type="text/css" href="login.css" />
<script type="text/javascript" src="createform.js"></script>
</HEAD>
<BODY>
<form method="POST">
<div id="dynamicInput">
<label for="fieldName">Name this field</label>
<input type="text" name="fieldName">
<br><br>
<SELECT name="element">
<OPTION value="text">Textbox</OPTION>
<OPTION value="radio">Radio</OPTION>
<OPTION value= "textarea">Text Area</option>
<OPTION value = "checkbox">Check Box</option>
</SELECT>
<input type="button" value="Add an option" onClick="addAllInputs('dynamicInput', document.forms[0].element.value);">
</div>
<br><br><br>
<input type = "button" value="Add another field" onClick = "addSec();">
<br><br>
</form>
</BODY>
</HTML>
Our JavaScript:
var counterText = 0;
var counterRadioButton = 0;
var counterCheckBox = 0;
var counterTextArea = 0;
var counter = 0;
function addAllInputs(divName, inputType){
var newdiv = document.createElement('div');
switch(inputType) {
case 'text':
newdiv.innerHTML = "Entry " +(counterText+1)+" <input type='text' name='myInputs[]'><br>";
counterText++;
break;
case 'radio':
newdiv.innerHTML = "Entry " +(counterRadioButton+1)+" <input type='radio' name='myRadioButtons[]'>";
counterRadioButton++;
break;
case 'checkbox':
newdiv.innerHTML = "Entry "+(counterCheckBox+1)+" <input type='checkbox' name='myCheckBoxes[]'>";
counterCheckBox++;
break;
case 'textarea':
newdiv.innerHTML = "Entry "+(counterTextArea+1)+" <textarea name='myTextAreas[]'>type here...</textarea>";
counterTextArea++;
break;
}
document.getElementById(divName).appendChild(newdiv);
}
function addSec(){
var newdiv = document.createElement('div');
var div = document.getElementById('dynamicInput').innerHTML;
newdiv.innerHTML = document.getElementById('dynamicInput');
document.body.appendChild(newdiv);
}
We've tried many different iterations of the AddSec function, which is meant to duplicate the HTML div which makes a form field. We have gotten it to duplicate the div, however it comes with all of the "options" like checkboxes and text fields that we have added to the original field, and it cannot be modified in any way. Any advice on this would be appreciated, and we would prefer pure JavaScript methods but jQuery would be okay if we can get it working.
So far I have tested using the .clone function to clone the dynamicInput div, and have also tried adding the new divs into an array but nothing about the program was functioning.
Update
Added a Plunk
This Demo makes <input type='text'>, <textarea>, <input type='checkbox'>, groups of <input type='radio'> and <select>. It also creates extra <fieldset> as well. Each form control has a unique #id and matching [name] and each radio button has a unique id but a common [name] for each group.
I didn't make <label> an option, I figure if you follow the pattern, you should be able to add it in as a simple string. The following references are to what was used:
insertAdjacentHTML()
Template Literals
Event Delegation
HTMLFormControlsCollection
var formA = document.forms[0];
var formB = document.forms[1];
var ui = formA.elements;
var base = formB.elements;
formA.addEventListener('change', selectTag);
formA.addEventListener('click', addFieldset);
function selectTag(e) {
var rad = `s${document.querySelector('.rad:checked').value}`;
var fst = base[rad];
var qty;
var ask;
var idx = -1;
if (e.target.id === "sel") {
idx = parseInt(e.target.value, 10);
}
switch (idx) {
case 0:
var ID0 = Math.round(new Date().valueOf() / 3000000 + performance.now());
var input = `<input id="t${ID0}" name="t${ID0} type="text">`;
fst.insertAdjacentHTML('beforeend', input);
break;
case 1:
var ID1 = Math.round(new Date().valueOf() / 3000000 + performance.now());
var textArea = `<textarea id="ta${ID1}" name="ta${ID1}"></textarea>`;
fst.insertAdjacentHTML('beforeend', textArea);
break;
case 2:
var ID2 = Math.round(new Date().valueOf() / 3000000 + performance.now());
var check = `<input id="ch${ID2}" name="ch${ID2}" type='checkbox' value=''>`;
fst.insertAdjacentHTML('beforeend', check);
break;
case 3:
var ID3 = Math.round(new Date().valueOf() / 3000000 + performance.now());
ask = prompt('Enter the number of radio buttons needed');
var rads = [];
qty = parseInt(ask, 10);
var name = ID3 + Math.floor(Math.random() * 11) + 10;
for (let i = 0; i < qty; i++) {
var radio = `<input id="r${ID3+i}" name="r${name}" type='checkbox' value=''>`;
rads.push(radio);
fst.insertAdjacentHTML('beforeend', radio);
}
break;
case 4:
var ID4 = Math.round(new Date().valueOf() / 3000000 + performance.now());
var select = `<select id="s${ID4}" name="s${ID4}"></select>`;
ask = prompt('Enter the number of options needed');
qty = parseInt(ask, 10);
fst.insertAdjacentHTML('beforeend', select);
var sel = document.getElementById('s' + ID4);
for (let i = 0; i < qty; i++) {
var opt = document.createElement('option');
sel.add(opt);
}
break;
default:
break;
}
}
function addFieldset(e) {
if (e.target.id === 'addSet') {
var sets = formB.querySelectorAll('fieldset').length;
var fs = `
<fieldset id='s${sets}'>
<legend>${sets}</legend>
</fieldset>`;
formB.insertAdjacentHTML('beforeend', fs);
var rad = `
<input id='r${sets}' name='rad' class='rad' type='radio' value='${sets}'>
<label for='r${sets}'>${sets}</label>`;
ui.addSet.insertAdjacentHTML('beforebegin', rad);
}
}
<form id='ui'>
<fieldset id='set'>
<legend>Create Form</legend>
<select id='sel'>
<option>Pick a Field</option>
<option value='0'>Text Box</option>
<option value='1'>Text Area</option>
<option value='2'>Checkbox</option>
<option value='3'>Radio Group</option>
<option value='4'>Select</option>
</select>
<input id='r0' name='rad' class='rad' type='radio' value='0' checked>
<label for='r0'>0</label>
<input id='r1' name='rad' class='rad' type='radio' value='1'>
<label for='r1'>1</label>
<input id='r2' name='rad' class='rad' type='radio' value='2'>
<label for='r2'>2</label>
<input id='r3' name='rad' class='rad' type='radio' value='3'>
<label for='r3'>3</label>
<button id='addSet' type='button'>Add Fieldset</button>
</fieldset>
</form>
<form id='base'>
<fieldset id='s0'>
<legend>0</legend>
</fieldset>
<fieldset id='s1'>
<legend>1</legend>
</fieldset>
<fieldset id='s2'>
<legend>2</legend>
</fieldset>
<fieldset id='s3'>
<legend>3</legend>
</fieldset>
</form>
var counterText = 0;
var counterRadioButton = 0;
var counterCheckBox = 0;
var counterTextArea = 0;
var counter = 0;
function addAllInputs(divName, inputType){
var newdiv = document.createElement('div');
switch(inputType) {
case 'text':
newdiv.innerHTML = "Entry " +(counterText+1)+" <input type='text' name='myInputs[]'><br>";
counterText++;
break;
case 'radio':
newdiv.innerHTML = "Entry " +(counterRadioButton+1)+" <input type='radio' name='myRadioButtons[]'>";
counterRadioButton++;
break;
case 'checkbox':
newdiv.innerHTML = "Entry "+(counterCheckBox+1)+" <input type='checkbox' name='myCheckBoxes[]'>";
counterCheckBox++;
break;
case 'textarea':
newdiv.innerHTML = "Entry "+(counterTextArea+1)+" <textarea name='myTextAreas[]'>type here...</textarea>";
counterTextArea++;
break;
}
document.getElementById(divName).appendChild(newdiv);
}
function addSec(){
var newdiv = document.createElement('div');
var div = document.getElementById('dynamicInput').innerHTML;
newdiv.innerHTML = document.getElementById('dynamicInput').innerHTML;
document.body.appendChild(newdiv);
}
<HTML>
<HEAD>
<TITLE>Create Form</TITLE>
<link rel="stylesheet" type="text/css" href="login.css" />
<script type="text/javascript" src="createform.js"></script>
</HEAD>
<BODY>
<form method="POST">
<div id="dynamicInput">
<label for="fieldName">Name this field</label>
<input type="text" name="fieldName">
<br><br>
<SELECT name="element">
<OPTION value="text">Textbox</OPTION>
<OPTION value="radio">Radio</OPTION>
<OPTION value= "textarea">Text Area</option>
<OPTION value = "checkbox">Check Box</option>
</SELECT>
<input type="button" value="Add an option" onClick="addAllInputs('dynamicInput', document.forms[0].element.value);">
</div>
<br><br><br>
<input type = "button" value="Add another field" onClick = "addSec();">
<br><br>
</form>
</BODY>
</HTML>
you've missed an innerHTML.
Related
I have two data list in the below snippet and the values of the selected option should be shown beside them.
My First(Account) one is working properly, but second(Head) one is not working. The value is not getting selected for Head.
/*List function starts*/
document.querySelector('input[list]').addEventListener('input', function(e) {
var input = e.target,
list = input.getAttribute('list'),
options = document.querySelectorAll('#' + list + ' option'),
hiddenInput = document.getElementById(input.getAttribute('id') + '-hidden'),
inputValue = input.value;
hiddenInput.value = inputValue;
for (var i = 0; i < options.length; i++) {
var option = options[i];
if (option.innerText === inputValue) {
hiddenInput.value = option.getAttribute('data-value');
break;
}
}
});
/*List function ends*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="accntid">Account: </label>
<input id="accntid" name="taccntlist" list="accnt_list" value="" placeholder="Account" required />
<datalist id="accnt_list">
<option data-value="001">Dummy1</option>
<option data-value="0000000">Dummy</option>
</datalist>
<input type="text" name="txtaccnt" id="accntid-hidden" readonly>
<br /><br /><br />
<label for="headid">Head: </label>
<input id="headid" name="txtheadlist" list="head_list" value="" placeholder="Head" required />
<datalist id="head_list">
<option data-value="1">d1</option>
<option data-value="0000000000">dummy</option>
</datalist>
<input type="text" name="txthead" id="headid-hidden" readonly>
<br /><br /><br />
I changed your js code, and added method forEach(), having previously declared the call to the inputs like this:
let inputs = document.querySelectorAll('input[list]');
This means that e.target is no longer necessary to use.
let inputs = document.querySelectorAll('input[list]');
inputs.forEach(function(current, index) {
current.addEventListener('input', function() {
list = current.getAttribute('list'),
options = document.querySelectorAll('#' + list + ' option'),
hiddenInput = document.getElementById(current.getAttribute('id') + '-hidden'),
inputValue = current.value;
hiddenInput.value = inputValue;
for (var i = 0; i < options.length; i++) {
var option = options[i];
if (option.innerText === inputValue) {
hiddenInput.value = option.getAttribute('data-value');
break;
}
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="accntid">Account: </label>
<input id="accntid" name="taccntlist" list="accnt_list" value="" placeholder="Account" required />
<datalist id="accnt_list">
<option data-value="001">Dummy1</option>
<option data-value="0000000">Dummy</option>
</datalist>
<input type="text" name="txtaccnt" id="accntid-hidden" readonly>
<br /><br /><br />
<label for="headid">Head: </label>
<input id="headid" name="txtheadlist" list="head_list" value="" placeholder="Head" required />
<datalist id="head_list">
<option data-value="1">d1</option>
<option data-value="0000000000">dummy</option>
</datalist>
<input type="text" name="txthead" id="headid-hidden" readonly>
<br /><br /><br />
How to Enable/Disable input field based on a dropdown selection. and also I should take the user data in JSP based on the selection.
<form action="../jsp/findActorbyChar.jsp">
<h3>Search by:
<select name ="nameField"> </h3>
<option> Only FirstName </option>
<option> Only LastName </option>
<option> Or </option>
<option> And </option>
</select>
<br><br>
First Name <input type="text" name="firstName"/>
Last Name <input type="text" name="lastName"/>
<br><br>
<input type="submit"/>
<input type="reset"/>
Modified Html as shown below:
<h3>Search by:</h3>
<select name ="nameField" id="nameField">
<option>Only FirstName</option>
<option>Only LastName</option>
<option>Or</option>
<option>And</option>
</select>
<br><br>
First Name <input type="text" name="firstName" id="firstNameInput"/>
Last Name <input type="text" name="lastName" id="lastNameInput" />
<br><br>
<input type="submit"/>
<input type="reset"/>
Javascript code:
var nameField = document.getElementById("nameField");
var firstNameInput = document.getElementById("firstNameInput");
var lastNameInput = document.getElementById("lastNameInput");
nameField.addEventListener("change", function(){
//Update this to your logic...
if(nameField.value === "And"){
firstNameInput.disabled = true;
lastNameInput.disabled = true;
}
});
But I think it would be easier if using JQuery to handle DOM update.
Give your menu an id and then you can access the selected index with menu.options.selectedIndex. From there, you can add an on change handler to the menu and use switch cases to set the disabled attribute of the menu.
<h3>Search by:
<select id="menu" name ="nameField"> </h3>
<option> Only FirstName </option>
<option> Only LastName </option>
<option> Or </option>
<option> And </option>
</select>
<br><br>
First Name <input id="first" type="text" name="firstName"/>
Last Name <input id="last" type="text" name="lastName"/>
<br><br>
<input type="submit"/>
<input type="reset"/>
<script type="text/javascript">
var menu = document.getElementById('menu');
var first = document.getElementById('first');
var last = document.getElementById('last');
menu.onchange = function(){
var enableFirst = false, enableLast = false;
switch(menu.options.selectedIndex){
case 0:
enableFirst = true;
enableLast = false;
break;
case 1:
enableFirst = false;
enableLast = true;
break;
case 2:
/*not sure which results you want here*/
break;
case 3:
/*not sure which results you want here*/
break;
default:
break;
}
first.disabled = !enableFirst;
last.disabled = !enableLast;
}
</script>
My code: still all the input fields are enabled
enter code here
<script src="script.js">
var nameField = document.getElementById("nameField");
var firstNameInput = document.getElementById("firstNameInput");
var lastNameInput = document.getElementById("lastNameInput");
nameField.addEventListener("change", function(){
//Update this to your logic...
<script src="script.js">
var nameField = document.getElementById("nameField");
var firstNameInput = document.getElementById("firstNameInput");
var lastNameInput = document.getElementById("lastNameInput");
nameField.addEventListener("change", function(){
//Update this to your logic...
if(nameField.value === "And"){
firstNameInput.disabled = true;
lastNameInput.disabled = true;
}
else if(nameField.value === "firstNameInput"){
firstNameInput.disabled = false;
lastNameInput.disabled = true;
}
else if(nameField.value === "lastNameInput"){
firstNameInput.disabled = true;
lastNameInput.disabled = false;
}
elseif(nameField.value === "lastNameInput"){
firstNameInput.disabled = true;
lastNameInput.disabled = true;
}
});
</script>
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">
I am trying to create a simple cost Estimator in HTML Javascript but I am having trouble calling a JS function with a HTML Button. I know the problem must be due to how I am calling my function or how I am displaying the result of the calculation, or both.
If any one could show me where I am going wrong and what is the correct practise it would be greatly appreciated.
Here is the Codepen: http://codepen.io/FredHair/pen/FgJAd
(It returns Undefined for the answer).
This is my HTML:
<div>
<h1>Cost Estimator</h1>
<form>
<input type= "numbers" id="x" placeholder = "Length" /><br />
<input type= "numbers" id="y" placeholder = "Width"/><br />
<input type= "numbers" id="z" placeholder = "Height"/><br />
<select id="choice" >
<option value = "" ></option>
<option value = "1">option 1</option>
<option value = "2">0ption 2</option>
<option value = "3">option 3</option>
</select>
<br/>
<br/>
<input id= "est" type="button" value = "Estimate" onclick= "calculator()"/>
<input id= "reset" type="reset" value = "Reset"/>
</form>
<h1 id="result"> = </h1>
</div>
This Is the JS:
function calculator(calc){
var x = Number(document.getElementById("x").value);
var y = Number(document.getElementById("y").value);
var z = Number(document.getElementById("z").value);
var p = Number(30);
var result;
switch(calc){
case"1" : result = z * p;
break;
case"2" : result = x * p + 50;
break;
case"3" : result = x * p + 30;
break;
}
document.getElementById("result").innerHTML = " = " + result;
}
http://codepen.io/FredHair/pen/FgJAd
Thanks.
function calculator() {
var x = Number(document.getElementById("x").value);
var y = Number(document.getElementById("y").value);
var z = Number(document.getElementById("z").value);
var p = Number(30);
var result;
var calc = document.getElementById("choice").value
switch (calc) {
case "1":
result = z * p;
break;
case "2":
result = x * p + 50;
break;
case "3":
result = x * p + 30;
break;
}
document.getElementById("result").innerHTML = " = " + result;
}
<div>
<h1>Cost Estimator</h1>
<form>
<input type="numbers" id="x" placeholder="Length" />
<br />
<input type="numbers" id="y" placeholder="Width" />
<br />
<input type="numbers" id="z" placeholder="Height" />
<br />
<select id="choice">
<option value=""></option>
<option value="1">option 1</option>
<option value="2">0ption 2</option>
<option value="3">option 3</option>
</select>
<br/>
<br/>
<input id="est" type="button" value="Estimate" onclick="calculator()" />
<input id="reset" type="reset" value="Reset" />
</form>
<h1 id="result"> = </h1>
</div>
You are not passing the value calc...
update your js code like this:
function calculator(){
var x = Number(document.getElementById("x").value);
var y = Number(document.getElementById("y").value);
var z = Number(document.getElementById("z").value);
var p = Number(30);
var result;
var calc = document.getElementById("choice").value
switch(calc){
case"1" : result = z * p;
break;
case"2" : result = x * p + 50;
break;
case"3" : result = x * p + 30;
break;
}
Instead get the value of calc in parameter get it under the method.
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!