jQuery "live" validation of form - javascript

I have recently completely recoded my site registration form, a lot of my users were complaining that upon registration, they would fill out the form only to be told that the username was already taken, or some other error that meant they would have to retype all of that information.
I set off today designing and coding the new registration page, and the resulting response from my users is that it looks more user friendly, and when the "live" validation is included, it will be just right.
Anyway, here is how my registration page looks, with the location of the divs that will contain errors;
For each area of the form, I have added the same div class next to it, which I hope I can then hide / unhide depending on what the user has typed in.
My issue is, surely if I use that same class for ALL of the fields, it will update ALL of the error fields when I use something like the innerHTML function?
jQuery is far from my strong point, and I would really appreciate any help. I will add more information if it is requested, thanks!

Why not give each field an id and use the selector #whatever instead of .whatever to access each specific field?

basically you validate on events like keyUp or blur and when the validation finished you traverse the proper div by going up from the input element to the element that contains both, the input and the error div and then search for the error div by it's class. this way you'll be sure to only avitvate the error for the proper element.
assuming the element surrounding the input and error div (and propably label etc.) has the class element and the error div has the class error
$('input').blur(function() {
// on error:
$(this).parents('.element').find('.error').text('Some error occured').show();
});
if you validate using ajax the on-error stuff needs to be in the ajax callback ofc...
also need the same routine for successful validation: remove text and hide error div...

Related

Is there an HTML5 validation API to set the state of an element to be invalid?

