Have this problem that form inputs with assigned mask (as a placeholder) are not validated as empty by jQuery validation.
I use:
https://github.com/RobinHerbots/jquery.inputmask
https://github.com/1000hz/bootstrap-validator
(which uses jQuery native validation in this case)
Some strange behaviors:
Inputs with attribute required are validated (by jQuery) as not empty and therefore valid, but in the other hand input is not considered as "not empty" and not checked for other validation rules (this is by validator.js)
When i write something into input field and then erase it, I get required error message
Can anyone give me some hint?
EDIT:
Relevant code:
HTML/PHP:
<form enctype="multipart/form-data" method="post" id="feedback">
<div class="kontakt-form-row form-group">
<div class="kontakt-form">
<label for="phone" class="element">
phone<span class="required">*</span>
</label>
</div>
<div class="kontakt-form">
<div class="element">
<input id="phone" name="phone" ' . (isset($user['phone']) ? 'value="' . $user['phone'] . '"' : '') . ' type="text" maxlength="20" class="form-control" required="required" data-remote="/validator.php">
</div>
</div>
<div class="help-block with-errors"></div>
</div>
</form>
JS:
$(document).ready(function() {
$('#phone').inputmask("+48 999 999 999");
$('#feedback').validator();
});
I managed to use the RobinHerbots's Inputmask (3.3.11), with jQuery Validate, by activating clearIncomplete. See Input mask documentation dedicated section:
Clear the incomplete input on blur
$(document).ready(function(){
$("#date").inputmask("99/99/9999",{ "clearIncomplete": true });
});
Personnaly, when possible, I prefer setting this by HTML data attribute:
data-inputmask-clearincomplete="true"
The drawback is: partial input is erased when focus is lost, but I can live with that. So maybe you too ...
Edit: if you need to add the mask validation to the rest of your jQuery Validate process, you can simulate a jQuery Validate error by doing the following:
// Get jQuery Validate validator currently attached
var validator = $form.data('validator');
// Get inputs violating masks
var $maskedInputList
= $(':input[data-inputmask-mask]:not([data-inputmask-mask=""])');
var $incompleteMaskedInputList
= $maskedInputList.filter(function() {
return !$(this).inputmask("isComplete");
});
if ($incompleteMaskedInputList.length > 0)
{
var errors = {};
$incompleteMaskedInputList.each(function () {
var $input = $(this);
var inputName = $input.prop('name');
errors[inputName]
= localize('IncompleteMaskedInput_Message');
});
// Display each mask violation error as jQuery Validate error
validator.showErrors(errors);
// Cancel submit if any such error
isAllInputmaskValid = false;
}
// jQuery Validate validation
var isAllInputValid = validator.form();
// Cancel submit if any of the two validation process fails
if (!isAllInputValid ||
!isAllInputmaskValid) {
return;
}
// Form submit
$form.submit();
It's not exactly the solution, but...
changing inputmask for some equivalent solves the problem.
Still far from perfect, though : (
EXPLANATION:
Other masking libraries, don't have these two strange behaviors mentioned, so it's possible to validate fields.
I used:
https://github.com/digitalBush/jquery.maskedinput
I have the same issue when combined these two libs together.
Actually there is a similar ticket here: https://github.com/RobinHerbots/Inputmask/issues/1034
Here is the solution provided by RobinHerbots:
$("#inputPhone").inputmask("999.999.9999", {showMaskOnFocus: false, showMaskOnHover: false});
The validator assumes that it is not empty when the mask focus/hover is there.
simply turn focus and hover of the mask off will fix the problem.
I solved this problem with:
phone_number: {
presence: {message: '^ Prosimy o podanie numeru telefonu'},
format: {
pattern: '(\\(?(\\+|00)?48\\)?)?[ -]?\\d{3}[ -]?\\d{3}[ -]?\\d{3}',
message: function (value, attribute, validatorOptions, attributes, globalOptions) {
return validate.format("^ Nieprawidłowa wartość w polu Telefon");
}
},
length: {
minimum: 15,
message: '^ Prosimy o podanie numeru telefonu'
},
},
Related
I just started learning JS, Jquery and HTML online. I have a question, and have tried doing things which were told in the answers of similar questions on SO, but it won't help.
I have a password form which only accepts input which have atleast 6 characters, one uppercase letter and one number. I wish to show a custom validation message which could just state these conditions again.
Here's my HTML code -
<div class="password">
<label for="password"> Password </label>
<input type="password" class="passwrdforsignup" name="password" required pattern="(?=.*\d)(?=.*[A-Z]).{6,}"> <!--pw must contain atleast 6 characters, one uppercase and one number-->
</div>
I'm using JS to set the custom validation message.
JS code
$(document).ready(function () {
$('.password').on('keyup', '.passwrdforsignup', function () {
var getPW = $(this).value();
if (getPW.checkValidity() === false) {
getPW.setCustomValidity("This password doesn't match the format specified");
}
});
});
However, the custom validation message doesn't show. Please help. Thank you so much in advance! :)
UPDATE 1
I changed the password pattern to (?=.*\d)(?=.*[A-Z])(.{6,}). Based on 4castle's advise, I realized there were a few errors in my javascript, and changed them accordingly. However, the custom validation message still doesn't show.
JavaScript:
$(document).ready(function () {
$('.password').on('keyup', '.passwrdforsignup', function () {
var getPW = $(this).find('.passwrdforsignup').get();
if (getPW.checkValidity() === false) {
getPW.setCustomValidity("This password doesn't match the format specified");
}
});
});
Again, than you all in advance!
First, update this:
var getPW = $(this).find('.passwrdforsignup').get();
to this:
var getPW = $(this).get(0);
...because $(this) is already the textbox .passwrdforsignup, you can't find it in itself!
The problem with setCustomValidity is, that it does only work once you submit the form. So there is the option to do exactly that:
$(function () {
$('.password').on('keyup', '.passwrdforsignup', function () {
var getPW = $(this).get(0);
getPW.setCustomValidity("");
if (getPW.checkValidity() === false) {
getPW.setCustomValidity("This password doesn't match the format specified");
$('#do_submit').click();
}
});
});
Please note the getPW.setCustomValidity(""); which resets the message which is important because if you do not do this, getPW.checkValidity() will always be false!
For this to work the textbox (and the submit-button) must be in a form.
Working JSFiddle
There are several issues going on here.
The pattern doesn't have a capture group, so technically nothing can ever match it. Change the pattern to (?=.*\d)(?=.*[A-Z])(.{6,})
$(this).value() doesn't refer to the value of the input tag, it's referring to the value of .password which is the container div.
getPW.checkValidity() and getPW.setCustomValidity("blah") are getting run on a string, which doesn't have definitions for those functions, only DOM objects do.
Here is what you should do instead (JS code from this SO answer)
$(document).ready(function() {
$('.passwrdforsignup').on('invalid', function(e) {
var getPW = e.target;
getPW.setCustomValidity("");
if (!getPW.checkValidity())
getPW.setCustomValidity("This password doesn't match the format specified");
}).on('input', function(e) {
$(this).get().setCustomValidity("");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<div class="password">
<label for="password">Password</label>
<input type="password" class="passwrdforsignup" name="password"
required pattern="(?=.*\d)(?=.*[A-Z])(.{6,})" />
</div>
<input type="submit" />
</form>
I am using the jQuery Validation Plugin to validate a number of inputs on a html page. The first name is always required, and either email OR mobile but not both. To do this, I use the require_from_group_exact method.
When the inputs are in this order, validation occurs perfectly:
<form>
Email: <input class="commsinfo" name="email"><br>
Mobile: <input class="commsinfo" name="mobile"><br>
Name: <input name="firstname"><br>
<input type="submit">
</form>
However if you swap the inputs around, validation of the last input (firstname) does not occur properly (you have to type a firstname and then delete it to trigger validation) - why??. This is the desired order and issue I'm trying to solve - is it a bug with the jQuery Validation Plugin or my code?
<form>
Name: <input name="firstname"><br>
Email: <input class="commsinfo" name="email"><br>
Mobile: <input class="commsinfo" name="mobile"><br>
<input type="submit">
</form>
I have created a JSFiddle of the version the does not validate properly. The code for the jQuery.validator.addMethod and $('form').validate can be seen in the fiddle.
You're not checking all the input fields,
change var fields = $(selector, element.form);
to var fields = $('form :input');
Updated Fiddle
In the example you've provided, there seems to be an issue with the call to fields.valid().
I've updated the fiddle to remove some code I don't think you need. The call to valid() seems to be the crux of the problem and removing it causes the validation to work as expected.
The updated code now looks like this:
jQuery.validator.addMethod("require_from_group_exact", function(value, element, options) {
var validator = this;
var selector = options[1];
var validOrNot = $(selector, element.form).filter(function() {
return validator.elementValue(this);
}).length == options[0];
return validOrNot;
}, jQuery.format("Please fill {0} of these fields."));
$('form').validate({
rules: {
firstname: { required: true },
email: { require_from_group_exact: [1, ".commsinfo"] },
mobile: { require_from_group_exact: [1, ".commsinfo"] },
}
});
Updated Fiddle
Every time you call the
fields.valid();
your validator method is recalled and so you get the apparently strange behaviour. You can check this debugging by yourself.
From the documentation http://1000hz.github.io/bootstrap-validator/:
Add custom validators to be run. Validators should be functions that receive the jQuery element as an argument and return a truthy or falsy value based on the validity of the input.
Object structure is: {foo: function($el) { return true || false } }
Adding the validator to an input is done just like the others, data-foo="bar".
You must also add default error messages for any custom validators via the errors option.
I don't quite understand how to define my own custom validator and how to use it with this plugin.
Could anyone give me a simple example or hint?
You need to call your plugin manually, as custom options will not work with data-attributes:
$().validator({
custom: {
'odd': function($el) { return Boolean($el.val() % 2);}
}
})
then use it like this:
<input placeholder="plz enter odd value" data-odd>
Don't forget to add error messages, see code
I wanted to flesh out the answers here with a bit more detail.
I was attempting to do this while using the data-api (putting data-toggle="validator" in the form tag). Removing that from my <form> tag and enabling it with Javascript, my custom function works:
$('#sign-up_area').validator({
custom: {
'odd': function($el) { return Boolean($el.val() % 2);}
},
errors: {
odd: "That's not an odd number!"
}
});
I also had to add a value to the data-odd attribute thusly:
<div class="row">
<div class="form-group col-xs-12 col-md-12">
<label class="control-label" for="test">Odd/Even:</label>
<input type="text" name="test" id="test" class="form-control" placeholder="Enter an odd integer" data-odd="odd" >
<span class="help-block with-errors"></span>
</div>
</div>
Interesting to note that if I add the following to the <input> element, it takes precedence over the error message declared in javascript:
data-odd-error="Not an odd number, yo!"
However, I get an error in console if I only use the data-odd-error attribute but NO error message specified in Javascript. Thus, you must declare an error message in Javascript.
First of all add your own custom validator, for example:
var validatorOptions = {
delay: 100,
custom: {
unique: function ($el) {
var newDevice = $el.val().trim();
return isUniqueDevice(newDevice)
}
},
errors: {
unique: "This Device is already exist"
}
}
Second, you need to "bind" the form input for the custom validator, for example:
<input id="add_new_device_input" class="form-control" data-unique="unique">
If you want to add to this input more validators error you must to add the custom error to the input: data-unique-error="This device is already exist"
for example:
<input id="add_new_device_input" class="form-control" data-unique="unique" data-unique-error="This device is already exist" data-error="The Device pattern is invalid" pattern="<Add some regex pattern here>">
The "data-error" is the default validator error and it called "native" key, the following code will demonstrate how the validator print the error messages according to the validator key:
function getErrorMessage(key) {
return $el.data(key + '-error')
|| $el.data('error')
|| key == 'native' && $el[0].validationMessage
|| options.errors[key]
}
I am using this Bootstrap validator github.com/1000hz/bootstrap-validator for my bootstrap forms but it appears there is no way to set some external JS conditional before submitting forms.
For example, I would like to do the following from an external JS files:
1 # if form or some input of the form is invalid using validator() then I do some action.
2 # else Users will see some bootstrap button loading message until everything is submitted into the databases.
You can have a single case here:
$('button[data-loading-text]').click(function () {
var btn = $(this);
btn.button('loading');
$.blockUI();
// #1 if form is invalid using validator() then I unblock the please wait message $.unblockUI(); and reset the bootstrap loading button.
// #2 else users will still see the "please wait" message + bootsrap loading button untill everything is submitted into the databases.
});
http://jsfiddle.net/temgo/k07nx06k/12/
Any help will be appreciated as it appears the plugin events are only set for specific field not for full form validation.
Regards
Check out the Events section on 1000hz page. (http://1000hz.github.io/bootstrap-validator/#validator-events)
If you want to fire up the action before validating - just listen to the event.
$('#someFormId').on('validate.bs.validator', function(){
doSomeStuff();
});
Edit
The problem with events is that it is fired after every field. From what I know this plugin doesn't provide an event for finished successful validation.
For your ref hope it will help u
$(document).ready(function () {
$('#contact-form').validate({
rules: {
name: {
minlength: 2,
required: true
},
email: {
required: true,
email: true
},
message: {
minlength: 2,
required: true
}
},
highlight: function (element) {
$(element).closest('.control-group').removeClass('success').addClass('error');
},
success: function (element) {
element.text('OK!').addClass('valid')
.closest('.control-group').removeClass('error').addClass('Done');
}
});
});
I came across this question looking for something else, but I have worked on precisely what you're trying to achieve.
My solution was to use the snippet of code the plugin author gives for binding to the submit button
$('#form').validator().on('submit', function (e) {
if ( !e.isDefaultPrevented() ) {
// put your conditional handling here. return true if you want to submit
// return false if you do not want the form to submit
}
});
Hope that helps someone out.
$(function () {
$("#myForm").validator();
$("#myButton").click(function (e) {
var validator = $("#myForm").data("bs.validator");
validator.validate();
if (!validator.hasErrors())
{
$("myForm").submit();
} else
{
...
}
}
})
Hope with will help.
I am working so much for a better coding with this form validator js plugin.
Follow my code and try yourself:
// Select every button with type submit under a form with data-toggle validator
$('form[data-toggle="validator"] button[type="submit"]').click(function(e) {
// Select the form that has this button
var form = $(this).closest('form');
// Verify if the form is validated
if (!form.data("bs.validator").validate().hasErrors()) {
e.preventDefault();
// Here go the trick! Fire a custom event to the form
form.trigger('submitted');
} else {
console.log('Form still not valid');
}
});
// And in your separated script, do the following:
$('#contactForm').on('submitted', function() {
// do anything here...
})
Consider the following HTML code:
<form id="contactForm" action="/contact/send" method="POST" data-toggle="validator" role="form">
<div class="form-group has-feedback">
<label for="inputName" class="control-label">Name:</label>
<input type="text" name="inputName" id="inputName" class="form-control" data-error="Your input has an invalid value"/>
<span class="help-block with-errors"></span>
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Send</button>
</div>
</form>
you can use validated.bs.validator to hand the event in order to do something after validating the form.
Regards!
I am trying to use the validate plugin on a div as shown in the answer to this question:
<script type="text/javascript">
$("#pseudoForm").validate({
onfocusout:true,
rules:{
first_name:"required",
last_name:"required"
}
});
</script>
<!-- whatever -->
<div id="pseudoForm">
<input type="text" name="first_name"/>
<input type="text" name="last_name"/>
</div>
I have all within a form.
I am getting a bunch of different errors on different browsers.
Firefox: validator in undefined
IE8: 'settings' is null or not an
object
Chrome: Cannot read property 'settings' of undefined
Any help appreciated!
This isn't the answer you want to hear, but the other answer is incorrect (it may have been right when it was posted, but there have been several major jQuery validation plugin changes since then).
The validation plugin is (currently) designed to work on a <form>, and only on a <form>. You can also note that all of the plugin documentation references a form, not any other generic container.
The plugin itself keeps track of validator.currentForm internally, which refers to the this of the passed in selector, getting .elements, etc off that...it's really not going to work any other way, not the way the current version's written.
The overall solution/alternative approach here: call .validate() on the <form> element (the jQuery wrapper for it rather) directly, not any other container. If you need to divide your <form> use <fieldset> elements, possibly using the ignore: ':hidden' option in .validate() if you don't want to validate input fields that aren't visible to the user.
You're missing a closing bracket. Try this instead:
$("#pseudoForm").validate({
onfocusout:true,
rules:{
first_name:"required",
last_name:"required"
}
});
You can get the same error if you select the form by class
$(".form_class").validate(...
instead of by ID
$("#form_id").validate(...
or tag name
$("form").validate(...
Open jquery.validate.js or jquery.validate.min.js and find(ctrl + F) "label" and replaceAll with your your required tag:
Example: div
then perform validation.
//HTML
<div class="form-group has-feedback col-xs-8 " style="padding-right:0px">
<input type="tel" class="form-control" name="Otp_MobileNo" id="mobileNo" placeholder="Mobile No." minlength="10" maxlength="10">
<span id="mobileno_message" style="display:none;color: red;">Please enter a valid Mobile No</span>
</div>
//Java Script
$("#getOtp").click(function(){
jQuery(document).ready(function(){
var MobileNo = jQuery("#mobileNo").val();
var MobileNoLength = MobileNo.length;
var zipRegex = /^\d{10}$/;
var mobileNo = $("#mobileNo").val();
if (!zipRegex.test(MobileNo))
{
jQuery('#mobileno_message').show();
}
else
{
// success!
jQuery('#mobileno_message').hide();
$.ajax({
type : 'POST',
url : '<?php echo site_url('Login/send_otp'); ?>',
data : {Otp_MobileNo:mobileNo,},
dataType : 'json',
beforeSend: function()
{
$("#error").fadeOut();
},
success : function(response)
{
alert(response.message_text);
$("#check-otp").delay().animate({
height: 'toggle',
},
"slow");
$("#getOtp").hide();
}
});
}
});
});