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.
I have a form, in the form there is a custom component that has certain fields in it. At the end of the form there is a button. The button has...
disabled.bind="!(formValid && subFromValid)"
Now, on the custom component I have a two-way binding of a variable "subFormValid" The subFormValid is only valid when the validation in the custom component is valid. So, the sub form validates some fields and sets subFormValid = true. Even though the "formValid" is false, the button is now enabled.
I can't figure out why and it is driving me nuts. I even went so far as to add a get function to a variable and add console logs in it, like so...
<button type="submit" disabled.bind="wholeFormValid">Submit</button>
Then in my class I have...
get wholeFormValid() {
console.log("validating form");
console.log(!(this.formValid && this.subFormValid));
return !(formValid && subFormValid);
}
I get a million plus lines in the console, but I was able to watch it, the entire time. When I first load the page it was logging...
validating form
true
Then I filled out the subform, and checked the console. The console showed...
validating form
true
Yet, the button was now enabled.
For some reason whenever subFormValid = true, the button is enabled, regardless of formValid.
Does anyone know how to disable a button unless 2 conditions are met? Everything I do enables the button as soon as subFormValid is true, even though the console is still logging "true", which should disable the button.
Just to help out, if anyone is wondering why there is a subform in the form it is because the address needs to be validated using Smarty Streets and we want to be able to reuse that part of the form in other places, so I created a custom component for the address section that validates the input, and validates the address. It is being called in the form like so...
<require from="components/smarty-streets"></require>
Then using like this...
<smarty-streets form-is-validated.two-way="subFormValid"></smarty-streets>
Then in smarty streets I have...
#bindable formIsValidated;
and I change the value from true to false and vice-versa depending on the validation in the component.
I have tried to recreate your problem using the following:
<input type="checkbox" checked.bind="formValid"/>
<input type="checkbox" checked.bind="subFormValid"/>
<button disabled.bind="wholeFormValid">Submit</button>
I noticed in your function that you used this.formValid in the console.log line, but in the return line you used formValid, without this. This seems to be a different variable than your actual binding variables. I think your function should look like this:
get wholeFormValid() {
console.log("validating form");
console.log(!(this.formValid && this.subFormValid));
return !(this.formValid && this.subFormValid);
}
Edit: I also strongly recommend using the #computedFrom decorator on your get() to reduce the amount of calculations aurelia does. You can read more on that here.
I am using jquery validate plugin to validate form fields . I am also using jqtree . on click of every child node a section of form is visible to user, which is supposed to be filled with values.For every child there is a form content to be filled. Entire tree content is declared within one form only. I have a button in the form which on click generates json file. I am calling the function below to validate form
$("myform").validate();
....
if($("#my-form).valid())
generate the json file
but this is not validating the entire form. suppose I am on childNode1 it validates only form section defined for childNode1. As far as I have understood jquery validate plugin should validate entire form when correct form id is specified. But can anyone tell me what has gone wrong in my approach?
The .validate() method does not "validate the form". It only initializes the plugin on the form. .valid() will programmatically trigger a validation test.
Your code:
$("myform").validate();
....
if($("#my-form).valid())
generate the json file
$("myform") - Is that supposed to be an id, class, or name? As you've written it, it's looking for a <myform></myform> element.
$("#myform") // id="myform"
$(".myform") // class="myform"
$("[name='myform']") // name="myform"
Is your form element called myform or my-form? If it's the same <form> element, then the two jQuery selectors would be the same.
$("#my-form) is missing the closing quotation mark.
If the id of the <form> element is "myform", then your code should be...
$("#myform").validate(); // <- initialize the plugin
....
if ($("#myform").valid()) { // <- test the form's validity
// generate the json file
....
}
OP Title: jquery validate plugin, validating form fields of only current screen
Your question does not seem to have anything to do with the title. There is only one form described in your OP, and since this is JavaScript, only the page that's loaded in the browser is relevant. Not sure what you mean by "current screen".
but this is not validating the entire form. suppose I am on childNode1 it validates only form section defined for childNode1. As far as I have understood jquery validate plugin should validate entire form when correct form id is specified.
By default, the plugin will not validate any form fields that are hidden. You would manipulate the ignore option to over-ride this behavior. Setting ignore to [] will tell the plugin to ignore nothing and validate all fields including the hidden ones.
The jQuery validation engine plugin has the ability to do ajax validation; which works gret except for one small catch...
It sends off the field ID instead of the field name to be validated.
Why is this an issue?
I have a simple item that to create it only requires one textbox to be filled out; so we have this as a modal on every page for managing said item.
We use the jQuery validation engine plugin to validate that the entered value is unique.
Now this also means that the modal shows up on the edit page. Which obviously has the title in a field as well for you to edit.
And we want this field to be validated as well but because the validation engine sends across the field ID instead of the field name we must give the two fields different ID's
e.g. createtitle and edittitle and then on the backend have
if($fieldId == 'createtitle' || $fieldId == 'edittitle'){$fieldId = $fieldId}
Which really is an ugly approach; is there any way to get it to use the name; or another attribute instead?
Maybe this plugin could help you. It uses class names of your element to validate.
I’m using Sys.Mvc to count errors and I have added my own custom validations by jQuery.
var validationErrors = Sys.Mvc.FormContext.getValidationForForm(this).validate('submit');
var errorsCount = validationErrors.length;
And also I have some fields, which will by hide (by using jQuery .hide();)
Question: How I can remove errors from Sys.Mvc.FormContext if the required element is hidden and add the error if the element is appearing again?
OR
How I can ignore hidden elements validation errors?
Best regards Paul.
Try to initialize the field even if it is hidden (using jQuery), and insert a temporary value. after submitting the form - you can insert the right value into the hidden fields (in the controller).
Something like this:
$("#myField").hide();
$("#myField").val("temporaryValidValue");