How to keep values of radio elements - javascript

SOLVED:
I am using jQuery to allow a user to dynamically add fields to a form and I am requiring that they select certain yes and no values. When I clone the row I need to keep the values on input radio elements but not on the text element. I was expecting that this would do it but no luck.
How would I keep the values on the radio elements?
Also when the previous node has radios selected the cloning duplicates the selection information. I DON'T want that to happen.
HTML:
<div class="dynamic-node">
<input type="text" name="custom-name[0]" value=""/>
<hr>
<input type="radio" name="haswood[0]" value="yes"/>Yes
<input type="radio" name="haswood[0]" value="no"/>No
<hr>
<input type="radio" name="hasmetal[0]" value="yes"/>Yes
<input type="radio" name="hasmetal[0]" value="no"/>No
<hr>
<input type="radio" name="hasplastic[0]" value="yes"/>Yes
<input type="radio" name="hasplastic[0]" value="no"/>No
</div>
<div class="clone-node">Add Row</div>
JQuery:
$cloneNode = $( ".clone-node" );
$cloneNode.click(function(){
var $newNode = $(".dynamic-node:last").clone(true);
$newNode.find('input').each(function() {
var $this = $(this);
$this.attr('name', $this.attr('name').replace(/\[(\d+)\]/, function($0, $1) {
return '[' + (+$1 + 1) + ']';
}));
$this.val('');
});
$newNode.insertAfter('.dynamic-node:last');
});
Solution:
Thanks to commenters below and borrowing their fresh set of eyes I resolved this by extending the code a little and making adjustment to elements based on their type and my needs:
$cloneNode = $( ".clone-node" );
$cloneNode.click(function(){
var $newNode = $(".dynamic-node:last").clone(true);
$newNode.find('input').each(function() {
var $this = $(this);
$this.attr('name', $this.attr('name').replace(/\[(\d+)\]/, function($0, $1) {
return '[' + (+$1 + 1) + ']';
}));
if( $this.is('input:text') ) {
$this.val('');
}
if( $this.is('input:radio') ) {
$this.prop('checked', false);
}
});
$newNode.insertAfter('.dynamic-node:last');
});

Related

Javascript checkbox that adds value from another table to the price

