Form is not being set to $dirty even though input is being edited - angularjs

I am using angular-unsaved Changes directive as well as the angular built in form controller to detect if a form is $dirty.
I have a form on a specific page that even though I edit elements, the form never registers as dirty. I have gone so far as to strip everything and leave only:
<form unsaved-warning-form class="form-horizontal" name="WHAT">
<input type="text" name="thematif" id="thematiff" class="form-control" >
</form>
The formis never $dirty even when I change the value of the input. Any ideas what the problem could be causing the changes to input not to be detected? Is it that there should be an angular input equivalent tag instead of a plain old "input"?
What could be disabling the detection?

Ng-model is missing on your input field.
Validations and all form enhancements are provided by utilizing ng-model directive (and its controller). So add ng-model and everything is Ok.
See: http://jsbin.com/podepo/edit?html,output
<form unsaved-warning-form class="form-horizontal" name="WHAT">
<input type="text" name="thematif" ng-model="whatever" >
<pre>{{WHAT|json}}</pre>
</form>

Related

How can we make autocomplete=off for password input in angular js?

I am completely new to AngularJs. I need to make autocomplete=off for a password input.
Is autocomplete=off the only way or do we have to do it in some different way in AngularJs?
This doesn't nothing to do with AngularJS at all, but simply html.
Regarding to your statement, password fields shouldn't be autocompleting if they are set to type password, otherwise if you want to set a specific field inside a form to autocomplete off you can do it setting that property to false like this <input autocomplete="on|off">.
This can be defined at form level or at input level. In a form it would be like this:
<form action="" autocomplete="on|off">
</form>
Also you can define it in a form level, and override the behavior for some specific inputs like this:
<form action="" name="myform" autocomplete="on">
<input autocomplete="off" name="myInput" >
</form>
In the above code, in the form myform the autocomplete is on, it means all inputs (the one which allow it) will do autocomplete, but in the input myInput will not, since it overrides the form behavior.
More info can be found in The HTML autocomplete attribute
This should be sufficient:
<input type="password"
autocomplete="off"
placeholder="password"
ng-model="vc.password">
I added the autocomplete="off" just for redundancy but it seems completely unnecessary.
jsbin - https://jsbin.com/bowuxopese/edit?html,js,output

Angular - Firing message onBlur after user edits field

