My app is based on Python 3.4 and Flask, but I need to use JavaScript to dynamically change the values of hidden fields. I am not familiar with JavaScript and I don't know why my code isn't working.
In one of my templates I have a very simple payment form that allows the user to select a single bundle of credits using radio buttons (I stripped out the CSS and form action):
<form>
<input id="amount" value="price_list.price1" type="radio" name="amount">
<input id="amount" value="price_list.price2" type="radio" name="amount">
<input id="amount" value="price_list.price3" type="radio" name="amount">
<input id="amount" value="price_list.price4" type="radio" name="amount">
<input id="item_name" type="hidden" name="item_name" value="">
<input id="item_description" type="hidden" name="item_description" value="">
<input id="custom_int1" type="hidden" name="custom_int1" value=0>
<input id="payment" type=submit value=Payment>
</form>
The "price_list.price1" fields refer to a dynamic price, set by the system. This changes hourly, but each of the entries point to a given number of credits.
Due to the requirements of the payment processor I use, I need to change three hidden fields depending on the selection made namely item_name, item_description and custom_int1 (which represents x number of credits bought).
I referenced the following answers:
Dynamically Change Multiple Hidden Form Fields
Setting a form variable value before submitting
Jquery Onclick Change hidden parameter and submit
What I ended up with is an attempt to use jQuery to change the values. The code is as follows:
<script>
$("#amount").change(function () {
// Get a local reference to the JQuery-wrapped select and hidden field elements:
var sel = $(this);
var set_name = $("input[name='item_name']");
var set_description = $("input[name='item_description']");
var set_creds = $("input[name='custom_int1']");
// Get the selected option:
var opt = sel.children("[value='" + sel.val() + "']:first");
// Set the values
if (opt.value=={{ price_list.price1 }}) {
set_name.value = '1 Credit';
set_description.value = '1 Credit';
set_creds.value = 1;
} else if (opt.value=={{ price_list.price5 }}) {
set_name.value = '5 Credits';
set_description.value = '5 Credits';
document.getElementById('custom_int1').value = 5;
} else if (opt.value=={{ price_list.price10 }}) {
set_name.value = '10 Credits';
set_description.value = '10 Credits';
set_creds.value = 10;
} else if (opt.value=={{ price_list.price25 }}) {
set_name.value = '25 Credit';
set_description.value = '25 Credit';
set_creds.value = 25;
} else if (get_amount.value=={{ price_list.price50 }}) {
set_name.value = '50 Credits';
set_description.value = '50 Credits';
set_creds.value = 50;
};
});
</script>
I added the script at the bottom of my template right before the <body> tag.
The script does not work to change the hidden fields at all. Any and all help would be greatly appreciated.
Element id's should be unique (amount). Names can be the same. So fix HTML:
<input id="amount1" value="price_list.price1" type="radio" name="amount" />
<input id="amount2" value="price_list.price2" type="radio" name="amount" />
<input id="amount3" value="price_list.price3" type="radio" name="amount" />
<input id="amount4" value="price_list.price4" type="radio" name="amount" />
Fix script:
$(document).ready(function () {
$('[type=radio]').click(function () { //click is right event
//console.log(this.id);//for test purpose
var set_name = $("input[name='item_name']");
var set_description = $("input[name='item_description']");
var set_creds = $("input[name='custom_int1']");
switch (this.id) {//"this" is the element clicked
case 'amount1':
set_name.val('1 Credit');//not set_name.value='...'
set_description.val('1 Credit');
set_creds.val(1);
break;
case 'amount2':
set_name.val('5 Credits');
set_description.val('5 Credits');
set_creds.val(5);
break;
case 'amount3':
set_name.val('10 Credits');
set_description.val('10 Credits');
set_creds.val(10);
break;
case 'amount4':
set_name.val('25 Credits');
set_description.val('25 Credits');
set_creds.val(25);
break;
default:
set_name.val('');
set_description.val('');
set_creds.val(0);
break;
}
});
});
`
The change event is called for all radio buttons, that are changed. To get only the button that is checked, use:
$("#amount:checked").change(function () {
//
}
Related
I'm trying to enable the submit button , there are 3 fields in a form value of 1st field-box is fixed and the addition of 2nd field-box and 3rd field-box is stored in 4th field box. So what i need is it should compare with the 1st number and th3 4th number (addition of 2nd and 3rd) and if the condition satisfied then it should enable the submit button or else button should be disable. I have done some work around and not able to figure it out what i am missing. Please help me regarding the same.
I have added the JSfiddle code on which I am working:
let $form = $('form');
let $first1 = $('#first1');
let $total1 = $('#total1');
let $total2 = $('#total2');
let $answer = $('#answer');
let $submitButton = $(':submit');
$form.on('submit', function(event) {
let val1 = Number($first1.val());
let val2 = Number($answer.val());
if (val1 < val2) { // If condition is NOT met.
event.preventDefault(); // Default submit from happening.
return false; // Stop function.
}
});
$form.on('input', function(event) {
let val1 = Number($first1.val());
let val2 = Number($answer.val());
console.log(val1, val2)
let isDisabled = val1 < val2; // Will return true or false.
$submitButton.prop('disabled', isDisabled);
});
$form.on('input', function(event) {
let val1 = Number($total1.val());
let val2 = Number($total2.val());
console.log(val1, val2)
let number = parseInt($('#total1').val()) + parseInt($('#total2').val());
$('#answer').val(number);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" action="order.php">
<label for="first1">Fixed Number</label>
<input type="number" id="first1" value="10" />
<br>
<label for="total1">First Number</label>
<input type="number" id="total1" class="change"/>
<br>
<label for="total2">Second Number</label>
<input type="number" id="total2" class="change"/>
<br>
Answer = <input type="number" id="answer" name="answer" value=""/>
<br>
<input type="submit" value="submit" disabled title="Not Relevant">
</form>
You can simplify your function more by combining the two input event listeners and put them in one. And the submit event listener is not needed either.
val1 and val2 are already numbers cause of the Number() constructor wrapping the $total1.val() function. It does the same thing as parseInt.
Add val1 to val2 and store that result in a new variable called total.
Then check if the total is lower or higher than the firstVal (fixed value) and disable or enable the submit button.
Add a readonly attribute to inputs that you don't want modified by the user.
let $form = $('form');
let $first1 = $('#first1');
let $total1 = $('#total1');
let $total2 = $('#total2');
let $answer = $('#answer');
let $submitButton = $(':submit');
$form.on('input', function(event) { // This function gets called every time you change the value in one of the inputs
let firstVal = Number($first1.val()); // Get fixed number
let val1 = Number($total1.val()); // Get 2nd field number
let val2 = Number($total2.val()); // Get 3rd field number
let total = val1 + val2; // Add 2nd and 3rd field
let isDisabled = total < firstVal; // If total is lower than fixed number, then is true, otherwise is false.
$submitButton.prop('disabled', isDisabled); // Disable based on if isDisabled is true or false
$answer.val(total); // Show the total
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" action="order.php">
<label for="first1">Fixed Number</label>
<input type="number" id="first1" value="10" readonly/>
<br>
<label for="total1">First Number</label>
<input type="number" id="total1" class="change"/>
<br>
<label for="total2">Second Number</label>
<input type="number" id="total2" class="change"/>
<br>
<label for="answer">Answer</label>
<input type="number" id="answer" name="answer" value="" readonly/>
<br>
<input type="submit" value="submit" disabled title="Not Relevant">
</form>
I have two textboxes where a user enters a number into each one and then clicks a radio button to select the mathematical operation to be performed upon the calculate button.This is for a homework assignment, so only javascript and html
are being used, no jquery. Currently when I click the button, nothing appears to happen and I am getting no console errors...
HTML
<div>
<p>Enter two numbers, select a math, then click the button.<br>
The answer will be shown below.</p>
<form>
1st number: <input type="text" name="number1">
2nd number: <input type="text" name="number2">
<br>
<input type="radio" name="add">Add <br>
<input type="radio" name="subtract">Subtract <br>
<input type="radio" name="multiply">Multiply <br>
<input type="radio" name="division">Division <br>
<input type="button" name="calc" onclick="calculate()" value="Calculate"> <br>
</form>
<p id="math_res"></p>
</div>
Javascript
function calculate(){
var num1 = parseInt("document.getElementsByName('number1').value;", 10);
var num2 = parseInt("document.getElementsByName('number2').value;", 10);
var add = document.getElementsByName("add");
var sub = document.getElementsByName("subtract");
var multi = document.getElementsByName("multiply");
var divis = document.getElementsByName("division");
var res = document.getElementById("math_res").innerHTML;
if (add.checked == true){
res = num1 + num2;
}
else if ( sub.checked == true){
res = num1 + num2;
}
else if (multi.checked == true){
res = num1 * num2;
}
else if (divis.checked == true){
res = num1 / num2;
}
}
I thought my function would take the input from the two text boxes and convert the user input to an integer and assign them to variable num1 and num2. Then assign each radio button to a variable to reduce typing of document.get...
that each if statement would check to see if that radio but was checked. If true perform calculation if false move to next if statement and display the results in a paragraph element.
where did I go wrong?
You have a couple of issues.
getElementsByName returns a collection of elements, not a single element so:
var add = document.getElementsByName("add");
will assign undefined to add. But you don't need to use it, just reference the controls as named properties of the form. Pass a reference to the button from the listener:
<input type="button" name="calc" onclick="calculate(this)" value="Calculate">
Then in the function get the form:
function calculate(element) {
var form = element.form;
Now just do:
var num1 = parseInt(form.number1.value, 10);
and so on, which also fixes the other issues you have with referencing the controls.
Also, radio buttons need to have the same name so that only one is selectable, so as Felix says, give them all the same name and differentiate on value (or class or some other attribute value). You'll need to loop over them to find out the operation to perform, so the HTML might be:
<input type="radio" name="operation" value="add">Add <br>
<input type="radio" name="operation" value="subtract">Subtract <br>
<input type="radio" name="operation" value="multiply">Multiply <br>
<input type="radio" name="operation" value="division">Division <br>
Then to get the operation:
var radios = form.operation;
var op;
for (var i=0; i<radios.length; i++) {
if (radios[i].checked) {
op = radios[i].value;
break;
}
}
Now check the value of op to work out whether to add, subtract, etc.
Here's a quick example, I don't recommend inline scripts like this but it's handy for playing.
<form>
<input type="radio" name="operation" value="add">Add <br>
<input type="radio" name="operation" value="subtract">Subtract <br>
<input type="radio" name="operation" value="multiply">Multiply <br>
<input type="radio" name="operation" value="division">Division <br>
<input type="button" onclick="
var form = this.form;
var radios = form.operation;
var op;
for (var i=0; i<radios.length; i++) {
if (radios[i].checked) {
op = radios[i].value;
break;
}
}
form.selectedOperation.value = op || 'No operation selected';
" value="Get selected operation">
<input type="text" readonly name="selectedOperation"><br>
<input type="reset">
</form>
There are a few issues I can notice.
1.
getElementsByName returns a NodeList, which is Array-like. You need to retrieve the first element in the NodeList before accessing its value. For example,
document.getElementsByName('number1')[0].value
2.
You are passing a literal code string to parseInt. You should write something like
parseInt(document.getElementsByName('number1')[0].value, 10);
3.
The code var res = document.getElementById('math_res').innerHTML stores a reference to the innerHTML of the element. When you assign res = num1 + num2 for example, you are simply overwriting the reference, instead of actually altering the innerHTML. To correct this,
var elem = document.getElementById('math_res');
// later...
elem.innerHTML = num1 + num2;
4. You are incorrectly defining multiple radio buttons with different names. In order for the browser to render them as a "radio button group" where only one can be selected, they must have the same name, but different "value" attributes. See RobG's answer or the Plunkr below for an example of how to define the radio button group and extract its value using JavaScript.
A working version of your code is here.
Edit Please note that these are minimal edits to make your code work. RobG's answer shows a more correct way of extracting the values of form fields.
Here is my version, hope it helps you.
<!DOCTYPE html>
<html>
<body>
<div>
<p>Enter two numbers, select a math, then click the button.<br>
The answer will be shown below.</p>
<form>
1st number: <input type="text" name="number1" id = 'number1'>
2nd number: <input type="text" name="number2" id = 'number2'>
<br>
<input type="radio" name="button" id = 'add' >Add <br>
<input type="radio" name="button" id = 'substract'>Subtract <br>
<input type="radio" name="button" id = 'multiply'>Multiply <br>
<input type="radio" name="button" id = 'division'>Division <br>
<input type="button" name="calc" onclick="calculate()" value="Calculate"> <br>
</form>
<p id="math_res"></p>
</div>
<script>
function calculate(){
//Obtaining the references to the text inputs
var number1 = parseInt(document.getElementById('number1').value);
var number2 = parseInt(document.getElementById('number2').value);
//Reference of the result Box
var resultBox = document.getElementById('math_res');
resultBox.innerHTML = '';
//Reference of the radio buttons
var buttonAdd = document.getElementById('add');
var buttonSubstract = document.getElementById('substract');
var buttonMultiply = document.getElementById('multiply');
var buttonDivision = document.getElementById('division');
//Make the magic
if(buttonAdd.checked == true){
resultBox.innerHTML = number1 + number2
}
else{
if(buttonSubstract.checked == true){
resultBox.innerHTML = number1 - number2
}
else{
if(buttonMultiply.checked == true){
resultBox.innerHTML = number1 * number2
}
else{
if(buttonDivision.checked == true){
resultBox.innerHTML = number1 / number2
}
}
}
}
}
</script>
</body>
I wrote some code using jQuery to convert <input> field values from one unit system to another (English <-> Metric). All was going well until I have realized that I am using a class selector, so instead of each value doing its conversion individually, all values (with same class) get converted to the same identical value (equal to the first occurrence of class).
An obvious solution is to assign an id to each value, which I suppose will work, but I am here to ask if there is a better way. I have a lot of values (which is why I tried using class), and would like to avoid using id, if possible. But, all I am looking for is "convert each value individually (using my conversion function)". How can this be done?
jQuery
function convertValues() {
if ($('#unit_system').val() == "English") //if changed to English
{
$('.value_gpm').val( //do converstion from Metric to English
convert($('.value_gpm').val(), "m3h", "gpm")
);
}
else if ($('#unit_system').val() == "Metric") //if changed to Metric
{
$('.value_gpm').val( //do conversion from English to Metric
convert($('.value_gpm').val(), "gpm", "m3h")
);
}
}
Calling Function
//below code is for select box (HTML for it is not shown)
$("#unit_system").change(function(){ //select box change detected
convertValues(); //function is called
});
HTML at first (before Select box change)
<input type="text" class="value_gpm" name="design_a" value="444" />
<input type="text" class="value_gpm" name="design_b" value="555" />
<input type="text" class="value_gpm" name="design_c" value="666" />
<input type="text" class="value_gpm" name="design_d" value="777" />
<input type="text" class="value_gpm" name="design_e" value="888" />
HTML after (after Select box is changed)
<input type="text" class="value_gpm" name="design_a" value="1954.87" />
<input type="text" class="value_gpm" name="design_b" value="1954.87" />
<input type="text" class="value_gpm" name="design_c" value="1954.87" />
<input type="text" class="value_gpm" name="design_d" value="1954.87" />
<input type="text" class="value_gpm" name="design_e" value="1954.87" />
Expected behavior: conversion produces different value per row
Actual behavior: same value produced for each row
Just loop through them, something like this.
var inputs = $('.value_gpm');
for(i=0;i < inputs.length; i++){
var input = inputs[i];
input.val( convert(input.val(), "m3h", "gpm") );
}
Best bet - using $.each and $(this).
$(document).ready(function(){
var valueEls = $('.value_gpm');
$("#unit_system").change(function(){
var unit = $(this).val();
switch(unit){
case "English":
valueEls.each(function(){
$(this).val(convert($(this).val(), "m3h", "gpm");
});
break;
case "Metric":
valueEls.each(function(){
$(this).val(convert($(this).val(), "gpm", "m3h");
});
break;
}
});
});
Use each()
$("value_gpm").each(function () {
convert(this.val(), ...etc
The less lines of codes I figure out for this is this:
var unit_system = $('#unit_system').val();
$('.value_gpm').each(function(){
convert($(this).val(), unit_system == "English" ? "m3h" : "gpm", unit_system == "English" ? "gpm" : "m3h");
});
You can use jQuery each:
$("#unit_system").change(function(){
var fromUnit = "m3h";
var toUnit = "gpm";
if ($(this).val() == "Metric"){
fromUnit = "gpm";
toUnit = "m3h";
}
$('.value_gpm').each(function(){
$(this).val(convert($(this).val(), fromUnit, toUnit));
});
});
im trying to take multiple inputs from a user with different element id's and run them through one if else function. here is my code:
Enter the grade and number of credits for course 1:
<input type="text" id="lettergrade1" onchange="lettergrade[0]=numgrade(this.value)";>
<input type="text" id="credithour1" onchange="credhour[0]";>
etc... this extends down to lettergrade 5. I have to run them through the function numgrade (without using a for loop). how do I run these through the same if else construct without making 5 different ones (how can I make one statement that will work for 5 diffferent id's)?
Iterate through the elements and bind them to the onchange callback:
var $ = document;
var lettergrade = [];
[].slice.call($.querySelectorAll('.lettergrade')).forEach(function(el, index) {
el.onchange = function() {
numgrade(index, this.value);
}
});
function numgrade(index, value) {
lettergrade[index] = value;
$.getElementById('output').innerText = JSON.stringify(lettergrade);
}
<input type="text" class="lettergrade" id="lettergrade1" placeholder="1">
<input type="text" class="lettergrade" id="lettergrade2" placeholder="2">
<input type="text" class="lettergrade" id="lettergrade3" placeholder="3">
<input type="text" class="lettergrade" id="lettergrade4" placeholder="4">
<input type="text" class="lettergrade" id="lettergrade5" placeholder="5">
<output id="output"></output>
I want to know how to reset a particular form field using jQuery.
I'm using the folowing function:
function resetForm(id) {
$('#'+id).each(function(){
this.reset();
});
}
but it is resetting all the fields. Is there any way to reset specific fields using jQuery or JavaScript? I want to reset only a particular field.
function resetForm(id) {
$('#' + id).val(function() {
return this.defaultValue;
});
}
example without using id:
http://jsfiddle.net/vYWdm/
The reset() method affects the whole form, by design, to reset only particular input elements, assuming that there's a Reset previous inputelement after eachinput`:
$('button.reset').click(
function(){
var input = $(this).prev('input:first');
input.val(''); // assuming you want it reset to an empty state;
});
JS Fiddle demo
To reset the input to its original state, then first I'd recommend storing the original value in a data-* attribute for recollection:
$('input').each(
function(){
$(this).attr('data-originalValue',$(this).val());
});
$('button.reset').click(
function(){
var input = $(this).prev('input:first');
input.val(input.attr('data-originalValue'));
});
JS Fiddle demo
Given HTML similar to the following (in which the input elements are grouped together):
<form action="#" method="post">
<fieldset>
<input value="something" />
<button class="reset">Reset the input</button>
</fieldset>
<fieldset>
<input type="checkbox" name="two" />
<input type="checkbox" name="two" checked />
<input type="checkbox" name="two" />
<button class="reset">Reset the input</button>
</fieldset>
<fieldset>
<input type="radio" name="three" checked />
<input type="radio" name="three" />
<button class="reset">Reset the input</button>
</fieldset>
</form>
The following jQuery will reset the input elements back to their page-load state:
$('button.reset').click(
function () {
$(this).prevAll('input').val(function(){
switch (this.type){
case 'text':
return this.defaultValue;
case 'checkbox':
case 'radio':
this.checked = this.defaultChecked;
}
});
});
JS Fiddle demo.
References:
attr().
prev().
reset()
val().
My approach would be to consider three cases: free-input-based fields, check-based fields and select-based fields.
$(set_of_fields).each(function() {
// Don't bother checking the field type, just check if property exists
// and set it
if (typeof(this.defaultChecked) !== "undefined")
this.checked = this.defaultChecked;
if (typeof(this.defaultValue) !== "undefined")
this.value = this.defaultValue;
// Try to find an option with selected attribute (not property!)
var defaultOption = $(this).find('option[selected]');
// and fallback to the first option
if (defaultOption.length === 0)
defaultOption = $(this).find('option:first');
// if no option was found, then it was not a select
if (defaultOption.length > 0)
this.value = defaultOption.attr('value');
});
Edit: I just noticed this won't work with <select multiple> fields.
You could do (if you plan to use the reset() javascript method):
function resetForm(id) {
document.getElementById(id).reset();
}
There is no need for jQuery as the method "reset" is a standard javascript method