Could anybody help me with this problem? I have an input price value that changes when you select different checkboxes, but it doesn't add up.
I don't really know how to fix it that if you select something, it adds to the total price, and when you select another one it adds again.
The foreach is to get all the exa_names from the Extra table with the checkbox and the price from that item.
Javascript
$(document).ready(function(){
$(".option").change(function(){
var id = $(this).attr('id');
console.log(id);
var id_number = id.split("_")[1];
console.log(id_number);
var hidden_input = $(".option_price" + id_number).val();
console.log(hidden_input);
})
});
HTML
<label>Options</label><br>
#foreach($options as $option)
<div>
<input type="checkbox" class="option" id="option_{{ $option->exa_id }}" name="option_{{ $option->exa_id }}" value="{{ $option->exa_id }}" {{ isset($cache) ? (isset($cache['option_' . $option->exa_id]) ? 'checked' : '') : (old() ? (old('option_' . $option->exa_id) ? 'checked' : '') : ($inschrijving ? (in_array($registration->exa_id, $registration_options) ? 'checked' : '') : '')) }} >
<input type="hidden" value="{{ $option->exa_price}}" class="option_price_{{ $option->exa_id }}">
<label>{{ $option->exa_name }}</label>
<label> €{{ $option->exa_price }} </label>
</div>
#endforeach
Html input totalprice(where it has to show the total price)
<div class="row">
<div class="col-xs-12">
<div class="form-group">
<label>Total</label>
<input type="text" name="totalprice" id="totalprice" class="form-control" data-blocked="<>{}" value="0" required>
</div>
</div>
</div>
RegistrationController
$options_ids_array = array();
$options = Extra::all();
foreach($options as $option){
$option->exa_id = "option_" . $option->exa_id;
$input_option = $option->exa_id;
if(!is_null($input_option)){
$options_ids_array[] = $input_option;
}
}
$registration->dev_option_id = implode(",", $options_ids_array);
$registration->save();
I think it's better to store the price of your item in a javascript variable (because it prevent to change the value of hidden input and have easy access on js side) and access to your price through your checkbox value (because it is exactly the id you tried to get with id value by split it with _ character). For add price from checked checkboxes (if they are not too much checkboxes), create a check function to detect which of them are checked and then select the price of each and add them to each other, then put it to your price place. Something like:
var options = $(".option");
var options_price = ['your', 'price', 'values', 'according', 'to', 'options', 'id'];
function optionsPrice() {
var total_price = 0;
options.each(function () {
var option = $(this);
if (option.is(':checked') && option.val() != '' && $.inArray(option.val(), Object.keys(options_price))) {
total_price += options_price[option.val()];
}
});
return total_price;
}
Call optionsPrice function on any checkbox change.
OR if you have a lot of checkeboxes on your page,
you can have a global total price variable and add or sub price from it on any checkbox change. Something like:
var total_price = 0;
var options = $(".option");
var options_price = ['your', 'price', 'values', 'according', 'to', 'options', 'id'];
var option, val;
options.on('change', function() {
option = $(this);
val = option.val();
if(val && val != '' && $.inArray(val, Object.keys(options_price)) !== -1) {
if(option.is(':checked')) {
total_price += options_price[option.val()];
} else {
if(total_price > 0) {
total_price -= options_price[option.val()];
} else {
total_price = 0;
}
}
}
});
I hope it helps :)
You've got the tricky part - uniquely identifying your inputs in JS - already done. All that is left is to sum them up!
The simplest option is to iterate over all your inputs whenever one of them changes, and recalculate the price from scratch.
I'm not 100% sure how your inputs and prices and extra costs work, but let's make it simple. Here's some example HTML in the format your Blade template could generate:
<div>
<input type="checkbox" class="option" id="option_1" name="option_1" value="1" checked>
<input type="hidden" value="1" class="option_price_1">
<label>Orange</label>
<label>1</label>
</div>
<div>
<input type="checkbox" class="option" id="option_2" name="option_2" value="2">
<input type="hidden" value="2" class="option_price_2">
<label>Apple</label>
<label>2</label>
</div>
<div>
<input type="checkbox" class="option" id="option_3" name="option_3" value="3" checked>
<input type="hidden" value="3" class="option_price_3">
<label>Pear</label>
<label>3</label>
</div>
<!-- I've added a total area to display the total result -->
<div id="total"></div>
Now taking your code, and using jQuery's .each() to iterate over all inputs on the page:
$('.option').change(function() {
// This is what we'll use to sum the prices
var total = 0;
// Use .each() to iterate over all .option inputs
$('.option').each(function(index) {
// Inside .each, $(this) represents the current element
var id = $(this).attr('id');
var id_number = id.split("_")[1];
// Note your code was missing the _ after price here
var hidden_input = $(".option_price_" + id_number).val();
// Is this option checked? If yes, we want to add its value to
// the total
if ($(this).prop('checked')) {
// .val() returns a string, prefixing hidden_input with '+' is
// a trick to cast it as a number
total += +hidden_input;
}
console.log(id, id_number, hidden_input, total);
});
// We've processed all inputs and have a total, update our page with
// the result
$('#total').html(total);
});
Done!
The above works fine, but here are some suggestions for minor improvements:
1) Use for on your labels, so that clicking on the text will also toggle the checkbox.
2) It is good practice to cache your jQuery selectors, otherwise jQuery has to parse the DOM each time to look for them. That's trivially unimportant in this example, but it is good practice to get into so you won't get bitten by problems as your pages get more complex.
3) It is good practice to separate your JS code into smaller chunks, so eg have a function that sums up the price, and a separate event handler which simply calls that when an option is changed.
Putting all that together, here's updated code:
<!-- Just one for example -->
<div>
<input type="checkbox" class="option" id="option_1" name="option_1" value="1" checked>
<input type="hidden" value="1" class="option_price_1">
<label for="option_1">Orange</label>
<label>1</label>
</div>
And now the JS:
// Cache your selectors
var $options = $('.option'),
$total = $('#total');
// Event handler, with callable function
$options.on('change', sumInputs);
function sumInputs() {
var id, id_number, hidden_input, price = 0;
$options.each(function(index) {
id = $(this).attr('id');
id_number = id.split("_")[1];
hidden_input = $(".option_price_" + id_number).val();
if ($(this).prop('checked')) {
price += +hidden_input;
}
console.log(id, id_number, hidden_input, price);
});
$total.html(price);
}

how do I check dynamically generated radio input value

