HTML5 validation: JavaScript weirdness with willValidate - javascript

OK this is a weird one. I'm sure I'm missing something obvious.
http://jsfiddle.net/wVp8j/
HTML:
<form>
<input type='text' required />
<button>check field validity</button>
</form>
JS:
var field = document.querySelector('input[type=text]');
document.querySelector('button').addEventListener('click', function() {
alert('Validates: '+field.willValidate);
alert('Value missing: '+field.validity.valueMissing);
}, false);
If the form is submitted with the field left blank, submission is suppressed, as you'd expect, but the first alert, checking the field's validity state, gives true. Why?
To contradict this further, the second alert confirms there's a problem with the field and also gives true, as expected.
What am I missing?
[Sidenote: MDN seems to think willValidate is a method, not a property.]
[EDIT]
As the commenter below points out, willValidate says whether the field is a candidate for validation, not, despite its misleading name, whether the field will validate.
Which presumably means the only means of telling whether a field will validate, should the form be submitted, via JS, is to iterate over its validity object and see if any flag is set to true.
[EDIT 2]
Turns out you can just check validity.valid on a field, even though the valid flag doesn't show up if you console.log the entire validity object. This would appear to be the way, therefore, to find out whether a field will hypothetically validate.

willValidate is a property that says whether or not an input can be validated, not if it is valid or not. The only time that willValidate is false is if the input element is disabled or the like.
See http://www.html5rocks.com/en/tutorials/forms/constraintvalidation/#toc-willValidate
Use field.validity.valid instead to check for validity.
http://jsfiddle.net/3xFua/
(function() {
var field = document.querySelector('input[type=text]');
document.querySelector('button').addEventListener('click', function() {
console.log('Validates: ', field.validity.valid);
console.log('Value missing: ', field.validity.valueMissing);
}, false);
})();

