I'd like to validate a form using the jquery validate plugin, but I'm unable to use the 'name' value within the html - as this is a field also used by the server app.
Specifically, I need to limit the number of checkboxes checked from a group. (Maximum of 3.) All of the examples I have seen, use the name attribute of each element. What I'd like to do is use the class instead, and then declare a rule for that.
html
This works:
<input class="checkBox" type="checkbox" id="i0000zxthy" name="salutation" value="1" />
This doesn't work, but is what I'm aiming for:
<input class="checkBox" type="checkbox" id="i0000zxthy" name="i0000zxthy" value="1" />
javascript:
var validator = $(".formToValidate").validate({
rules:{
"salutation":{
required:true,
},
"checkBox":{
required:true,
minlength:3 }
}
});
Is it possible to do this - is there a way of targeting the class instead of the name within the rules options? Or do I have to add a custom method?
Cheers,
Matt
You can add the rules based on that selector using .rules("add", options), just remove any rules you want class based out of your validate options, and after calling $(".formToValidate").validate({... });, do this:
$(".checkBox").rules("add", {
required:true,
minlength:3
});
Another way you can do it, is using addClassRules.
It's specific for classes, while the option using selector and .rules is more a generic way.
Before calling
$(form).validate()
Use like this:
jQuery.validator.addClassRules('myClassName', {
required: true /*,
other rules */
});
Ref: http://docs.jquery.com/Plugins/Validation/Validator/addClassRules#namerules
I prefer this syntax for a case like this.
I know this is an old question. But I too needed the same one recently, and I got this question from stackoverflow + another answer from this blog. The answer which was in the blog was more straight forward as it focuses specially for this kind of a validation. Here is how to do it.
$.validator.addClassRules("price", {
required: true,
minlength: 2
});
This method does not require you to have validate method above this call.
Hope this will help someone in the future too. Source here.
Here's the solution using jQuery:
$().ready(function () {
$(".formToValidate").validate();
$(".checkBox").each(function (item) {
$(this).rules("add", {
required: true,
minlength:3
});
});
});
Here's my solution (requires no jQuery... just JavaScript):
function argsToArray(args) {
var r = []; for (var i = 0; i < args.length; i++)
r.push(args[i]);
return r;
}
function bind() {
var initArgs = argsToArray(arguments);
var fx = initArgs.shift();
var tObj = initArgs.shift();
var args = initArgs;
return function() {
return fx.apply(tObj, args.concat(argsToArray(arguments)));
};
}
var salutation = argsToArray(document.getElementsByClassName('salutation'));
salutation.forEach(function(checkbox) {
checkbox.addEventListener('change', bind(function(checkbox, salutation) {
var numChecked = salutation.filter(function(checkbox) { return checkbox.checked; }).length;
if (numChecked >= 4)
checkbox.checked = false;
}, null, checkbox, salutation), false);
});
Put this in a script block at the end of <body> and the snippet will do its magic, limiting the number of checkboxes checked in maximum to three (or whatever number you specify).
Here, I'll even give you a test page (paste it into a file and try it):
<!DOCTYPE html><html><body>
<input type="checkbox" class="salutation">
<input type="checkbox" class="salutation">
<input type="checkbox" class="salutation">
<input type="checkbox" class="salutation">
<input type="checkbox" class="salutation">
<input type="checkbox" class="salutation">
<input type="checkbox" class="salutation">
<input type="checkbox" class="salutation">
<input type="checkbox" class="salutation">
<input type="checkbox" class="salutation">
<script>
function argsToArray(args) {
var r = []; for (var i = 0; i < args.length; i++)
r.push(args[i]);
return r;
}
function bind() {
var initArgs = argsToArray(arguments);
var fx = initArgs.shift();
var tObj = initArgs.shift();
var args = initArgs;
return function() {
return fx.apply(tObj, args.concat(argsToArray(arguments)));
};
}
var salutation = argsToArray(document.getElementsByClassName('salutation'));
salutation.forEach(function(checkbox) {
checkbox.addEventListener('change', bind(function(checkbox, salutation) {
var numChecked = salutation.filter(function(checkbox) { return checkbox.checked; }).length;
if (numChecked >= 3)
checkbox.checked = false;
}, null, checkbox, salutation), false);
});
</script></body></html>
Since for me, some elements are created on page load, and some are dynamically added by the user; I used this to make sure everything stayed DRY.
On submit, find everything with class x, remove class x, add rule x.
$('#form').on('submit', function(e) {
$('.alphanumeric_dash').each(function() {
var $this = $(this);
$this.removeClass('alphanumeric_dash');
$(this).rules('add', {
alphanumeric_dash: true
});
});
});
If you want add Custom method you can do it
(in this case, at least one checkbox selected)
<input class="checkBox" type="checkbox" id="i0000zxthy" name="i0000zxthy" value="1" onclick="test($(this))"/>
in Javascript
var tags = 0;
$(document).ready(function() {
$.validator.addMethod('arrayminimo', function(value) {
return tags > 0
}, 'Selezionare almeno un Opzione');
$.validator.addClassRules('check_secondario', {
arrayminimo: true,
});
validaFormRichiesta();
});
function validaFormRichiesta() {
$("#form").validate({
......
});
}
function test(n) {
if (n.prop("checked")) {
tags++;
} else {
tags--;
}
}
If you need to set up multpile class rules you can do it like this:
jQuery.validator.addClassRules({
name: {
required: true,
minlength: 2
},
zip: {
required: true,
digits: true,
minlength: 5,
maxlength: 5
}
});
source: https://jqueryvalidation.org/jQuery.validator.addClassRules/
Disclaimer: Yes, I know it's 2021 and you shouldn't be using jQuery but, sometimes we have to. This information was really useful to me, so I hope to help some eventual random stranger who has to maintain some legacy system somewhere.
$(".ClassName").each(function (item) {
$(this).rules("add", {
required: true,
});
});
Related
I want to send the value of my checkbox to database using ajax. Through some searching in internet, I somehow managed to get this far.This is what I have been using. What changes do I need to make on json2.stringify for it to correctly send my values.
Html:
<input type="checkbox" id="txtCategoryIsPaid" name="cateogryIsPaid" value="Paid">Yes<br>
Javascript:
AddCategory: function () {
BusinessManagement.config.method = "AddBusinessCategory";
BusinessManagement.config.url = BusinessManagement.config.baseURL + BusinessManagement.config.method;
BusinessManagement.config.data = JSON2.stringify({
CategoryIsPaid: $('#txtCategoryIsPaid :checked').val(),
});
BusinessManagement.config.ajaxCallMode = 0;
BusinessManagement.ajaxCall(BusinessManagement.config);
Use .prop('checked') attribute
<HTML>
<input type="checkbox" id="txtCategoryIsPaid" name="cateogryIsPaid" value="Paid">Yes<br>
Javascript
AddCategory: function () {
BusinessManagement.config.method = "AddBusinessCategory";
BusinessManagement.config.url = BusinessManagement.config.baseURL + BusinessManagement.config.method;
BusinessManagement.config.data = JSON2.stringify({
CategoryIsPaid: $('#txtCategoryIsPaid').prop('checked') == true ? "true": "false",
});
BusinessManagement.config.ajaxCallMode = 0;
BusinessManagement.ajaxCall(BusinessManagement.config);
I have a function that returns whether or not every text input in a form has a value.
When I first made the function it looked like this:
function checkInput(inputId) {
check = 0; //should be 0 if all inputs are filled out
for (var i=0; i < arguments.length; i++) { // get all of the arguments (input ids) to check
var iVal = $("#"+arguments[i]).val();
if(iVal !== '' && iVal !== null) {
$("#"+arguments[i]).removeClass('input-error');
}
else {
$("#"+arguments[i]).addClass('input-error');
$("#"+arguments[i]).focus(function(){
$("input").removeClass('input-error');
$("#"+arguments[i]).off('focus');
});
check++;
}
}
if(check > 0) {
return false; // at least one input doesn't have a value
}
else {
return true; // all inputs have values
}
}
This worked fine, but when I called the function I would have to include (as an arstrong textgument) the id of every input I wanted to be checked: checkInput('input1','input2','input3').
Now I am trying to have my function check every input on the page without having to include every input id.
This is what I have so far:
function checkInput() {
var inputs = $("input");
check = 0;
for (var i=0; i < inputs.size(); i++) {
var iVal = inputs[i].val();
if(iVal !== '' && iVal !== null) {
inputs[i].removeClass('input-error');
}
else {
inputs[i].addClass('input-error');
inputs[i].focus(function(){
$("input").removeClass('input-error');
inputs[i].off('focus');
});
check++;
}
}
if(check > 0) {
return false;
}
else {
return true;
}
}
When I call the function it returns this error:
Uncaught TypeError: inputs[i].val is not a function
What am I doing wrong?
When you do inputs[i], this returns an html element, so it is no longer a jquery object. This is why it no longer has that function.
Try wrapping it with $() like $(inputs[i]) to get the jquery object, and then call .val() like:
$(inputs[i]).val()
If you are going to use this in your for loop, just set it as a variable:
var $my_input = $(inputs[i])
Then continue to use it within the loop with your other methods:
$my_input.val()
$my_input.addClass()
etc..
if you use jquery .each() function, you can do it a little cleaner:
$(document).ready(function() {
$('.submit').on('click', function() {
$('input').each(function() {
console.log('what up');
if($(this).val().length < 1 ) {
$(this).addClass('input-error');
}
else {
$(this).removeClass('input-error');
}
});
});
});
.input-error {
background-color: pink;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" /><br/>
<input type="text" /><br/>
<input type="text" /><br/>
<input type="text" /><br/>
<input type="text" /><br/>
<input type="text" /><br/>
<input type="text" /><br/>
<input type="text" /><br/>
<input type="text" /><br/>
<input type="text" /><br/>
<br/>
SUBMIT
This is actually a very simple fix. You need to wrap you jquery objects within the jquery constructor $()
Such as for inputs[i].val() to $(inputs[i]).val();
Here is the full working example:
http://jsbin.com/sipotenamo/1/edit?html,js,output
Hope that helps!
This is exactly one of the things the .eq() method is for. Rather than using inputs[i], use the following:
// Reduce the set of matched elements to the one at the specified index.
inputs.eq(i)
Given a jQuery object that represents a set of DOM elements, the .eq() method constructs a new jQuery object from one element within that set. The supplied index identifies the position of this element in the set.
in this case, I would make use of the jQuery.each() function for looping through the form elements. This will be the modified code
function checkInput() {
var $inputs = $("input"),
check = 0;
$inputs.each(function () {
val = $.trim($(this).val());
if (val) {
$(this).removeClass('input-error');
}
else {
$(this).addClass('input-error');
$(this).focus(function () {
$("input").removeClass('input-error');
$(this).off('focus');
});
check++;
}
});
return check == 0;
}
So I've got code that looks like this:
<input class="messageCheckbox" type="checkbox" value="3" name="mailId[]">
<input class="messageCheckbox" type="checkbox" value="1" name="mailId[]">
I just need Javascript to get the value of whatever checkbox is currently checked.
EDIT: To add, there will only be ONE checked box.
None of the above worked for me but simply use this:
document.querySelector('.messageCheckbox').checked;
For modern browsers:
var checkedValue = document.querySelector('.messageCheckbox:checked').value;
By using jQuery:
var checkedValue = $('.messageCheckbox:checked').val();
Pure javascript without jQuery:
var checkedValue = null;
var inputElements = document.getElementsByClassName('messageCheckbox');
for(var i=0; inputElements[i]; ++i){
if(inputElements[i].checked){
checkedValue = inputElements[i].value;
break;
}
}
I am using this in my code.Try this
var x=$("#checkbox").is(":checked");
If the checkbox is checked x will be true otherwise it will be false.
in plain javascript:
function test() {
var cboxes = document.getElementsByName('mailId[]');
var len = cboxes.length;
for (var i=0; i<len; i++) {
alert(i + (cboxes[i].checked?' checked ':' unchecked ') + cboxes[i].value);
}
}
function selectOnlyOne(current_clicked) {
var cboxes = document.getElementsByName('mailId[]');
var len = cboxes.length;
for (var i=0; i<len; i++) {
cboxes[i].checked = (cboxes[i] == current);
}
}
This does not directly answer the question, but may help future visitors.
If you want to have a variable always be the current state of the checkbox (rather than having to keep checking its state), you can modify the onchange event to set that variable.
This can be done in the HTML:
<input class='messageCheckbox' type='checkbox' onchange='some_var=this.checked;'>
or with JavaScript:
cb = document.getElementsByClassName('messageCheckbox')[0]
cb.addEventListener('change', function(){some_var = this.checked})
$(document).ready(function() {
var ckbox = $("input[name='ips']");
var chkId = '';
$('input').on('click', function() {
if (ckbox.is(':checked')) {
$("input[name='ips']:checked").each ( function() {
chkId = $(this).val() + ",";
chkId = chkId.slice(0, -1);
});
alert ( $(this).val() ); // return all values of checkboxes checked
alert(chkId); // return value of checkbox checked
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="checkbox" name="ips" value="12520">
<input type="checkbox" name="ips" value="12521">
<input type="checkbox" name="ips" value="12522">
Use this:
alert($(".messageCheckbox").is(":checked").val())
This assumes the checkboxes to check have the class "messageCheckbox", otherwise you would have to do a check if the input is the checkbox type, etc.
<input class="messageCheckbox" type="checkbox" onchange="getValue(this.value)" value="3" name="mailId[]">
<input class="messageCheckbox" type="checkbox" onchange="getValue(this.value)" value="1" name="mailId[]">
function getValue(value){
alert(value);
}
None of the above worked for me without throwing errors in the console when the box wasn't checked so I did something along these lines instead (onclick and the checkbox function are only being used for demo purposes, in my use case it's part of a much bigger form submission function):
function checkbox() {
var checked = false;
if (document.querySelector('#opt1:checked')) {
checked = true;
}
document.getElementById('msg').innerText = checked;
}
<input type="checkbox" onclick="checkbox()" id="opt1"> <span id="msg">Click The Box</span>
If you're using Semantic UI React, data is passed as the second parameter to the onChange event.
You can therefore access the checked property as follows:
<Checkbox label="Conference" onChange={(e, d) => console.log(d.checked)} />
Surprised to see no working vanilla JavaScript solutions here (the top voted answer does not work when you follow best practices and use different IDs for each HTML element). However, this did the job for me:
Array.prototype.slice.call(document.querySelectorAll("[name='mailId']:checked"),0).map(function(v,i,a) {
return v.value;
});
If you want to get the values of all checkboxes using jQuery, this might help you. This will parse the list and depending on the desired result, you can execute other code. BTW, for this purpose, one does not need to name the input with brackets []. I left them off.
$(document).on("change", ".messageCheckbox", function(evnt){
var data = $(".messageCheckbox");
data.each(function(){
console.log(this.defaultValue, this.checked);
// Do something...
});
}); /* END LISTENER messageCheckbox */
pure javascript and modern browsers
// for boolean
document.querySelector(`#isDebugMode`).checked
// checked means specific values
document.querySelector(`#size:checked`)?.value ?? defaultSize
Example
<form>
<input type="checkbox" id="isDebugMode"><br>
<input type="checkbox" value="3" id="size"><br>
<input type="submit">
</form>
<script>
document.querySelector(`form`).onsubmit = () => {
const isDebugMode = document.querySelector(`#isDebugMode`).checked
const defaultSize = "10"
const size = document.querySelector(`#size:checked`)?.value ?? defaultSize
// 👇 for defaultSize is undefined or null
// const size = document.querySelector(`#size:checked`)?.value
console.log({isDebugMode, size})
return false
}
</script>
Optional_chaining (?.)
You could use following ways via jQuery or JavaScript to check whether checkbox is clicked.
$('.messageCheckbox').is(":checked"); // jQuery
document.getElementById(".messageCheckbox").checked //JavaScript
To obtain the value checked in jQuery:
$(".messageCheckbox").is(":checked").val();
In my project, I usually use this snippets:
var type[];
$("input[name='messageCheckbox']:checked").each(function (i) {
type[i] = $(this).val();
});
And it works well.
I have the following checkbox:
<input type="checkbox" id="startClientFromWeb" name="startClientFromWeb" data-bind="checked: StartClientFromWeb" />
and the following input text field:
<input id="mimeType" name="mimeType" data-bind= "value: MimeType" />
This is my js validation code:
$("#franchiseForm").validate({
rules: {
mimeType: {
required: $("#startClientFromWeb").is(":checked")
}
}
});
I want the mimeType input text field to be required only if checkbox is checked. For some reason the above is not working. I am quite new to javascript and jquery. Any help with working example will be greatly appreciated. Thank You!
You can add your own custom validation methods to handle things like this:
$.validator.addMethod("requiredIfChecked", function (val, ele, arg) {
if ($("#startClientFromWeb").is(":checked") && ($.trim(val) == '')) { return false; }
return true;
}, "This field is required if startClientFromWeb is checked...");
$("#franchiseForm").validate({
rules: {
mimeType: { requiredIfChecked: true }
}
});
Validation will not triger if input is disabled. You could use that fact - let textbox be required, but initially disabled, and enable it only when checkbox is checked.
$(function () {
$('#startClientFromWeb').change(function () {
if ($(this).is(':checked')) {
$('#mimeType').removeAttr('disabled');
}
else {
$('#mimeType').attr('disabled', 'disabled');
}
});
});
The simpliest way which works:
rules : {mimeType:{required:"#startClientFromWeb:checked"}}, messages: {mimeType: {required: 'Repeat checked, To date required'}}
I am trying to get jquery validate to work on multiple fields. Reason being I have dynamically generated fields added and they are simply a list of phone numbers from none to as many as required. A button adds another number.
So I thought I'd put together a basic example and followed the concept from the accepted answer in the following link:
Using JQuery Validate Plugin to validate multiple form fields with identical names
However, it's not doing anything useful. Why is it not working?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/lib/jquery.delegate.js"></script>
<script type="text/javascript" src="http://dev.jquery.com/view/trunk/plugins/validate/jquery.validate.js"></script>
<script>
$("#submit").click(function(){
$("field").each(function(){
$(this).rules("add", {
required: true,
email: true,
messages: {
required: "Specify a valid email"
}
});
})
});
$(document).ready(function(){
$("#myform").validate();
});
</script>
</head>
<body>
<form id="myform">
<label for="field">Required, email: </label>
<input class="left" id="field" name="field" />
<input class="left" id="field" name="field" />
<input class="left" id="field" name="field" />
<input class="left" id="field" name="field" />
<br/>
<input type="submit" value="Validate!" id="submit" name="submit" />
</form>
</body>
</html>
This: $("field").each(function(){
Should be: $("[name=field]").each(function(){
Also your IDs should be unique, you'll get unpredictable behavior when this isn't true. Also, you should move the rule adding inside the document.ready, like this (this is now all your script):
$(function(){
$("#myform").validate();
$("[name=field]").each(function(){
$(this).rules("add", {
required: true,
email: true,
messages: {
required: "Specify a valid email"
}
});
});
});
#pratik
JqueryValidation maintaining rulesCache, You need to modify core library.
elements: function() {
var validator = this,
rulesCache = {};
// select all valid inputs inside the form (no submit or reset buttons)
return $(this.currentForm)
.find("input, select, textarea")
.not(":submit, :reset, :image, [disabled]")
.not(this.settings.ignore)
.filter(function() {
if (!this.name && validator.settings.debug && window.console) {
console.error("%o has no name assigned", this);
}
// select only the first element for each name, and only those with rules specified
if (this.name in rulesCache || !validator.objectLength($(this).rules())) {
return false;
}
rulesCache[this.name] = true;
return true;
});
},
Just comment the rulesCache[this.name] = true;
elements: function() {
var validator = this,
rulesCache = {};
// select all valid inputs inside the form (no submit or reset buttons)
return $(this.currentForm)
.find("input, select, textarea")
.not(":submit, :reset, :image, [disabled]")
.not(this.settings.ignore)
.filter(function() {
if (!this.name && validator.settings.debug && window.console) {
console.error("%o has no name assigned", this);
}
// select only the first element for each name, and only those with rules specified
if (this.name in rulesCache || !validator.objectLength($(this).rules())) {
return false;
}
// rulesCache[this.name] = true;
return true;
});
},
If you don't want to change in core library file. there is another solution. Just override existing core function.
$.validator.prototype.checkForm = function (){
this.prepareForm();
for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
if (this.findByName( elements[i].name ).length != undefined && this.findByName( elements[i].name ).length > 1) {
for (var cnt = 0; cnt < this.findByName( elements[i].name ).length; cnt++) {
this.check( this.findByName( elements[i].name )[cnt] );
}
}
else {
this.check( elements[i] );
}
}
return this.valid();
};