I have to generate multiple input fields dynamically for each time user clicks "add" button and I was successfully able to get them. Each contact should have this radio input field in different different name so I've created a name in an array form.
Here's what I have so far and I wonder how I'm supposed to get the radio value for each person:
var options = '';
var count = 0;
var maxfields = 4;
$('button#add').click(function() {
options = '<p>Visit Type:
<label class="radio-inline">
<input type="radio" class="c_visittype' + count +'" name="c_visittype[]" value="Student" required>Student</label>
<label class="radio-inline">
<input type="radio" class="c_visittype' + count +'" name="c_visittype[]" value="Visitor" required>Visitor</label> </p>';
if(count < maxfields){
count++;
$(options).fadeIn("slow").appendTo('.companion');
return false;
}
});
$('.c_visittype' + count).on('click', function(){
$('input:radio[name="c_visittype"]').attr('checked', 'checked');
});
Each person should get a choice of either 'student' or 'visitor' and I have to get this value for multiple persons whenever more person fields created.The reason why I put field's name as an array is to iterate it in the next page by php.
<script src="http://code.jquery.com/jquery-2.2.4.min.js" integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44=" crossorigin="anonymous"></script>
<script>
$( document ).ready(function() {
var options = '';
var count = 0;
var maxfields = 4;
$('button#add').click(function() {
var options = '<p style="display: none">Visit Type:<label class="radio-inline"> <input type="radio" class="c_visittype' + count +'" name="c_visittype' + count +'[]" value="Student" required>Student</label> <label class="radio-inline"><input type="radio" class="c_visittype' + count +'" name="c_visittype' + count +'[]" value="Visitor" required>Visitor</label> </p>';
if(count < maxfields){
count++;
$('.companion').append(options);
$(".companion p:last").fadeIn();
}
});
});
</script>
<button id="add">add</button>
<div class="companion">
</div>
$('input[name=c_visittype[]]:checked').val();
That's how you access the value of a checked radio button with jQuery.
var inputValues = [];
$('.c_visittype:checked').each(function() {
inputValues.push($(this).val());
});
// Your code using inputValues
For update on changes:
$(function() {
$('.c_visittype').click(function(){
// Insert code here
}
)});
Make sure to move the numbering from the class attribute to the name attribute (like it was, everything was part of the same set of options). Also, put the whole string on 1 line.

JavaScript Validation For Checkbox, When Multiple checkbox selected from option list

I want to do JavaScript validation for Checkbox
If Value from Checkbox is not selected, it should get alert "Please Select Languages You Know"
But if user select 2 Languages from list of checkbox. I need that 2 languages should get alert using JavaScript.
I know to do with single checkbox, but not getting how to do using array.
Here is my Code...
<script type="text/javascript">
function myFunction(form){
var i,
chks = document.getElementsByName('lang[]');
for (i = 0; i < chks.length; i++){
if (chks[i].checked){
//Here how i should alert selected values
return true;
}else{
alert('No item selected');
return false;
}
}
}
</script>
<form name="registration" id="registration_form_id" action="" method="post" onsubmit="return myFunction(this)">
<div id="languageId"><label>Language : </label>
<input type="checkbox" name="lang[]" value="english" >English</input>
<input type="checkbox" name="lang[]" value="marathi">Marathi</input>
<input type="checkbox" name="lang[]" value="hindi">Hindi</input>
</div>
<div id="submit1"><button type="submit">Submit</button></div><br/>
</form>
Thank You,
Rahul
If you want to get the list of selected checkbox values.. you can use this..
$('#someButton').click(function() {
var values= [];
$('#MyDiv input:checked').each(function() {
values.push(this.val);
});
// now values contains all of the values of checked checkboxes
// do something with it
});
If you only need one selected value, it's easier to use a radio input type. With it, you can find the selected value using a querySelector (see MDN). For multiple languages, you can also use querySelectorAll, convert its results to an Array and use Array.map (see MDN) to map the results into an Array of the values of the checked checkboxes.
Here's your snippet rewritten for both cases (without a form):
(function (d, w, undefined) {
d.querySelector('#languageId button').addEventListener('click', doSubmit);
d.querySelector('#multiLanguageId button').addEventListener('click', doSubmitMulti);
var languageSelectorContainer = d.querySelector('#languageId');
var multiLanguageSelectorContainer = d.querySelector('#multiLanguageId');
function doSubmit() {
var languageChecked = languageSelectorContainer
.querySelector('[type=radio]:checked');
d.querySelector('#result').innerHTML =
'your selected language: <b>'+
(languageChecked
? languageChecked.value
: 'not yet selected') +
'</b>';
}
function doSubmitMulti() {
var languagesChecked = [].slice.call(
multiLanguageSelectorContainer
.querySelectorAll('[type=checkbox]:checked') )
.map(function (v){
return v.value;
});
d.querySelector('#result').innerHTML =
'you selected these language(s): <b>'+
(languagesChecked.length
? languagesChecked.join(', ')
: 'none yet selected') +
'</b>';
}
}(document, window))
<div id="languageId">Pick your language:
<input type="radio" name="lang[]" value="english">English
<input type="radio" name="lang[]" value="marathi">Marathi
<input type="radio" name="lang[]" value="hindi">Hindi
<button>Submit</button>
</div>
<div id="multiLanguageId">Pick the languages you know:
<input type="checkbox" name="mlang[]" value="english">English
<input type="checkbox" name="mlang[]" value="marathi">Marathi
<input type="checkbox" name="mlang[]" value="hindi">Hindi
<button>Submit</button>
</div>
<div id="result"></div>