I don't want to use the HTML 5 validation API but for one thing. I will do my custom validation using JavaScript but I would like to use the nice tool-tip like thingy that the browser uses to display the validation message.
So, in short, I'd like to selectively use the element.setCustomValidity("my own message") in my own event handler, so I can avoid using a third-party tool-tip.
However, even though I set the custom validity, it won't display until I somehow invalidate the state of the controls.
If I call into the validation API (element.checkValidity()), it will start doing its own in-built validation looking for attributes on my HTML elements. But I don't want any of that.
function submitEventHandler() {
let errors = myOwnValidateFunction();
if (errors && errors.length > 0) {
let txt = document.getElementById("txt");
txt.setCustomValidity("No, no, no, no, you're doing it wrong!");
// Is there a way to invalidate an HTML element?
// ...???
}
}
Well, as always, each browser simply act differently on pretty much any new API.
To invalidate an input, its enough to set this: input.setCustomValidity('just an error');, this will let the browser know this input have an issue with it.
HOWEVER each browser will do its own things:
Chrome - Won't show any error until you try to submit the form, only than it will let the user know that the first field with an error have an error, it will ignore the rest of the inputs with errors.
Firefox - will show your custom message and highlight the input in red right away after you set it, you don't need to wait for a submit to show the errors, when submit is clicked it shows a different tooltip on the invalid input.
Edge - Will show an tooltip with custom message only after the user hover over it, and will highlight in red with different tooltip after submit
Didn't test it on other browsers, but i'm sure each browser will use its own way of showing the error, some might wait for submit, some will show right away, but all who support this API should invalid the input after you input.setCustomValidity('Some error message')
This is why you might consider showing your own tooltip to avoid this browser dependency, and make sure its working the same way on all of them.
https://jsfiddle.net/q60bwteL/17/
Update
You don't need to set any type, and the validation above works the same way for type='text', i'm not sure what you see, but the code snippet below have 2 inputs, 1 with no type and 1 with type='text', both works.
You can create a fiddle with your issue so I could take a look, but as you can see from the fiddle, its working for all type of inputs:
https://jsfiddle.net/q60bwteL/21/
But again, note that it works differently on different browsers, chrome only shows the first field with the error, not all of them and only on submit, while firefox shows errors for all of the fields (if have multiple errors) and before you click on submit.
This is why I personally never trust the implementation of the browser with stuff I could do on my own, it is very easy to implement a basic error handling stuff, from the question you already have it, you simply need to add the styling and the tooltip to it, there are many ways to create a tooltip with CSS alone on the web (for example: https://stackoverflow.com/a/25391104/8727608).
Create a function that will handle your error things:
function setError(inputElement, errorMessage) {
inputElement.setAttribute('title', 'errorMessage');
inputElement.classList.add('errorInput')
}
Create a function that will remove all the error things:
function removeError(inputElement) {
inputElement.removeAttribute('title');
inputElement.classList.remove('errorInput')
}
And style the errorInput class as you wish with CSS.
Now I assume you only return the errors in array of strings with the error messages, but you can use an array of objects that each object contain the error message and the input element which have the error:
if (errors && errors.length > 0) {
for(var i = 0; i<errors.length; i++) {
setError(errors[i].element, errors[i].message);
}
}
Before you validate the input simply call the removeError function and don't forget to return false when you submit if there are errors. (as you already do)
UPDATE 2
I don't know why I didn't think of it. but there is a way to stop validation and start it when you want:
Adding the novalidate attribute on the form will let the browser know that you don't want to perform a validation on that form, so this won't show any errors and will handle submit as you like it to.
But you still want to use that validation and for this you can call the reportValidity() on the form element, basically this function enable the validation on submit, it doesn't matter where you call it, it will run the validation when submit is clicked BUT this will show only the first input with the error message and not all of them (even on firefox), it looks like there are 2 states of validation, the before and after submit, not sure why, but those are 2 different checks, and you can only control the after submit check, not the before.
check this fiddle: https://jsfiddle.net/q60bwteL/64/
So you can control when you do the validation, but there are 2 types of validation, before and after submit, you can control only after submit, and it only show the first input error not all of them.
Do we like it? no, why its like that? I have no idea, to be honest, it really looks like the firefox developers simply break the loop after first error is found.
P.S - after thinking about it, they simply implement the title attribute tooltip method, but because only 1 element can be hovered or focused they can only show 1 error message, this is how tooltips works.

Place Error Messages for the same field in different Locations jquery

So I am doing a required check and a digits check on the same input field. I have the error messages appearing however I want the required message to appear to the right of a div and digits error message to appear at the bottom of the page. I thought I could achieve this by doing if (error[0].innerText == "This Field is required") then place to the right of the div and if not put else where, however it is not working. If I enter an invalid response to digits it will put the required error message at the bottom of the page from then on and vice versa for if I leave the field blank at first.
I am very confused on why this would be happening and any help would be appreciated.
You can use jQuery on error function
$('.class').error(function(){
//When .class having an error do this
$('.errorMessage).addClass('show'); /*Maybe*/
});
did you thought on use bootstrap? I used and it was the best option for a clear code
go to this link
http://getbootstrap.com/css/?#forms-control-validation
Found the answer in another stack over flow post. Apparently errorPlacement is called once per element which is why it was not updating. Here is the stack overflow post that resolved this for me: jQuery Validation Plugin: Invoke errorPlacement function when onfocusout, keyup and click

Refocus input field after page gets refreshed in wicket

Is it somehow possible to refocus an input field after a refresh which was last focused before the page was requested?
I have a Wicket Form within my WebPage and in this Form there are quite some input fields (like text fields) the user can use to filter my data view. But when the user for example has the focus on the second input field and then clicks on 'go to next page' within the data view he loses the focus, but due to accessibility it is necessary to refocus the second input field.
My idea was to first tag the input field with jQuery with "regain-focus" when focused:
$("input").focus(function() {
$("input").removeAttr("regain-focus");
$(this).attr("regain-focus", "regain-focus");
});
Then on server update search for the element with the "regain-focus" tag - but that's the part, I don't know how to do that... - tag the corresponding component with "autofocus":
input.add(AttributeModifier.append("autofocus", "autofocus"));
and refocus with javascript:
$('[autofocus]').focus();
Since you have JavaScript experience it would be much simpler to do it completely client side: $(document).on('focusin', 'input textarea', function(event) {localStorage.setItem('focus:'+location.pathname, event.target.id)}) and then use jQuery.ready() based logic to read the entry and use it.
When your page DOM/elements change between requests/refresh/ajax calls, it is better to use a CSS selector using optimal-select to store just a unique identifier for the element and use a JQuery selector to find it again for focus setting. I used this in the NoWicket web framework to remember the focused element on ajax calls. Example JS code here.

custom css error class not applying for the fields jquery validator

I have a form which contains two file input and two check box and one submit button. With my current code when the user click submit button the jquery validation will work perfectly but the problem was the custom error class was not applying and not removing correctly for example if the user click the check box that particular errorClassshould be removed this was not happening. When i search through SO I got one use full information it was mentioned instead of using border red for the check box or if the upload any file that particular field errRed class should remove and I try using outline-color but this was also not working. It might be simple somewhere I am missing some bit of code
I tried giving $('.chk_requ').removeClass('errRed_chkb'); still no use
Here is the fiddle link
kindly please help me.
Thanks in Advnace
Instead of remove class you can add empty div with id="diverr" there and give it desplay:none;
$("#diverr").text("Please select Gender");
$("#diverr").css("display","list-item");
if condition is false then
$("#diverr").css("display","none");

Getting two errors using Parsley.js to add validators to fields that are dynamically cloned

I have a form which I am using Parsley.js to validate. Everything works like a charm. Except, there is a part of the form where users are allowed to add new fields:
addFieldsToContainer = function($fields, $container) {
$fields.clone(true).removeClass('empty-form').appendTo($container);
if (typeof(Parsley) !== 'undefined'){
$('form.form-horizontal').parsley().destroy();
addValidatorsListeners();
}
};
My validations are a little complicated, because there are sections, and in each section, the inputs must all add up to a total number, which is the value of another input. I've got the inputs triggered to blur, and if any of the inputs are entered and the total for the section is wrong, all the inputs for the section are given the parsley-error class, and vice versa. Now, on the new input that is being added to the DOM, the parsley ui is not working on it, i.e. the parsley-success/error classes are not being added to it. But the rest of the section still works fine, and even includes whatever number is in the input in the total calculation. I'm also seeing these two errors in the dev console:
Uncaught TypeError: Cannot set property 'validatedOnce' of undefined parsley.min.js:8
Uncaught TypeError: Cannot read property '$errorsWrapper' of undefined
My code here.
How can I correctly bind these new inputs to the parsley validator?
Edit:
So I just realized that the when the user clicks the add input button, all of the inputs that have parsley:success/error classes have them all removed (because of model_form.parsley().destroy() I assume?) except for the new input that has been added. This input class never changes with the rest of the section, as I've pointed out. Also, the total enrollment input doesn't change, I'm guessing because of the { excluded: '[data-parsley-sum-total="all"]' } line. So it looks like the input that is being cloned from the page isn't having it's binding destroyed or it's validators correctly added, so some sort of event handling problem?
Maybe related?
If you clone Parsley's elements with their data, yeah, Parsley will be confused as hell.
I'd simply recommend not doing that. More precisely, clone without the data and events, or else clone before binding with parlsey.
If you really have to go this way, you might be able to get away with cloning afterwards if you $yourClone.removeData('Parsley'). I haven't tested it and can't guarantee that even if it works now it would in the future.

Categories