I would like to catch the value of a checkbox when the value changes and then send it through Ajax.
There are several hundred of checkboxes displayed in my HTML page, so I cannot simply send all the values when one value changes. I only want to send the value of the checkbox that just changed.
Here is my HTML code :
<INPUT type="checkbox" name="cb_redir301" value="post_id_445">
<INPUT type="checkbox" name="cb_redir301" value="post_id_573">
<INPUT type="checkbox" name="cb_redir301" value="post_id_264">
<INPUT type="checkbox" name="cb_redir301" value="post_id_387">
<INPUT type="checkbox" name="cb_redir301" value="post_id_190">
(...)
<INPUT type="checkbox" name="cb_redir301" value="post_id_268">
I tried the following Javascript to catch and send the value, but it doesn't work, probably because the name of the checkbox ('cb_redir_301') is not unique.
$('#redir_selector').change(function(evt) {
$.post(ajaxurl, {
action: 'save_backend_assocs',
nonce: $('#ajax_admin_redir_selector_nonce').text(),
cb_redir301: $(this).is(':checked')
}, function(response) {
});
});
});
So, how can I told JS to only send the value of the checkbox that has been changed?
Faster:
var checkboxes = document.querySelectorAll("input[type='checkbox']");
for(var i = 0 ; i < checkboxes.length ; i++) {
checkboxes[i].addEventListener("change", updateData);
}
Just found a solution through:
$("input[type='checkbox']").on("change",function(){
console.log($(this).val());
It should work now.
Ken.
Related
There are checkboxes, which belong to Form A:
<input type="checkbox" class="item-selector" name="item[]" value="1" />
<input type="checkbox" class="item-selector" name="item[]" value="2" />
<input type="checkbox" class="item-selector" name="item[]" value="3" />
<!-- etc. -->
Then I have Form B that needs the checkbox values from Form A. Form A might have other input fields too, but I'm not interested in those. I only care about $('input.item-selector'). I'm going about it like this:
var postData = $('#form-a').serializeArray();
var items = $('.item-selector:checked').map(function(){
return this.value;
}).get();
if(items.length > 0) {
postData.push({name: 'itemId', value: items});
}
But this way of adding stuff to the postData doesn't seem to work, because the PHP script I send the form to can not find the itemId. Interestingly this does work:
postData.push(name: 'aName', value: 'notAnArrayButAStringValue');
I also tried a couple of solutions like this one: http://benalman.com/projects/jquery-misc-plugins/#serializeobject but the problem with them is that, while they otherwise work fine, for some reason if there are checkboxes in Form B, the checkbox values of Form B are parsed incorrectly and result in null values and loss of data. That would look like this:
var postData = $(this.form).serializeObject();
var items = $('.item-selector:checked').map(function(){
return this.value;
}).get();
if(items.length > 0) {
postData.itemId = items;
}
Using JSON.stringify revealed the object structure to be like this:
{
"name":"Simon J. Kok",
"address_id":"39669",
"email":"*****",
"content_id":"21921",
"client_id":"42101",
"is_ebill":["","1"], <-- this is a checked checkbox
"is_banned":"", <-- this is an unchecked checkbox
"button":"save"
}
The checkboxes in Form B look like
<input type="checkbox" value="1" name="is_ebill" />
<input type="checkbox" value="1" name="is_banned" />
So what I need is either some insight on how to add the checkboxes from Form A to the $.serializeArray() result array -OR- a way to solve the issue of a checked checkbox returning an array when using Ben Alman's plugin.
Here's one approach. First it requires a hidden field in form-b:
<input type="hidden" id="itemId" name="itemId" value="" />
This would be populated with the item-selector data when the form is submitted:
$('#form-b').on('submit', function() {
var checkedValues = [];
$('.item-selector:checked').each(function() {
checkedValues.push($(this).val());
});
$('#itemId').val(checkedValues.join(','));
console.debug('Form B data:', $('#form-b').serializeArray());
});
Adjust the syntax to suit your idiom. Here's a fiddle to demonstrate:
http://jsfiddle.net/klenwell/12evxfvc/
Actually I kinda answered my own question already when I asked it. I used JSON.Stringify to output the JSON formatted string of what $.serializeArray() returned and it became apparent what the structrure needed to work. So here is how to add array values one by one to an array retrieved using $.serializeArray():
var items = $('.item-selector:checked').map(function(){
return this.value;
}).get();
$.each(items, function(i, v){
postData.push({name: 'itemId[]', value: v});
});
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 a photo gallery. Underneath each photo is a checkbox, with the ID containing a prefix of 'checkbox_', followed by the photo ID.
<input type="checkbox" id="checkbox_<%=photoID%>" name="photos">
When I check a 'selectAll' checkbox, like this one:
<input type="checkbox" id="toggleAll" name="toggleAll" onclick="toggleAll()">
I want to check/uncheck all checkboxes that have the name 'photos', so I have this function that should do that... but it doesn't:
function toggleAll() {
if (document.getElementById('toggleAll').checked == true)
{
$('.photoBlob').animate({backgroundColor: 'rgba(0,102,204,0.5)'}, 500);
$('.photoBlob').animate({backgroundColor: 'rgba(204,204,204,1)'}, 1500);
document.getElementByName('photos').checked = true;
}
else
{
$('.photoBlob').animate({backgroundColor: 'rgba(0,0,0,0)'}, 1000);
document.getElementByName('photos').checked = false;
}
}
The rest of the function works okay, it animates the background colors of the containing DIV (#photoBlob) when the toggleALL() function is called. But, I really can't get all the checkboxes to check and I have tried so many different variations!
Can anybody see what I am doing wrong? The problem lies with these two lines:
document.getElementByName('photos').checked = true;
document.getElementByName('photos').checked = false;
Any suggestions gratefully received...
You can do like this,
don't use same name for several check boxes because the name shroud be unique. Instead of use the class.
<input type="checkbox" id="checkbox_<%=photoID%>" class="photos">
an the jquery,
$('#toggleAll').click(function(){
var checked =$(this).attr('checked');
$('.photos').attr('checked', checked);
}
$('#toggleAll').click(function(){
$(':checkbox[name="photos"]').prop('checked',this.checked);
});
Fiddle demo: http://jsfiddle.net/uNeX2/
I think you're missing an "s" in getElementByTagName. Try getElementsByTagName.
This might also work:
$("#toggleAll").click(function() {<br/>
$("input[name='photos']").attr("checked",!!$(this).attr("checked"));
});
well, since you said, you have multiple checkboxes with the name 'photos', selecting only one element by using the function getElementByName, can't be ur choice of game. Using jQuery simplifies the task your trying to do;
$("input[name=photos]").each(function(elem){
elem.checked=true;
}
or simpler;
$("input[name=photos]").attr('checked','checked');
its its js-only, youd need to select all input elements via getElementsByTagName and then filter out the ones that don't comply with having a name of 'photos'.. and then do your task.
Here is simple example using jQuery:
html
<input type="checkbox" id="all" >
<input type="checkbox" name="photo" >
<input type="checkbox" name="photo" >
<input type="checkbox" name="photo" >
<input type="checkbox" name="photo" >
js
$('#all').click(function() {
if ($(this).attr('checked') == undefined) {
$('input[name=photo]').removeAttr('checked');
}
else {
$('input[name=photo]').attr('checked', 'checked');
}
});
Code: http://jsfiddle.net/b8Y9t/3/
I would use:
$('.photos:checkbox').attr('checked','checked');
There is no function called getElementByName. Did you have a javascript-error? I think it should be getElementsByName. This returns a list with elements. That means you have to loop trough it to check all checkboxes.
BTW I think it is not correct to use a name called 'photos' for a checkbox, since a checkbox is a single object and does not display a photo itself. I would name it 'photoCheckbox' or 'cbPhoto' to clearify it is a checkbox.
var checkboxList = getElementsByName('photoCheckbox'); // returns list with checkboxes with name 'photoCheckbox'
if (checkboxList)
{
for (var i = 0; i < checkboxList.length; i++)
{
var checkbox = checkboxList[i];
checkbox.checked = false;
}
}
Thats how the getElementsByName function works. So if you would evaluate this method, you would say this is unnecessary since you are already using jQuery? I would simplify the code of the checkbox:
<input type="checkbox" onclick="toggleAll(this)" />
The new toggleAll function looks like this:
function toggleAll(checkbox)
{
if (checkbox.checked)
{
$('.photoBlob').animate({backgroundColor: 'rgba(0,102,204,0.5)'}, 500);
$('.photoBlob').animate({backgroundColor: 'rgba(204,204,204,1)'}, 1500); // btw why 2 animations on the same elements..?
$('input[name="photos"]').prop("checked", true);
}
else
{
$('.photoBlob').animate({backgroundColor: 'rgba(0,0,0,0)'}, 1000);
$('input[name="photos"]').prop("checked", false);
}
}
// jquery check all or uncheck all
$('.checkall').click(function(){
var status = 'false';
status = $('.checkall').is(":checked");
//alert ('status is ' + status); // you should see true or false
$('.metacheckbox').each( function() {
$(this).attr('checked', status);
});
});
<input class="checkall" type="checkbox" />Check/UnCheck All
<input class="metacheckbox" type="checkbox" id='checkboxone' name="checkboxone" value="Y" />
<input class="metacheckbox" type="checkbox" id='checkboxtwo' name="checkboxtwo" value="Y" />
<input class="metacheckbox" type="checkbox" id='checkboxthree' name="checkboxthree" value="Y" />
this worked for me.
hi everyone i have a problem in javascript i can print array if fix them in html but whn i try to print them on clic they are not working just print the array names
if i print seriesre simple it print values that is fine but when i check any checkbox and want to print one or tow of them it just showing array name not values
thanks for help
check this example
$(document).ready(function() {
Comment = [['2011-01-29',7695],['2011-02-02',19805]];
WallPost = [['2011-01-29',11115],['2011-02-02',8680]];
Likes = [['2011-01-29',5405],['2011-02-02',10930]];
var seriesre= [Comment,WallPost,Likes];
var mygraphs = new Array();
alert(seriesre);
$("#testCheck").click(function() {
i=0;
$("#testCheck :checked").each(function() {
mygraphs[i]= $(this).val();
i++;
});
newseriesre = "["+mygraphs+"]";
alert(newseriesre);
});
});
<div class="activity">
<form method="POST" id="testCheck" name="myform">
Likes
<input type="checkbox" value="Likes" name="box2">
Comments
<input type="checkbox" value="Comment" name="box3">
Wall Post
<input type="checkbox" value="WallPost" name="box4">
</form>
</div>
You can use
alert(myarray.join())
to alert your array's values
You should use a associative array instead of an array, so that you can look up the data based on the name as a string instead of trying to find the variable. All objects in Javascript are associative arrays, so just put the data in an object.
Also:
Create the mygraphs array inside the event handler, otherwise it can not shrink when you uncheck options.
Catch the click on the checkboxes inside the form, not on the form itself.
Put a label tag around the checkbox and it's label, that way the label is also clickable.
You don't need an index variable to put values in the mygraphs array, just use the push method to add items to it.
http://jsfiddle.net/cCukJ/
Javascript:
$(function() {
Comment = [['2011-01-29',7695],['2011-02-02',19805]];
WallPost = [['2011-01-29',11115],['2011-02-02',8680]];
Likes = [['2011-01-29',5405],['2011-02-02',10930]];
var seriesre = {
'Comment': Comment,
'WallPost': WallPost,
'Likes': Likes
};
$("#testCheck :checkbox").click(function() {
var mygraphs = [];
$("#testCheck :checked").each(function() {
mygraphs.push(seriesre[$(this).val()]);
});
alert("["+mygraphs+"]");
});
});
HTML:
<div class="activity">
<form method="POST" id="testCheck" name="myform">
<label>
Likes
<input type="checkbox" value="Likes" name="box2">
</label>
<label>
Comments
<input type="checkbox" value="Comment" name="box3">
</label>
<label>
Wall Post
<input type="checkbox" value="WallPost" name="box4">
</label>
</form>
</div>
I understand that you want to alert the selected values when clicking anywhere on the form? If that's true correct code with minimal changes to your existing code will be:
var mygraphs = [];
$("#testCheck").click(function() {
$("#testCheck :checked").each(function() {
mygraphs.push($(this).val());
});
alert("Selected values are: " + mygraphs.join(", "));
});
You can try this.
alert($("#testCheck :checked")
.map( function(i, field) { return field.value}
).get());
Check your working example in http://jsfiddle.net/dharnishr/d37Gn/
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.