The documentation suggests using .checkValidity() which
Method Description
checkValidity() Returns true if the element's value has no validity problems; false otherwise. If the element is invalid, this method also causes an invalid event at the element.
while (as #soktinpk's answer correctly states) .willValidate simply flags it as available for validation, not passing validation.
Thus I recommend using this:
function() {
alert('Validates: '+field.checkValidation());
alert('Value missing: '+field.validity.valueMissing);
}
off-topic, alert is a terrible debugging tool. Consider using console.log or debugger;

Related

How to programatically set invalid value in input type=number?

I want to set an invalid value to input element with type=number.
I'm writing unit tests for my component which uses input with type=number and it behavior depends on whether the input is empty or not not. Note that I'm treating invalid values like '1.2.3' as not empty, even though it's value property is ''.
While it's possible for user in browser to enter invalid values like '1.2.3' I cannot simulate it for my tests.
// let input be HTMLInputElement
input.value = '1.2.3';
console.log(input.value); // ""
console.log(input.validity.valid); // true
I would like to somehow set invalid value for my input type=number, so I could test if my component's logic is valid.
You can use
input.setCustomValidity("dummy value");
to make input.validity.valid return false.
For an idea of why this works, see this CodePen. What it does is it sets an error message that indicates the input is invalid. To make it appear valid once again, use
input.setCustomValidity("");

Difference between checkValidity & validity

I've noticed there are 2 ways for an input element validation:
element.checkValidity().
element.validity.valid.
I understand that validity is an object while checkValidity is a function but I don't understand when should I use either one of them and what is the key difference between them.
HTMLSelectElement.checkValidity():
The HTMLSelectElement.checkValidity() method checks whether the element has any constraints and whether it satisfies them. If the element fails its constraints, the browser fires a cancelable invalid event at the element, and then returns false.
ValidityState.valid:
Is a Boolean indicating the element meets all constraint validations, and is therefore considered to be valid.
So the main difference is that checkValidity() will also fire an "invalid" event. If you just want to know whether the value is valid, use ValidityState.valid. But if you want to change the form state to invalid, use checkValidity().

Meaning of JavaScript form validation code?

I have to explain how a specific Javascript code validates a web form, but I am stuck with what some of the features do, most specifically this section of the code. I understand that the first line defines that the rest of the section should only run if the field Field1 of the form ExampleForm is left empty, but I do not know what purpose the rest of the code serves. All I know is that msg is a variable created earlier in the document with an empty default value, and that result is another variable with a default value of true. Can anyone help me out by explaining what each line does?
if (document.ExampleForm.Field1.value=="") {
msg+="You must enter your name \n";
document.ExampleForm.name.focus();
document.getElementById('Field1').style.color="red";
result = false;
}
In plain english:
If the document form field value is equal to an empty string, set the error message to msg, then focus on the element, and give is a red color so the user knows it's an error, and set the result to false, for whatever you're going to use that for later in your code/function.
So this would in part depend on what other code is on the page. For example document.ExampleForm is not part of the DOM and seems to be something someone kludged onto your page.
Overall I would say this is pretty bad code that makes a ton of assumptions that won't necessarily hold up written by someone who doesn't understand in-browser javascript very well, but let's go with it
//if the value in this variable is falsy (false, empty, or 0)
if (document.ExampleForm.Field1.value=="") {
//Append this to the msg string. Note \n is usually used
//to indicate "new line" but wont' do anything on the web since that's not how line breaks
//work on the web
msg+=”You must enter your name \n”;
//Invoke the `focus` field on this variable. From the context I assume this is
//a DOM node so you are basically focusing it in the browser
document.ExampleForm.name.focus();
//Set the font color of '#Field1' to red
document.getElementById('Field1').style.color=”red”;
//Presumably result is something that tells you true/false did the validation succeed.
//set it to false to indicate failure.
result = false;
}
My guess about what document.ExampleForm is that it depends on some undocumented behavior of an old browser to add anything with id=ExampleForm to the document element. But really I have no idea. Maybe you have some code elsewhere that creates that variable. Either way its a horrible idea and should get someone yelled at.

Unable to save changes made to entity when calling javascript function through custom ribbon button event

I'm trying to create a simple function which, when ribbon button is pressed, sets entity attribute value to null.
Now the problem I am facing is, that the changes I make to the entity are not saved, form reloads and returns previous value.
To the button event I pass 'Task' activity attribute 'actualend'. 'Actual End' field is disabled by default.
ClearField: function (field) {
if (Xrm.Page.getAttribute(field) == null) return;
Xrm.Page.ui.controls.get(field).setDisabled(false);
Xrm.Page.getAttribute(field).setSubmitMode("always");
Xrm.Page.getAttribute(field).setValue(null);
if (Xrm.Page.data.entity.getIsDirty()) {
Xrm.Page.data.entity.save(); //also tried addOnSave(function)
}
}
Following debugger I was able to track that all changes are made correctly, except that on save() method they are 'discarded', then form reloads with previous value. This code works fine with CRM UR8 yet with CRM UR13 it does not.
Am I missing something?
As Guido mentions in his comment the code looks good which leads me to think that one of your two if statements is failing.
The first one obviously will fail if it is set to null. A little bit less obvious is that it will fail as well as if the field is not actually on the form (even though it may be a valid attribute of the entity). So step 1, ensure that your field exists on the form.
The second one I'm not sure of... I don't think getIsDirty() is keeps track of programmatic changes, so even though your programmatically updating a field and setting it to always submit, it may be returning false. Regardless of how exactly it's working, the if statement really isn't needed. The Xrm.Page.data.entity.save function will only actually save if it has some value that has changed, so I'd remove your dirty check regardless.
Eh, the problem with my issue all this time was that even though the field existed in the form, it never had an entity passed to it, therefore it was unable to save it. I've edited a ribbon button so to pass entity through CrmParameters and the issue was gone. Thank you both for supplying me with possible solutions regardless!

Getting the value of a HTML5 number input

I'm using one of the new HTML5 input types, number:
<input type="number" />
In Opera, which is the only desktop browser I know of which currently recognises it, it renders it as such:
The problem I'm facing is one of validation. If a user types something invalid into the field, eg: "abc", the value returned by myInput.value is an empty string. This makes it impossible to tell whether the user left the field blank, or if they entered some incorrect data. Is there any way to get the real value of the field?
The HTML5 draft defines:
The value sanitization algorithm is as follows: If the value of the element is not a valid floating point number, then set it to the empty string instead.
Reference1
I suppose you'd have use a default value of "0" to make sure the field was left untouched or if something invalid was entered, since there seems to be no obvious way to differentiate the two.
After reading up validation specs and some testing (in Opera 10.54) I concluded that:
<input id="email" type="email" value="blah">
document.getElementById("email").validity.typeMismatch // True
Doesn't work on <input type="number">. Not sure if it's supposed to, or if it's a work in progress. The property does however exist, though it always returns False.
Read more2
You can also set a custom validation method Reference3

Categories

Resources