Looking at posts such as https://stackoverflow.com/a/15453130/1032531, I see how I can validate the quantity of checked boxes.
Instead, I wish to validate checkboxes based on some other criteria such as whether another input is filled out.
EDIT. Context: Inputs are users home, work, and mobile phone. Checkboxes are "call me at home", "call me at work", and "call my mobile phone". They are checkboxes and not radioboxes, and as such, the user will get multiple responses if they check multiple checkboxes.
I've put together the following, however, it appears that jQuery Validator only looks at the first element of a given name. I can probably change the names to be unique instead of using the [], however, I wish the elements to be posted to the server as an array.
How can this be accomplished?
http://jsfiddle.net/suu44yng/
<p>one:
<input id="one" type="text" value="foo" />
</p>
<p>two:
<input id="two" type="text" />
</p>
<p>three:
<input id="three" type="text" value="bar" />
</p>
<hr>
<form id="myform">
<p>
<input type="checkbox" name="test[]" value="1" checked data-check="one" />One</p>
<p>
<input type="checkbox" name="test[]" value="2" checked data-check="two" />Two</p>
<p>
<input type="checkbox" name="test[]" value="3" checked data-check="three" />Three</p>
<p>
<input type="submit" />
</p>
</form>
(function() {
$.validator.addMethod("checkboxes", function(value, element, params) {
console.log(this, value, element, params);
console.log($(element).data('check'), $('#' + $(element).data('check')).val());
console.log(!$('#one').val(),!$('#two').val(),!$('#three').val());
var error = false;
if (value == 1 && !$('#one').val()) {
error = true;
}
else if (value == 2 && !$('#two').val()) {
error = true;
}
else if (value == 3 && !$('#three').val()) {
error = true;
}
console.log(error)
if (error) {
$(element).data('error', value);
return false;
} else {
return true;
}
},
function(params, element) {
return $.validator.format('This checkbox is not allowed since ' + $(element).data('error') + ' is empty.')
})
})();
$(document).ready(function() {
$('#myform').validate({
rules: {
'test[]': {
checkboxes: true
}
},
submitHandler: function(form) {
alert('valid form submitted');
return false;
}
});
});
"I can probably change the names to be unique instead"
That's exactly what you're going to have to do. This plugin uses the name attribute to keep track of input elements and if you have multiple input elements with the same name, only the first one will be considered for validation and the others are ignored.
However, when you have a grouping of checkbox or radio elements sharing the same name, they are considered as a single data point for the form. Example: when setting the grouping to required, then at least one will need to be checked.
There is no workaround if you want each one to be considered individually with a custom rule. Naming would have to be specified as test[1], test[2], etc.
<input type="checkbox" name="test[1]" value="1" checked data-check="one" />One
<input type="checkbox" name="test[2]" value="2" checked data-check="two" />Two
<input type="checkbox" name="test[3]" value="3" checked data-check="three" />Three
rules object:
rules: {
'test[1]': {
checkboxes: true
},
'test[2]': {
checkboxes: true
},
'test[3]': {
checkboxes: true
}
},
Related
I'm trying to enable/disable a place order button based on whether or not the terms acceptance checkbox has been checked. The script I have been working on works fine for that, but it's also triggered when a different checkbox (with a different id) is checked. Although the other checkbox enables the button, it doesn't disable it again when un-checking it. So I think it's something wrong with the 'on change' part.
I've tried everything I could find and can't make it work only when the checkbox with id 'terms' is checked:
<script>
jQuery(window).on('load',function(){
setTimeout(function(){
jQuery('#payment #place_order').attr("disabled","disabled");
},1000);
});
jQuery(document).on('change','#terms',function() {
var ischecked = document.getElementById("terms");
if(ischecked.checked == false){
jQuery('#payment #place_order').attr("disabled","disabled");
}else{
jQuery('#payment #place_order').removeAttr("disabled");
}
});
</script>
The terms checkbox is as below:
<input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox ios-switch" name="terms" id="terms">
And the other one that triggers it is as below:
<input class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox" id="createaccount" type="checkbox" name="createaccount" value="1">
Your code is not clear.
Assuming the place order has the id of #place_order, there is no need to add the container
jQuery(function() { // on page load
jQuery('#place_order').attr("disabled", "disabled");
jQuery(document).on("change", "#terms", function() { // assuming the terms is dynamically inserted
if (!this.checked) {
jQuery('#place_order').attr("disabled", "disabled");
} else {
jQuery('#place_order').removeAttr("disabled");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Terms <input type="checkbox" class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox ios-switch" name="terms" id="terms"><br/>
<button id="place_order">Place order</button>
<hr/>
Create account <input class="woocommerce-form__input woocommerce-form__input-checkbox input-checkbox" id="createaccount" type="checkbox" name="createaccount" value="1">
Hi I have a form with multiple checkboxes. It should be that when a master option is checked and a suboption is not, the user can not proceed to the next step.
I use the code below, but that ensures that when you enable and disable another suboption (of another main option) you can continue to the next step without checking a suboption of another main option.
The checkboxes:
<input name="input_1" type="checkbox" value="1" id="choice_1">
<input name="input_1.1" type="checkbox" value="1.1" id="choice_1_1">
<input name="input_1.2" type="checkbox" value="1.2" id="choice_1_2">
<input name="input_1.2" type="checkbox" value="1.3" id="choice_1_3">
<input name="input_1.3" type="checkbox" value="1.4" id="choice_1_4">
<input name="input_2" type="checkbox" value="2" id="choice_2">
<input name="input_2.1" type="checkbox" value="2.1" id="choice_2_1">
<input name="input_2.2" type="checkbox" value="2.2" id="choice_2_2">
<input name="input_3" type="checkbox" value="3" id="choice_3">
<input name="input_3.1" type="checkbox" value="3.1" id="choice_3_1">
<input name="input_3.2" type="checkbox" value="3.2" id="choice_3_2">
Jquery / Js
$('#choice_1').change(function(){
if($(this).prop('checked')){
if($("#choice_1:checked").length) {
$("#field_18_104").hide(200);
}
checked = $("#choice_1_1:checked").length || $("#choice_1_2:checked").length || $("#choice_1_3:checked").length || $("#choice_1_4:checked").length;
if(!checked) {
var $diverror = $( "<div id='error-form' class='error-form'><p>Error text</p></div>" );
$("#input_18_26").append($diverror);
$('#form_next_button').prop('disabled', true);
return false;
} else {
$( "#error-form" ).remove();
$('#form_next_button').prop('disabled', false);
}
} else {
$( "#error-form" ).remove();
$('#form_next_button').prop('disabled', false);
// if($('#choice_18_26_3').prop('checked')){
// $('#choice_18_26_3').prop('checked', false).change();
// }
}
});
I also use the js code for the main option and suboptions of options 2 and 3. This causes problems when for example main option 1 is checked without a suboption and main option 2 or 3 is checked with a suboption. Then the button is enabled again.
So there are actually 3 groups with suboptions, when group 1 the main option is checked and the suboptions are not and in group 2 a main option and suboption the user must not be able to continue.
The user should not be able to continue when a main option is checked without a sub-option.
try this:
- be sure your checkbox are inside a container, in my example gonna use a div:
#EDIT
<div id="checkContainer">
<input name="input_1" type="checkbox" value="1" id="choice_1">
<input name="input_1.1" type="checkbox" value="1.1" id="choice_1_1">
<input name="input_1.2" type="checkbox" value="1.2" id="choice_1_2">
<input name="input_1.2" type="checkbox" value="1.3" id="choice_1_3">
<input name="input_1.3" type="checkbox" value="1.4" id="choice_1_4"> aaa
<input name="input_2" type="checkbox" value="2" id="choice_2">
<input name="input_2.1" type="checkbox" value="2.1" id="choice_2_1">
<input name="input_2.2" type="checkbox" value="2.2" id="choice_2_2"> bbb
<input name="input_3" type="checkbox" value="3" id="choice_3">
<input name="input_3.1" type="checkbox" value="3.1" id="choice_3_1">
<input name="input_3.2" type="checkbox" value="3.2" id="choice_3_2">
</div>
<button id="form_next_button" disabled>HI</button>
<script>
var MAIN_CHECBOX_SELECTOR = "input[type='checkbox']:not([value*='.'])";
//OR var MAIN_CHECBOX_SELECTOR = "input[type='checkbox']:not([name*='.'])";
var TOTAL_CHECKBOX = $(MAIN_CHECBOX_SELECTOR).length;
$(document).ready(function () {
$("#checkContainer").change(function () {
var _checkedCheckboxes = $(MAIN_CHECBOX_SELECTOR + ":checked");
//this might work as well:
$('#form_next_button').prop('disabled', (_checkedCheckboxes.length !== TOTAL_CHECKBOX));
// if (_checkedCheckboxes.length == TOTAL_CHECKBOX) {
// $('#form_next_button').prop('disabled', false);
// } else {
// $('#form_next_button').prop('disabled', true);
// }
});
});
</script>
There were some small bits of ambiguity on your question but I believe you can work with this.
This is very verbose but it should show what is happening.
What it does: disables subsequent checkbox groups if one does not have sub items.
Does NOT un-check the sub groups if that occurs (was not specified but seems to make sense to do so - what if someone submits a form for example)
IF you check a sub box, it auto checks the master for that group.
You must un-check the master in a group manually if needed - might un-check if NO sub boxes are checked, but easy to refactor to do that.
no fancy messaging or other fields not posted in your question manipulation, basic to address the check boxes only
comments on JS should be removed prior to production publish perhaps.
Note this "disables forward progress" by disabling subsequent groups, as long as you start with all unchecked that is fine, with initial unpredictable checked items it would be good to trigger this process on instantiation - probably on the first group such as: $("input[name='input_1']").trigger('change');
$(function() {
// change event for all named check boxes
// note these are name prefix selectors
$("input[name^='input_1']")
.add("input[name^='input_2']")
.add("input[name^='input_3']")
.on('change', function() {
console.log('change detected');
// clear any prior message
$('#showerrors').html("");
// group 1 of checkboxes
var choice1HasMaster = $("input[name='input_1']")[0].checked;
// note that dot (.) on the prefix selector to get sub group:
var choice1HasSubcheck = !!$("input[name^='input_1.']")
.filter(":checked").length;
// check master if sub checked, update master bool
choice1HasMaster = $("input[name='input_1']")[0].checked = choice1HasMaster || choice1HasSubcheck;
var choice1OK = !choice1HasSubcheck || (choice1HasMaster && choice1HasSubcheck);
// something in first group changed
if ($(this).is("input[name^='input_1']")) {
// past here if needed disable
if (choice1HasMaster && !choice1HasSubcheck) {
$("input[name^='input_2']")
.add("input[name^='input_3']")
.each(function() {
//uncheck sub group would trigger this function:
//this.checked = false;
$(this).prop('disabled', "disabled");
});
$('#showerrors').html("must check sub box group 1");
} else {
// enable next groups
$("input[name^='input_2']")
.add("input[name^='input_3']")
.each(function() {
$(this).prop('disabled', false);
});
}
}
var choice2HasMaster = $("input[name='input_2']")[0].checked;
var choice2HasSubcheck = !!$("input[name^='input_2.']")
.filter(":checked").length;
// check master if sub checked, update master bool
choice2HasMaster = $("input[name='input_2']")[0].checked = choice2HasMaster || choice2HasSubcheck;
if ($(this).is("input[name^='input_2']")) {
// past here if needed disable
if (choice2HasMaster && !choice2HasSubcheck) {
$("input[name^='input_3']")
.each(function() {
//uncheck sub group would trigger this function:
// this.checked = false;
$(this).prop('disabled', "disabled");
});
$('#showerrors').html($('#showerrors').text() + "must check sub box group 2");
} else {
$("input[name^='input_3']")
.each(function() {
$(this).prop('disabled', false);
});
}
}
var choice3HasMaster = $("input[name='input_3']")[0].checked;
var choice3HasSubcheck = !!$("input[name^='input_3.']")
.filter(":checked").length;
// check master if sub checked, update master bool
choice3HasMaster = $("input[name='input_3']")[0].checked = choice3HasMaster || choice3HasSubcheck;
if (choice3HasMaster && !choice3HasSubcheck) {
$('#showerrors').html($('#showerrors').text() + "must check sub box group 3");
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input name="input_1" type="checkbox" value="1" id="choice_1">
<input name="input_1.1" type="checkbox" value="1.1" id="choice_1_1">
<input name="input_1.2" type="checkbox" value="1.2" id="choice_1_2">
<input name="input_1.2" type="checkbox" value="1.3" id="choice_1_3">
<input name="input_1.3" type="checkbox" value="1.4" id="choice_1_4"> group 2:
<input name="input_2" type="checkbox" value="2" id="choice_2">
<input name="input_2.1" type="checkbox" value="2.1" id="choice_2_1">
<input name="input_2.2" type="checkbox" value="2.2" id="choice_2_2"> group 3:
<input name="input_3" type="checkbox" value="3" id="choice_3">
<input name="input_3.1" type="checkbox" value="3.1" id="choice_3_1">
<input name="input_3.2" type="checkbox" value="3.2" id="choice_3_2">
<div id="showerrors"></div>
I have a dynamic list of checkboxes all with the same class. I want to disable the submit button until all checkboxes in the class "group1" has been selected.
I also only want to do this, when this class is present on the page.
I was did that part this way:
<input type="checkbox" class="group1" value="20" />
<input type="checkbox" class="group1" value="15" />
<input type="checkbox" class="group1" value="14" />
if ($(".group1").length > 0) {
//run below code
}
So I started like this, but am unsure of how to know when, all the checkboxes of that class are selected.
$(document).ready(function() {
$(':input[type="submit"]').prop('disabled', true);
$('input[type="text"]').keyup(function() {
var checkboxes = $('.group1');
if($(this).is(':checked')) {
//if all chekced, enable submit button
$(':input[type="submit"]').prop('disabled', false);
} else {
$(':input[type="submit"]').prop('disabled', true);
}
}
});
});
I have seen this jQuery Array of all selected checkboxes (by class), but as the class can be of any length, I dont know how to check that all are selected.
The easiest way to do this is to compare the total number of checkboxes to the number which are checked, like this:
var $group = $('.group1');
$(':input[type="submit"]').prop('disabled', $group.length != $group.filter(':checked').length);
You can simply check like this, total number of checkboxes and total number of checked checkboxes:
if ($('.group1').length == $('.group1:checked').length) {
// all are checked...
$(':input[type="submit"]').prop('disabled', false);
} else {
$(':input[type="submit"]').prop('disabled', true);
}
var selected = $(".group1:checked").length;
Count the checkboxes wich are checked.
First you will need to bind an event to checkboxes, to every time they change state to re-run the check to enable or disable the button;
Then you can check if all checkboxes are checked comparing the length of your group vs the length of your group filtered by :checked pseudo selector
And to change the state of the submit button, you can use .prop method, that accept an attribute and a state of this attribute as a second parameter. So:
$group1 = $(".group1");
$submit = $('[type=submit]');
if ($group1.length > 0) {
$group1.on('change', checkBoxes)
}
function checkBoxes(){
var $checked = $group1.filter(':checked');
$submit.prop('disabled', $group1.length != $checked.length);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" class="group1" value="20" />
<input type="checkbox" class="group1" value="15" />
<input type="checkbox" class="group1" value="14" />
<input type="submit" disabled>
I'm trying to implement a "Select All" checkbox on an HTML form using JQuery 1.9.1. As far as I can tell, it should be as simple as using .prop to check or uncheck a checkbox, but nothing I try seems to work.
Please see below for what I have tried, I've commented out some failed attempts out and I cannot get this to work for even one checkbox. What is the correct way to do this? Am I missing something, possibly in the HTML?
HTML
<input type="checkbox" id="cb_select_all" name="cb_select_all" value="t" />
<label for="cb_select_all"><b>Select All</b>
</label>
<br />
<input type="checkbox" name="cb1" id="cb1" class="cb_all" value="t" />
<label for="cb1">1 test</label>
<br />
<input type="checkbox" name="cb2" id="cb2" class="cb_all" value="t" />
<label for="cb2">2 test</label>
Javascript
$(document).ready(function () {
$("#cb_select_all").change(cb_select_all_onchange);
}); //end $(document).ready
function cb_select_all_onchange() {
if ($("#cb_select_all").checked) {
//$("#cb1").prop("checked", true);
//$(".cb_all").each(function(){ this.checked = true; });
//document.getElementById("cb1").checked = true;
$(".cb_all").prop("checked", true);
} else {
$("#cb1").prop("checked", false);
}
}
http://jsfiddle.net/mLnb5qed/5/
Thanks,
jdt
Change your if to this
if ($("#cb_select_all")[0].checked) { }
( or ) if ($("#cb_select_all").is(":checked")) { }
The problem is the first one is a property of native element and not jQuery object. Accessing it by an index gives you the ability to use that property. The second way is the jQuery way.
Use
$("#cb_select_all").is(':checked');
This worked for me:
$(document).ready(function () {
$("#cb_select_all").change(function () {
if ($("#cb_select_all").prop("checked") == true) {
$('.cb_all').prop('checked', true);
}
else {
$('.cb_all').prop('checked', false);
}
});
});
What happens:
Check if the "cb_select_all" checkbox changes state
if the "checked" state is set to true
check all "cb_all" checkboxes
else
uncheck all "cb_all" checkboxes
How can I get this list of checkboxes to be added to a div prior to their selected state, so if they are selected, they should be added to the div, if not they are removed from the list if not selected.
<div id="selected-people"></div>
<input type="checkbox" value="45" id="Jamie" />
<input type="checkbox" value="46" id="Ethan" />
<input type="checkbox" value="47" id="James" />
<input type="checkbox" value="48" id="Jamie" />
<input type="checkbox" value="49" id="Darren" />
<input type="checkbox" value="50" id="Danny" />
<input type="checkbox" value="51" id="Charles" />
<input type="checkbox" value="52" id="Charlotte" />
<input type="checkbox" value="53" id="Natasha" />
Is it possible to extract the id name as the stored value, so the id value will be added to the div instead of the value - the value needs to have the number so that it gets added to a database for later use.
I looked on here, there is one with checkboxes and a textarea, I changed some parts around, doesn't even work.
function storeuser()
{
var users = [];
$('input[type=checkbox]:checked').each(function()
{
users.push($(this).val());
});
$('#selected-people').html(users)
}
$(function()
{
$('input[type=checkbox]').click(storeuser);
storeuser();
});
So you want to keep the DIV updated whenever a checkbox is clicked? That sound right?
http://jsfiddle.net/HBXvy/
var $checkboxes;
function storeuser() {
var users = $checkboxes.map(function() {
if(this.checked) return this.id;
}).get().join(',');
$('#selected-people').html(users);
}
$(function() {
$checkboxes = $('input:checkbox').change(storeuser);
});
Supposing you only have these input controls on page I can write following code.
$.each($('input'), function(index, value) {
$('selected-people').append($(value).attr('id'));
});
Edited Due to More Description
$(document).ready(function() {
$.each($('input'), function(index, value) {
$(value).bind('click', function() {
$('selected-people').append($(value).attr('id'));
});
});
});
Note: I am binding each element's click event to a function. If that doesn't work or it isn't a good for what you are supposed to do then change it to on "change" event.
Change:
users.push($(this).val());
to:
users.push($(this).attr('id'));
This is for to bind the comma seperated values to input checkbox list
$(".chkboxes").val("1,2,3,4,5,6".split(','));
it will bind checkboxes according to given string value in comma seperated.