Like others, I have been looking for a good way to validate my forms with Angular without the messages being too aggressive. The closest I have gotten is checking for $dirty and $touched prior to firing the messages. Which works for most situations.
The one situation I can't figure out is when the user edits, for example, a required field. The field has text in it, is valid, dirty, and touched. The user goes back into the field to change it. They backspace what is in the input and immediately the message fires because the input is now dirty, touched, and invalid. I'd rather it "reset" at that point and reevaluate when the user blurs the input again. Give them a chance to fill in the input while it's still focused.
Make sense? Any ideas?
Thanks!
Matt
Perhaps this works:
ng-model-options="{ updateOn: 'blur' }"
Add it to your input element. I believe the validation will occur when the model is updated, this way the model gets updated on blur.
Here you can see more options for this directive: https://docs.angularjs.org/guide/forms in Custom model update triggers. And a more detailed explanations in ngModelOptions.
Let me know if it works :)
Use function on ng-blur to validate and show messages if invalid.
ng-blur="validate()"
In your controller -
$scope.validate = function(){
//Validate logic
//If invalid
//Show message logic here
}
Take a look at the ngMessages documentation:
https://docs.angularjs.org/api/ngMessages/directive/ngMessages
You have an example there that shows you how to use it:
<form name="myForm">
<label>
Enter your name:
<input type="text"
name="myName"
ng-model="name"
ng-minlength="5"
ng-maxlength="20"
required />
</label>
<pre>myForm.myName.$error = {{ myForm.myName.$error | json }}</pre>
<div ng-messages="myForm.myName.$error" style="color:maroon" role="alert">
<div ng-message="required">You did not enter a field</div>
<div ng-message="minlength">Your field is too short</div>
<div ng-message="maxlength">Your field is too long</div>
</div>
</form>
I think this is the best way to do it (at least it's how I do it).

AngularJS ng-required better implement from controller?

I'm thinking of a good way to implement ng-required.
Let's say I have a bunch of inputs with ng-required in my app.
<input type="text" id="one" />
<input type="date" id="two" />
<input type="radio" id="three" />
<input type="checkbox" id="four" />
I would like to do something in a controller, where I could pass an array of required fields. I'm thinking that if I made an array of elements such as:
var myEl = angular.element( document.querySelector( '#some-id' ) );
and some how set the required property that way.
I write a directive which would decide from an array if the field is required, if it does not exist in the array, it's not required if it does, it's required.
Ultimately, I would like to have an array that allows passing of fields in such a way:
var reqArray = ('#id', ('#id1' || 'id2')) etc.
Works the same as conditional logic operators:
#id is required
#id1 || #id2 is required, but not both.
Not sure where to begin, or if it's feasible in Angular.
This would make it easier to modify required fields in large applications without having to modify the actual html.
It can be done, but angular already provides its own ways to validate forms. Some brief details:
The form tag must have a novalidate attribute in order to prevent HTML5 validation. <form name="myForm" novalidate>
With that, now angular can take charge of the validation by adding a "required" attribute to your inputs <input ng-model="myModel" type="text" required>
By this point, angular has taken control of your validation, it can also validate other HTML5 attributes like pattern. <input pattern="[0-9][A-Z]{3}" type="text" title="Single digit followed by three uppercase letters."/>
I suggest you take look at this official guide (also take a look at the directives guide on that same site, I wanted to link it but I don't yet have the rep).
That being said, what you are trying to accomplish is also possible, but rather redundant since you would have to add an attribute to your inputs anyway (the directive, and angular is able to validate already) and also require ngModel in the directive.
I made this plunkr to show you how to do it, but take notice of the extra work needed in order to validate something that angular already does natively, I'd leave this kind of work for expanding on validations, like comparing items or models.
Also, querying a selector directly like in your suggestion is not considered "the angular way". A better way would be to add the directive to your form element and access the element through the 'element' parameter in the directive.
Hope this helps.

Angular form.fieldName.$invalid not working inside ng-class attribute

I have already solved this problem, but it took me a while to realize what I did wrong. It's a very simple mistake, but I figured I'd post it here in hopes I can save someone else some work in case they run across the same mistake.
I was trying to use simple Angular validation to set a class on an input field based on whether it was valid. I failed to realize it wasn't working because I specified the name of my form with ng-form. So using $scope.form or the actual value of name attribute of the form did not work. Of course, the examples below are simplified and a much larger form could make this mistake much harder to recognize.
Here is a failed example:
<form name="myForm" ng-form="form1">
<input type="text" name="myField" ng-class="error: myForm.myField.$invalid"/>
</form>
Here is a successful example:
<form name="myForm" ng-form="form1">
<input type="text" name="myField" ng-class="error: form1.myField.$invalid"/>
</form>

Angular - binding data a form

I have a form that POST all data that is entered, when saving. But when I refresh the page, not all entries are bound to their respective input fields.
It is a bit strange because I am using ng-model on all the fields.
Here is an example of what doesn't bind:
<input name="full_name" ng-model="user.full_name" type="text" required></input>
and here is one that does bind:
<input name="address" ng-model="user.address" type="text" required></input>
Has anyone run into this issue, or notice something I may be missing?
It could be the browser remembering your last input in the forms. So after refreshing, the browser pre-populates the form and angular doesn't update the scope. There is a Google Groups thread about that. The best solution I found is to add autocomplete="off" in the inputs of the forms. Because after refreshing, there is no way angular could be remembering your last input in the form, unless you are using cookies for that wich you are obviously not.

Resources