I have three checkboxes which have a class name of (names). I am trying to say if the checkbox is checked log the value to the console.
if( $('.names').is(':checked') ){
console.log($('.names').val());
}else{
console.log('null');
}
However, this is only logging the first value to the console (when there is more than one ticked).
Do i need to create an array and log that?
The getter version of val() will return the value of the first element only.
One solution is to get an array of all the checked values and print it
var checked = $('.names:checked').map(function() {
return this.value;
}).get();
if (checked.length) {
console.log(checked);
} else {
console.log('null');
}
While you have a correct answer posted already, it's worth noting that jQuery is not required for this to be 'easy'; it's quite possible in vanilla JavaScript:
// creating a named function to handle the change-event (later):
function logToConsole() {
// retrieves a collection of elements that match the CSS selector:
var checked = document.querySelectorAll('input[type=checkbox].names:checked'),
// converts the collection to an Array:
values = Array.prototype.slice.call(checked, 0)
// map iterates over the Array returned by
// Array.prototype.slice():
.map(function(checkbox) {
// checkbox is the Array Element itself:
// returning the value of the checked checkbox:
return checkbox.value;
});
// if the collection has a length other than 0:
if (checked.length) {
// outputs the array of values to the console:
console.log(values);
}
}
document.querySelector('form').addEventListener('change', logToConsole);
<form action="#" method="post">
<fieldset>
<legend>Check any of the check-boxes to see the values of those check-boxes logged to the console</legend>
<label>value: 3
<input value="3" class="names" type="checkbox" />
</label>
<label>value: 4
<input value="4" class="names" type="checkbox" />
</label>
<label>value: 5
<input value="5" class="names" type="checkbox" />
</label>
<label>value: 6
<input value="6" class="names" type="checkbox" />
</label>
</fieldset>
</form>
Vanilla Javascript solution:
[].forEach.call(document.querySelectorAll('.names:checked'), function (cb) {
console.log(cb.value);
});
And if you wan't that for older browsers as well:
var cbs = document.querySelectorAll('.names:checked');
for(var i = 0; i < cbs.length; i++)
console.log(cbs[i].value);
Related
While creating quiz app I got stuck on one problem:
If the user selects the radio button I want to push its value into an empty array and if the user selects none I want to push a single empty string to an array without breaking the indexing chain.
I tried this using a for...of loop:
When I select the radio the array gets full of values like this: ["value"," "," "," "]
When I select none it gets filled like this: [" "," "," "," ]
I know the problem but don't know how to fix it.
for(let option of allOptions){
if(option.checked){
selectedAnswer.push(option.value);
}
if(!option.checked){
selectedAnswer.push(" ")
}
}
For Single Option :-
// lets target all the radio button
let options = document.getElementsByName("option");
// suppose option 1 has clicked
options[0].checked = true
// initiate our checked option with an array containing a empty string
let checkedOpttion = [""];
for( i = 0; i < options.length; i++ ) {
if( options[i].checked ) {
// if an option has clicked insted of pushing value we are gonna reset the variable with a new array containg that options value
checkedOpttion = [options[i].value]
}
}
console.log(checkedOpttion)
<input type="radio" name="option" value="01" >
<label for="male">option 1</label><br>
<input type="radio" name="option" value="02">
<label for="female">option 2</label><br>
<input type="radio" name="option" value="03">
<label for="female">option 3</label><br>
<input type="radio" name="option" value="04">
<label for="female">option 4</label><br>
For Multiple Option
// lets target all the radio button
let options = document.getElementsByName("option");
// suppose option 1 and option 2 has clicked
options[0].checked = true
options[1].checked = true
// initiate our checked option with an array
let checkedOpttion = [];
for( i = 0; i < options.length; i++ ) {
if( options[i].checked ) {
checkedOpttion.push(options[i].value)
}
}
// If you want to push an empty string if none the option checked then
if(checkedOpttion.length === 0){
checkedOpttion.push("")
}
// if you dnn't want comment the above one if clause
console.log(checkedOpttion)
<input type="checkbox" id="01" name="option" value="01" >
<label>option 1</label><br>
<input type="checkbox" name="option" value="02" id="02" >
<label>option 2</label><br>
<input type="checkbox" name="option" value="03" id="03" >
<label>option 3</label><br>
<input type="checkbox" name="option" value="04" id="04" >
<label>option 4</label><br>
I think Array.splice will be wonderful for your case, because it will allow you to swap existing values inside the array in one single action.
Just pass along the index to your callback function
To add a "value" to any index in the array
selectedAnswer.splice(index, 1, "value");
and to remove
selectedAnswer.splice(index, 1, "");
Notice that calling .splice will modify the original array and will return any of the removed values from the array.
Example:
// HTML
<input type="checkbox" id="cb">
// JS
document.getElementById("cb").addEventListener('change', function(event) {
if (event.currentTarget.checked) {
selectedAnswer.splice(index, 1, "value");
} else {
selectedAnswer.splice(index, 1, "");
}
});
Maybe will help use else instrad second if
if(option.checked){
selectedAnswer.push(option.value);
} else {
selectedAnswer.push(" ")
}
Hi I'm making a website that has a user order a pizza. I am using a form to collect all the data and am having troubles with my JavaScript.
<input class="customCheckbox" type="checkbox" name="cheeseCheckbox" value="cheese" onclick="toppingAddedRemoved(this.form)" />Cheese<br />
<input class="customCheckbox" type="checkbox" name="pepperoniCheckbox" value="pepperoni" />Pepperoni<br />
<input class="customCheckbox" type="checkbox" name="hamCheckbox" value="ham" />Ham<br />
<input class="customCheckbox" type="checkbox" name="pineappleCheckbox" value="pineapple" />Pineapple<br />
This is the relevant HTML that I am trying to get data from. I'm currently only testing with the first input.
function getToppings(form){
var toppingsNames = new Array("cheeseCheckbox", "pepperoniCheckbox", "hamCheckbox");
var toppings = new Array();
var numberOfToppings = 0;
var i;
// writeToDIV(form.cheeseCheckbox.checked);
for (i in toppingsNames){
if (form.toppingsNames[i].checked === true){
toppings.push(form.toppingsNames[i].value);
numberOfToppings++;
}
}
// if (form.cheeseCheckbox.checked === true){
// toppings.push(form.cheeseCheckbox.value);
// numberOfToppings++;
// }else if (form.Checkbox.checked === true)
// writeToDIV(toppings + numberOfToppings);
}
My JavaScript here at the bottom with the if statement is working but that would be tedious set if statements for all of my checkboxes.
My thought was to use a for loop that that replaces the name in the code
form.INPUTNAME.checked
with form.toppingsNames[i].input.
This however doesn't seem to work. Does anyone have any suggestions on how I can loop this? Thanks.
Simpler way to do this would be to give the checkboxes all the same name. That way you can select the checkboxes from the markup without recreating them in the js. Since they are all the same name, you can simply grab the checkboxes that are checked and loop through those.
This will also make it easier when submitting your form to the server since languages like PHP will be able to read the values based on the name. (In this case $_POST['toppings'])
function saveToppings() {
var checkedToppings = document.querySelectorAll("input[name='toppings']:checked");
var usersToppings = [];
for(i = 0; i < checkedToppings.length; i++) {
usersToppings.push(checkedToppings[i].value);
}
if(usersToppings.length < 1) {
document.getElementById('savedToppings').innerHTML = 'No toppings selected';
} else {
document.getElementById('savedToppings').innerHTML = usersToppings;
}
}
(function(){
document.getElementById('save').addEventListener('click', saveToppings);
})();
<input class="customCheckbox" type="checkbox" name="toppings" value="cheese" />Cheese<br />
<input class="customCheckbox" type="checkbox" name="toppings" value="pepperoni" />Pepperoni<br />
<input class="customCheckbox" type="checkbox" name="toppings" value="ham" />Ham<br />
<input class="customCheckbox" type="checkbox" name="toppings" value="pineapple" />Pineapple<br />
<button id="save">Save toppings</button>
<div id="savedToppings"></div>
First, I'll explain why your current code doesn't work.
The error stems from the toppingsNames[i] in form.toppingsNames[i]
This is being interpreted as an attempt to get the index i of an array named toppingsNames that is a property of the object form, however form has no such property.
I have some example code to help explain.
var foo = {"a": 1, "b": 2, "c": 3};
var bar = ["a", "b", "c"];
//The following will cause TypeError: Cannot read property '1' of undefined
//It will not output 2
console.log(foo.bar[1]);
//This will output '2'
console.log(foo.b)
//Instead, access the value like this
//This will output '2'
console.log(foo[bar[1]]);
form[toppingsNames[i]] should output a property of form named toppingsNames[i]'s value, which is what you are looking for.
form[toppingsNames[i]].value should evaluate to either true or false
I am trying to make "toggle checkboxes" function, as below:
HTML Code:
<!-- "Check all" box -->
<input type="checkbox" name="check" id="cbx_00_00" onclick="selectbox( this.getAttribute( 'id' ));" />
<!-- the other ones -->
<input type="checkbox" name="check" id="cbx_00_01" />
<input type="checkbox" name="check" id="cbx_00_02" />
<input type="checkbox" name="check" id="cbx_00_03" />
JavaScript:
function selectbox( eID ) {
// instead of writing the element id in the html code,
// i want to use "this.getAttribute( 'id' )"
var c = document.getElementById( eID );
// now when we've got the id of the element,
// let's get the required attribute.
var box = c.getAttribute( 'name' );
// set var i value to 0, in order to run "for i" loop
var i = 0;
for(i; i < box.length; i++) {
// now lets find if the main box (as box[0]) checked.
// if returns true (it has been checked), then check all - else -
// do not check 'em all.
if(box[0].checked == true) {
box[i].checked = true;
}
else {
box[i].checked = false;
}
}
}
I don't want any jQuery solution (even if it can be easier than pure js), so please avoid suggesting it. All I want to know is - If I'm wrong - what do you think I should do to solve this?
Thank you very much. every suggestion/tip is appreciated.
Your problem mainly seems to be that you are iterating over the checkbox name, not the checkboxes with that name.
var box = c.getAttribute( 'name' );
Now, box is equal to "check", so box[0] is "c", box[1] is "h" etc.
You need to add this:
var boxes = document.getElementsByName(box);
And then iterate over boxes.
Of course, at that point, you may want to rename your variables too.
Given the name in the variable box, you can check all boxes with the same name like this:
Array.prototype.forEach.call(document.getElementsByName(box), function(el) {
el.checked = true;
});
(Array.prototype.forEach.call is used to loop over the "fake-array" returned by getElementsByName because the NodeList class doesn't have forEach.)
I think you can further simply your code by not passing the element's ID to your function, but directly the name (selectbox(this.name)). Also note that you can access ID and name using .id and .name instead of using getAttribute.
You can make it simple.
HTML Code:
input type="checkbox" name="check" id="cbx_00_00" onclick="selectbox(this.getAttribute('name'));" />
<input type="checkbox" name="check" id="cbx_00_01" />
<input type="checkbox" name="check" id="cbx_00_02" />
<input type="checkbox" name="check" id="cbx_00_03" />
Javascript:
function selectbox(eID) {
var checkBoxes = document.getElementsByName(eID);
for (var i = 0; i < checkBoxes .length; i++) {
if (checkBoxes[0].checked) {
checkBoxes[i].checked = true;
}
else {
checkBoxes[i].checked = false;
}
}
}
I have a checkbox in a form that acts as a flag.
In order to do it, I added a hidden input element so that if the checkbox is not checked, something will still be saved
<form action="">
...
<input type="hidden" name="foo" value="no" />
<input type="checkbox" name="foo" value="yes">
...
</form>
The problem I am having is that when I
check the checkbox
then run jQuery.serializeArray() on the form
the value set for the foo element is "no"
Object { name="foo", value="no"}
Shouldn't serializeArray() emulate browser behaviour? If so, shouldn't it return "yes" if checkbox is checked?
I am using jQuery v1.10.2
In a short word: No. The serializeArray method only returns the checkbox in the case it is checked. Thus, it will ignore it as long as it remains unchecked.
In case you checked it, though, it wiill return the value of your input directly.
Check out the demo at http://api.jquery.com/serializearray/ .
Using serializeArray on a form with multiple inputs of the same name returns more than one object for each element (if checked). This means that the following HTML will return the following object. So the data in question is there and is available. Because of this I'm assuming that you're attempting to either manipulate the data to be in 1 object or you're posting it to a server which is only taking into account the data from the first value with that key. You just need to make sure that any checkbox element takes precedence.
Returned Object:
[
{
name:"foo",
value:"no"
},
{
name:"foo2",
value:"no"
},
{
name:"foo2",
value:"yes"
}
]
HTML:
<form>
<input type="hidden" name="foo" value="no" />
<input type="checkbox" name="foo" value="yes" />
<input type="hidden" name="foo2" value="no" />
<input type="checkbox" name="foo2" value="yes" checked />
</form>
JS:
console.log($('form').serializeArray());
DEMO
Another way you can do this is get rid of the hidden fields and before you submit the form go through each unchecked checkbox and check if there is any data in the serializeArray with the same name. If not just add it in there as a off.
$('#submit').on('click', function(){
var arr = $('form').serializeArray(),
names = (function(){
var n = [],
l = arr.length - 1;
for(; l>=0; l--){
n.push(arr[l].name);
}
return n;
})();
$('input[type="checkbox"]:not(:checked)').each(function(){
if($.inArray(this.name, names) === -1){
arr.push({name: this.name, value: 'off'});
}
});
console.log(arr);
});
DEMO
Using the same name for multiple fields is problematic at best and there is no standardized way that front end systems, or back end systems, will handle it.
The only reason to use the same name is if you are trying to pass some kind of a default value, like you are in the case below, where you are doing a simple yes/no.
What you want, to emulate the browser, is serialize method, not the serializeArray.
I added the form to a page -- from my console:
JSON.stringify(f.serializeArray());
"[{"name":"foo","value":"no"}]"
NO checkmark
JSON.stringify(f.serialize());
""foo=no""
Checkmark
JSON.stringify(f.serialize());
""foo=yes&foo=no""
If your back end system gets confused and is picking up the wrong value, reverse the order of your checkmark and hidden element.
FACT: jQuery serializeArray() does not include unchecked checkboxes that probably we DO need them sent to server (no problem for radios though).
SOLUTION: create a new serialize:
//1. `sel` any collection of `form` and/or `input`, `select`, `textarea`
//2. we assign value `1` if not exists to radios and checkboxes
// so that the server will receive `1` instead of `on` when checked
//3. we assign empty value to unchecked checkboxes
function serialize(sel) {
var arr,
tmp,
i,
$nodes = $(sel);
// 1. collect form controls
$nodes = $nodes.map(function(ndx){
var $n = $(this);
if($n.is('form'))
return $n.find('input, select, textarea').get();
return this;
});
// 2. replace empty values of <input>s of type=["checkbox"|"radio"] with 1
// or, we end up with "on" when checked
$nodes.each(function(ndx, el){
if ((el.nodeName.toUpperCase() == 'INPUT') && ((el.type.toUpperCase() == 'CHECKBOX') || (el.type.toUpperCase() == 'RADIO'))){
if((el.value === undefined) || (el.value == ''))
el.value = 1;
}
});
// 3. produce array of objects: {name: "field attribute name", value: "actual field value"}
arr = $nodes.serializeArray();
tmp = [];
for(i = 0; i < arr.length; i++)
tmp.push(arr[i].name);
// 4. include unchecked checkboxes
$nodes.filter('input[type="checkbox"]:not(:checked)').each(function(){
if(tmp.indexOf(this.name) < 0){
arr.push({name: this.name, value: ''});
}
});
return arr;
}
The reason we assigned empty string to unchecked checkboxes is because a checked one will submit it's value to server which is set in html and can be a zero!!!
So, an empty value denotes a unchecked checkbox.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<form url="http://application.localdev/api/v1/register" method="post" id="formReg" accept-charset="utf-8">
<input type="email" placeholder="email" name="email"><br>
<input type="text" placeholder="firstname" name="firstname"><br>
<input type="text" placeholder="lastname" name="lastname"><br>
<input type="number" placeholder="zip_code" name="zip_code"><br>
<input type="checkbox" name="general" value="true"> general<br>
<input type="checkbox" name="marketing" value="true"> marketing<br>
<input type="checkbox" name="survey" value="true"> survey<br>
<button type="submit">save</button>
</form>
<script>
$(document).ready(function() {
$('#formReg').on('submit', function(e){
// validation code here
e.preventDefault();
var values = {};
$.each($('#formReg').serializeArray(), function(i, field) {
values[field.name] = field.value;
});
$('input[type="checkbox"]:not(:checked)').each(function(){
if($.inArray(this.name, values) === -1){
values[this.name] = $(this).prop('checked')
}
});
console.log(values)
});
});
</script>
serializeArray doesn't return unchecked checkbox. I try this instead of serializeArray:
$('input, select, textarea').each(
function(index){
var input = $(this);
alert('Type: ' + input.attr('type') + 'Name: ' + input.attr('name') +
'Value: ' + input.val());
}
);
I have several checkboxes and a fake submit button to make an AJAX request:
<form>
<input type="checkbox" value="1"/>
<input type="checkbox" value="2" checked="checked"/>
<input type="checkbox" value="3"/>
<input type="checkbox" value="4" checked="checked"/>
<input type="button" onclick="return mmSubmit();"/>
</form>
Within the mmSubmit() method, I would like to retrieve an array of values that have been selected. Here is what I am currently doing.
mmSubmit = function() {
var ids = [];
$('input[type=checkbox]:checked');.each(function(index) {
ids.push($(this).attr('value'));
});
// ids now equals [ 2 , 4 ] based upon the checkbox values in the HTML above
return false;
};
I'm wondering if there is a shorthand method in jQuery used to retrieve the values into an array, or if what I have is already optimal.
I think this can be accomplished with map. Try the following..
mmSubmit = function() {
var ids = $('input[type=checkbox]:checked').map(function(){
return $(this).val();
}).get();
// ids now equals [ 2 , 4 ] based upon the checkbox values in the HTML above
return false;
};
Take a look at: jQuery Traversing/Map
Well you can use .val() instead of .attr('value').
$.serializeArray() may also do what you want (http://docs.jquery.com/Ajax/serializeArray).
It's needs some optimization, buts generally it is right way. My variant:
mmSubmit = function () {
var ids = [];
$('input[type=checkbox]').each(function () {
if (this.checked) {
ids[ids.length] = this.value;
}
});
return ids;
};
It's little faster.