Select at least 1 checkbox in a loop of checkboxes group

I'm trying to get this thing work for a while but I guess I need to tweak the code from somewhere. I thought, someone here could better guide me instead of banging my head to my coding screen :)
here's the actual process:
<input type="hidden" name='oneSelectionChk_1'>
<input type="checkbox" name='awp_group_1' id='id1'>
<input type="checkbox" name='awp_group_1' id='id2'>
<input type="checkbox" name='awp_group_1' id='id3'>
<input type="checkbox" name='awp_group_1' id='id4'>
<input type="hidden" name='oneSelectionChk_2'>
<input type="checkbox" name='awp_group_2' id='id5'>
<input type="checkbox" name='awp_group_2' id='id6'>
<input type="checkbox" name='awp_group_2' id='id7'>
<input type="checkbox" name='awp_group_2' id='id8'>
<input type="hidden" name='oneSelectionChk_3'>
<input type="checkbox" name='awp_group_3' id='id9'>
<input type="checkbox" name='awp_group_3' id='id10'>
<input type="checkbox" name='awp_group_3' id='id11'>
<input type="checkbox" name='awp_group_3' id='id12'>
what I'm using for jQuery is:
var chkFields = $("input[name='oneSelectionChk']");
$.each(chkFields, function(i, field){
var groupID = field.id.split('_'); // Getting the ID of the group
var chkGroupBoxes = $('input[name="awp_group_"'+groupID[1]);
if(field.value==1)
{
//$.each(chkGroupBoxes, function(j, thisChkBox){
//alert(thisChkBox.value + " #"+j);
alert( $('input[name="awp_group_"'+groupID[1]).filter(':checked').length);
if($('input[name="awp_group_"'+groupID[1]+':checked').length > 0 )
{
//$.scrollTo( '#awp_container', 1200 );
alert($('input[name="awp_group_"'+groupID[1]+':checked').length+" Selected ");
//alert( "Class AlertMsgText Should be removed Now");
$("#selectInstruction_"+groupID[1]).removeClass("AlertMsgText");
//return
}
else
{
alert($('input[name="awp_group_"'+groupID[1]+':checked').length+" Still not selected ");
//alert("Please select atleat 1 from Option #"+groupID[1]);
$("#selectInstruction_"+groupID[1]).addClass("AlertMsgText");
$.scrollTo( '#awp_container', 1200 );
//return;
}
//});
}
});
This code always giving me 0 length of checkboxes, I'm not sure if I need to loop through again for each checkbox or this might work?
Any quick help should be appreciated!
Try
var chkFields = $('input[name^="oneSelectionChk"]');
$.each(chkFields, function (i, field) {
var groupID = field.name.replace('oneSelectionChk_', '')
var chkGroupBoxes = $('input[name="awp_group_' + groupID + '"]');
if (chkGroupBoxes.filter(':checked').length == 0) {
alert('please select at least one checkbox under: ' + field.name)
}
});
Demo: Fiddle
There is no element with name attribute of oneSelectionChk in your markup, the hidden inputs have name attributes that start with oneSelectionChk, you have to use attribute starts with selector.
In case that elements are siblings you can select the target elements using .nextUntil() method:
var $hidden = $('input[type=hidden]').filter('[name^=oneSelectionChk]');
$hidden.each(function(){
var $chekboxes = $(this).nextUntil('input[type=hidden]'),
$checked = $checkboxes.filter(':checked'),
$unchecked = $chekboxes.not($checked);
});
Using name attributes:
var $hidden = $('input[type=hidden]').filter('[name^=oneSelectionChk]'),
$checkboxes = $('input[type=checkbox]');
$hidden.each(function() {
var n = this.name.split('_')[1];
var $grp = $checkboxes.filter('[name="awp_group_'+ n +'"]');
// ..
});

