AngularJS: validate ng-disabled / ng-readonly fields - javascript

I scribbled this jsFiddle to describe the problem at hand. Basically I have a form with certain ng-required text inputs. The catch is that the user cannot type inside them, but has to click on a button which opens up a dialog with a list of allowed values; clicking on one sets the input's ng-model accordingly (in my example, the button next to the input sets the ng-model right away, but you get the jist).
Trouble is that if I set ng-disabled (comprehensible) or ng-readonly (this honestly I can't figure out why) the form is submitted even if the field is left empty, whereas I'd like to enforce user input. How could I achieve this? Cheers.

I got around this by adding another input sharing the same model and putting it right below the visible one. You can't just do a hidden input however (either by setting type="hidden" or ng-hide and whatnot), as hiding it entirely won't let the validation show up.
<!-- Normal input: we want this to be required, yet read-only -->
<input id="inputMyValue" ng-model="myValue" ng-click="openSelectionDialog()" ng-readonly="true"/>
<!-- Hidden input: not really hidden - just visible enough for the validation to work -->
<input id="inputMyValueHidden" ng-model="myValue" ng-required="true" style="height: 0; border: 0;"/>

Write your own validation function on submit:
$scope.validateForm = function() {
if ($scope.myDisabledInput === '') {
return;
}
};
I would alert the user somehow, but this should at least point you in the right direction.

Related

How to validate a hidden input field in a form / change validation behavior?

I have a HTML form with several inputs which have the required attribute and thus are automatically validated when the form is submitted. This works fine, but I also have an input field of type='checkbox' that needs to be invisible/hidden due to special CSS styling, which changes a label's appeareance to display a styled checkbox. But this checkbox input field also needs to be validated (it has the required attribute).
So when the form is submitted, the browser (Chrome here) can't focus the invisible field, so it does nothing in the UI and gives the error
An invalid form control with name='consent' is not focusable.
How can I override the form validation to focus the label element instead of the invisible input element when it is invalid? Are there any useful form validation events that I can hook into to change this behavior?
Thanks in advance.
Edit: It's a bit similar to OPs question and this answer here: https://stackoverflow.com/a/23215333/15717315
Edit 2: I can optionally use jQuery.
This is what it looks like currently:
<div>
<input type='checkbox' id='myfield' class='my-styled-checkbox' name='myfield' required>
<label for='myfield'>
The label
</label>
</div>
Edit 3:
Alright, so I added an event listener to the submit event of the form. This successfully prevents the from from being submitted when the checkbox isn't checked.
document.getElementById("myform").addEventListener("submit", function(e) {
var field = document.getElementById("myfield");
if (field.checked) {
field.setCustomValidity("");
e.returnValue = true;
}
else {
field.setCustomValidity("Invalid");
e.returnValue = false;
}
});
But it still throws the same error as in the OP, and the validation message does not display.
It would be helpful if you provided with a code example. Also to know if you are using any framework or library like react, angular, etc.
Css properties like
visibility: hidden;
or
display: none;
do not prevent you from editting the DOM with js code. So you should be able to change the field value before submitting.
Also, if the field is not editable by the user, you could just not make it into a required field and assign it a default value. That way you are certain it will never submit being empty.
Looks like you are trying to focus the field, this is not what you want, you should be trying to just change the field's value with js or jquery.

How to automatically disable a text field after checkbox is ticked

I am currently working on a project, that requires me to implement the following:
I've got 2 input fields - a regular text field, and a checkbox.
What I want to do is - if the user fills in the text field, the checkbox should be automatically disabled. If the checkbox is checked instead, the text field should be disabled.
What I've come up with so far is:
<input type="text" name="num-input1" id="dis_rm" value=""
onblur="document.getElementById('dis_per').disabled = (''!=this.value);" >
<input type="checkbox" name="num-input2" id="dis_per" value=""
onblur="document.getElementById('dis_rm').disabled = (''!=this.value);" >
If I fill in the text field, the checkbox is successfully disabled. However, if I tick the checkbox, the text field remains available.
What am I missing?
If I were you I would:
Move my JS code out of the HTML and into a separate file or at least into a script element.
Use document.getElementById to find an item in the DOM. See https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById
Once you have the element from the DOM, add an event listener for the blur events like this myElement.addEventListener('blur', myCallbackMethod). See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener for more info.
Inside your callback method you can use event.target.checked to see if the element you've added the event listener to is checked.
Here is a little snippet to get you going:
const
textInput = document.getElementById('element-ID-here'),
checkbox = document.getElementById('element-ID-here');
function onTextInputBlurHandler(event) {
// if textinput value is empty then
// set disabled for checkbox to false
// else
// set disabled for chexbox to true
}
textInput.addEventListenet('blur', onTextInputBlurHandler);
<input type="text" name="num-input1" id="dis_rm" value=""/>
<input type="checkbox" name="num-input2" id="dis_per" value=""/>
With this info you should be able to get (a little) further. When you do, update your question with your JavaScript code and I am sure people will be happy to help you further.
People are bringing up great suggestions in the comments and answers for better code design and quality, but from a purely functional point of view, there are two core things that you should do to get the functionality that you are describing:
1) As mentioned by Paul S. use the checked property for your checkbox logic. Right now, you are checking to see if the checkbox value is not an empty string, but it will always be an empty string, because that's the value that you've assigned to the element:
<input type="checkbox" name="num-input2" id="dis_per" value="" <----- *here*
Nothing else in your code is changing that, so it will always fail the logic check.
However, the checked property automatically switches between true and false as you check and uncheck the input. To do the logic check that you are looking for using that, do this for your JavaScript!
document.getElementById('dis_rm').disabled = this.checked;
2) Switch the event that you are binding for (at least) the checkbox to the "change" event instead of "blur". For checkboxes, the "change" event will trigger when you click on the checkbox (or hit space bar), but the element still maintains its focus. The blur event Will only fire once the user moves the focus to another element of the page.
I'd also recommend using "change" for the text field (there's no point in running the check, if the value is the same when you leave the field as it was when you entered it), but it's not as important since, from a timing point of view, when the "change" event fires, it happens immediately after the "blur" event, so, from the user's point-of-view, the behavior would be the same.
When it's all said and done, if you made no other changes to your code to improve the code design/quality (Thijs made some great suggestions, BTW), this is the minimum change that you would need to get the functionality that you want:
<input type="text" name="num-input1" id="dis_rm" value=""
onblur="document.getElementById('dis_per').disabled = (''!=this.value);" >
<input type="checkbox" name="num-input2" id="dis_per" value=""
onchange="document.getElementById('dis_rm').disabled = (this.checked);" >

