Form-level ng-change in Angular? - angularjs

How can I check for any field changes in a form? I would like to only enable a Save button if the underlying object has changed. Currently, I'm adding a ng-change="vm.formChanged()" attribute to every single field on the form. I would much rather do this once at the form level and not decorate every single field.
My method looks something like this:
formChanged () {
vm.hasChanges = (JSON.stringify(vm.item) != JSON.stringify(vm.original));
}
... and I'm binding the Save button to ng-disabled="!vm.hasChanges".

Assuming you have given a name to your form you could do something like this:
<form name="myForm">
<input type="text" ng-model="form.name">
<input type="text" ng-model="form.age">
<button ng-disabled="myForm.$pristine">Submit</button>
</form>
This will just disable the button as long as the form is pristine. Once the model has changed it will enable the submit button. However, note, if you undo your change to a field, the button will still be enabled since angular assumes the form is no longer pristine.
Here is a link to a working example: http://plnkr.co/edit/RYJIrZ3m4b8jmd0oVIuh?p=preview

You can use "yourForm.$pristine" to check if form has been monified

Related

How to make required work on a custom directive?

My custom directive looks like
<cities-directive name="cities" ng-model="obj.cities" required></cities-directive>
The required directive does not work. Initially obj.cities is an empty array. How do I make it compulsory for the user to select at least one city so that obj.cities is not an empty array? Basically this directive is inside a ng-form and I dont want the form to be submitted if the array is still empty.
According to this , you can only use required on 3 types oh html markup :
TextArea
Input
Select
For what you are trying to do, there are some basic solution :
If your custom directive template consists in an input, then you can try to modify your directive so you can use it as an attribute or a class and not as an element. (See A, E and C restrictions). Then apply your directive to a select or input markup.
You can simply use ngDisabled on the button of your form submit to prevent the user to send the form if obj.cities is empty.
<form>
<button ng-disabled="obj.cities.isEmpty()"> Submit </button>
</form>

In Angular, how do you check if a form (or its elements) have changed in value?

I'm aware of properties like $pristine, $dirty etc. However, $dirty simply indicates if that form element has been interacted with.
How do I check if that form element has been actually changed?
I need something like a $changed property on the element that indicates if the value of that input (or in the case of a form, any child input) has been updated. If the value is set back to the original value, I want $changed to be set back to false.
My question: does angular have something like this already? If not, how do I go about building such functionality?
You will need to store the form data, watch and then compare. This directive seems to that does that with a "modified" property which sounds like your "changed" property you are looking for. They have a plunker to test.
You could use a watch but if you want to re-use the code repeatedly you will need to create a directive to do the heavy lifting.
https://github.com/betsol/angular-input-modified
You can use $watch like so:
In your controller:
$scope.$watch('myForm', function(){
console.log('Form Changed')
},true)
In your HTML:
<form name='myForm'>
<input type="text" placeholder="Enter new name" ng-model="myForm.inputText" />
<input type="text" placeholder="Other" ng-model="myForm.inputOther" />
<input type="submit" />
</form>

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

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>

angular form validation - ng-valid to start

I'm using angular-auto-validate and am having some state management issues. I have a multipart form where some fields are required (name/email address) and the user is able to go "back" to change answers. Basically, I have a partial for every stage in the form which is working well, with one exception. The continue button is disabled if the field is invalid. I tried simply using the $valid identifier, but when the partial loads, each field begins with ng-valid so I can either use $touched or $pristine. Problem is, when the user goes back, the value that has binded to a data source is valid, but the field isn't touched so the continue button doesn't activate. Sample code (this is generated code after I've hit the "back" button):
<input type="text" name="name" ng-minlength="3" ng-model="myModel" placeholder="Your First Name" ng-focus="inputFocused()" ng-pattern-err-type="" ng-model-options="{updateOn: 'blur'}" class="ng-valid ng-valid-pattern ng-valid-minlength">
and the button:
Continue
How can I either disable the default ng-valid or identify a condition where the value is being populated by the controller?
I think you should use ng-dirty/pristine. You can manually set the condition of the form as the user navigates.
When you populate your form data you can do something like:
if($scope.myForm.data) {
$scope.myForm.$setDirty
}
Your button:
Continue

How to reset the focus after resetting the form to pristine state?

I have a field that has autofocus attribute
<input placeholder="ID" type="text" name="searchId" autofocus
data-ng-model="vm.searchCriteria.searchId" data-ng-required="vm.isSearchIdRequired"
data-ng-minlength="1" data-sr-maxlength="{{vm.searchIdMaxLength}}" data-sr-numberonly
data-ng-class="{'input-error': vm.isSearchIdValid}"
data-ng-change="vm.onSearchIdChange()">
and I have a clear button that resets the form to initial state via reset function on the controller
function reset() {
$scope.searchForm.$setPristine();
$scope.vm.reset();
}
Everything works fine, except the form is not focusing back to the searchId field. What is the proper way to handle this? Do I need to write a directive and use it instead of autofocus?
autofocus is an html5 input attribute that only focuses a field when a page is loaded. It does not re-trigger when a form resets or when a field is added dynamically using JavaScript.
So yes, you would have to write a directive for it.
Maybe you can use
https://github.com/hiebj/ng-focus-if
and have "searchForm.$getPristine()" as criterion?

Resources