Update price after checkbox is selected

I have a fairly simple problem (I think) that involves updating a number using jQuery. I have a DIV that holds a price for an item. Users can select a checkbox to add on to the total price. What I need is when someone clicks on a checkbox, it will add the correct amount to the DIV. When a user un-checks a checkbox, the value is subtracted. Here is my code so far:
<div class="cell">
<div class="check">
<input id="check-0" type="checkbox" />
<label for="check-0">$100</label>
<div class="mask"></div>
</div>
</div>
<div class="price">$347</div>
Any help is greatly appreciated!
Hopefully this is something that you could use or help you:
http://jsfiddle.net/VWRAd/
$(".cell").on("click", "input:checkbox", function () {
var $this = $(this);
var $total = $("#price");
var $target = $("label[for='" + $this.attr("id") + "']");
var item_value = +($target.html().replace("$", "") || 0);
var cur_total = +($total.html().replace("$", "") || 0);
if ($this.prop("checked") === true) {
cur_total += item_value;
} else {
cur_total -= item_value;
}
$total.html("$" + cur_total);
});
Although notice that I changed the element with the class of "price" to have an id of "price". It just makes sense, unless you expect to have several "price" elements.
And here is another possible way of doing it...not sure which is better:
http://jsfiddle.net/VWRAd/1/
$(".cell").on("click", "input:checkbox", function () {
var $items = $(".cell").find("input:checkbox:checked");
var $total = $("#price");
var cur_total = 0;
$items.each(function () {
var $this = $(this);
var $target = $("label[for='" + $this.attr("id") + "']");
var item_value = +($target.html().replace("$", "") || 0);
cur_total += item_value;
});
$total.html("$" + cur_total);
});
Some things to consider - it makes sense to separate the "$" from the actual value of the item when displaying it...I'm sure you aren't storing the value with "$", so you might want a structure similar to <label for="whatever">$<span class="the-value">100</span></label>. It would change your jQuery selector logic a little bit, but it would prevent the need for using .replace so often. Also, as someone else already pointed out, it would definitely be easier to store the item's price in the checkbox's value attribute and retrieve it that way (instead of finding the corresponding <label>'s content.
var changePrice = function changePrice(amt, state){
var curPrice = $('.price').text();
curPrice = curPrice.substring(1, curPrice.length);
if(state==true){
curPrice = parseInt(curPrice) + parseInt(amt);
}else{
curPrice = parseInt(curPrice) - parseInt(amt);
}
curPrice = '$' + curPrice;
$('.price').text(curPrice);
}
$(function(){
$('#check-0').on('change', function(){
var itemPrice = $('label[for="check-0"]').text();
itemPrice = itemPrice.substring(1, itemPrice.length);
changePrice(itemPrice, $('#check-0').is(':checked'));
});
})​;​
Demo: http://jsfiddle.net/pratik136/r2Snu/
Even though these may not be form controls intended to hit the server, i would still put the value attribute for each of the inputs.
So for the 'check-0' input, i'd put in a value attribute of 100 (to represent the $100).
Then, a bit of javascript logic should make it easy to update the price value.
So something like this should do it (http://jsbin.com/orodow/1/edit):
<div class="cell">
<div class="check">
<input id="check-0" type="checkbox" value="100" />
<label for="check-0">$100</label>
<div class="mask"></div>
</div>
</div>
<div class="cell">
<div class="check">
<input id="check-1" type="checkbox" value="50" />
<label for="check-1">$50</label>
<div class="mask"></div>
</div>
</div>
<div class="cell">
<div class="check">
<input id="check-2" type="checkbox" value="20" />
<label for="check-2">$20</label>
<div class="mask"></div>
</div>
</div>
<div class="price"></div>
<script>
$(function(){
var inputs = $('.check input:checkbox');
function updatePrice(){
var value = 0;
inputs.filter(':checked').each(function(){
value += parseInt($(this).val(), 10);
});
$('.price').html('$' + value);
}
inputs.change(updatePrice);
});
</script>

Categories