Text filed and dropdown validation without submit in angularjs

I am validating a textfield and dropdown. Both can be empty or both must be filled. I looked into below sample, but it validates only on button click. I need to validate once the user moves to some another field in the form without filling the text filed and after selecting the dropdown, similar to onblur event. I could not find any samples to my issue. Any pointers to my question ?
I think you can do the trick with ng-touched. It is applied when the element has lost focus.
These class can be combined with Angular validation and a ng-class
ng-class="{'has-error':yourModelObject.$invalid && yourModelObject.$touched}"
To make something like:
<div ng-class="{'has-error':yourModelObject.$invalid && yourModelObject.$touched}"">
<input type="text" ng-model="yourModelObject" required>
<div>

Angular Validation to show all errors on submit

I have a simple example form that will validate a name to be required and 3 letters at least. Nicely display errors as you make the field dirty:
[http://plnkr.co/edit/FEclhN?p=preview]
Our designer wants , however, all the fields that are empty and that are "required" to go "red" as well, when the user presses the Submit button. Right now, unless they have touched and made the field "dirty" the validation doesn't turn the field red.
Of course the field should not be red to start with, only after they Submit the form or they make a field dirty.
jQueryValidate.org does this, so that's what they want in Angular too.
I ran into this same requirement and solved it by adding a boolean onto my controller's scope to indicate if the form had been submitted formSubmitted
And inside my form submit method I would set the value of formSubmitted to true
Then I would dynamically add a class where I needed:
<div ng-class="{'required-error': formSubmitted && formName.field.$error.required}">
<input name="field" required/>
</div>
You can also use this
https://github.com/AngularAgility/AngularAgility
For all controls and error summary in toster.
Its best way to validate and focus on field which causes validation.

mvc 3 razor cannot clear form value with validation class

I'm using MVC 3 with Razor and using unobtrusive client validation. Things are working great, but I want to be able to reset the form if a user decides he wants to start over or cancel his action. It seems that there is a lot of meta data attached to each form element when using the validation.
<input type="text" value="" name="User.FirstName" id="User_FirstName" data-val-required="The First Name field is required." data-val-length-max="50" data-val-length="The field FirstName must be a string with a maximum length of 50." data-val="true" class="text-box single-line">
The jQuery snippet here shows my problem. When you try to manually reset the value of the text field, some other javascript is intercepting execution after I clear the value and it sets it back to what it was:
$("#btnReset").click(function () {
alert($("#User_FirstName").val());
$("#User_FirstName").val("");
alert($("#User_FirstName").val());
});
I'm looking for pointers here on how to clear form values when a user clicks a button. It seems like such a simple task, but I can find no documentation how to accomplish this and I haven't found anything here or elsewhere to help.
I was using an html input of type reset rather than the button type. The reset should not have been used in this case.

Categories

Resources