I have my form like this:
<form name="myForm">
<input name="myText" type="text" ng-model="mytext" required />
<button disabled="{{ myForm.$invalid }}">Save</button>
</form>
As you may see, the button is disabled if the input is empty but it doesn't change back to enabled when it contains text. How can I make it work?
You need to use the name of your form, as well as ng-disabled: Here's a demo on Plunker
<form name="myForm">
<input name="myText" type="text" ng-model="mytext" required />
<button ng-disabled="myForm.$invalid">Save</button>
</form>
To add to this answer. I just found out that it will also break down if you use a hyphen in your form name (Angular 1.3):
So this will not work:
<form name="my-form">
<input name="myText" type="text" ng-model="mytext" required />
<button ng-disabled="my-form.$invalid">Save</button>
</form>
myForm.$invalid
should still work, so in your case, I would think my_formset_name0.$invalid
should work.
Selected response is correct, but someone like me, may have issues with async validation with sending request to the server-side - button will be not disabled during given request processing, so button will blink, which looks pretty strange for the users.
To void this, you just need to handle $pending state of the form:
<form name="myForm">
<input name="myText" type="text" ng-model="mytext" required />
<button ng-disabled="myForm.$invalid || myForm.$pending">Save</button>
</form>
!myForm.$valid
that handles async Pending issues as well. itnext.io/valid-and-invalid-in-angular-forms-61cfa3f2a0cd
If you are using Reactive Forms you can use this:
<button [disabled]="!contactForm.valid" type="submit" class="btn btn-lg btn primary" (click)="printSomething()">Submit</button>
(click)
and [disabled]
aren't valid AngularJS code, nor are Reactive Forms a part of the AngularJS framework. "Angular is the name for the Angular of today and tomorrow. AngularJS is the name for all v1.x versions of Angular" angular.io/guide/ajs-quick-reference
We can create a simple directive and disable the button until all the mandatory fields are filled.
angular.module('sampleapp').directive('disableBtn',
function() {
return {
restrict : 'A',
link : function(scope, element, attrs) {
var $el = $(element);
var submitBtn = $el.find('button[type="submit"]');
var _name = attrs.name;
scope.$watch(_name + '.$valid', function(val) {
if (val) {
submitBtn.removeAttr('disabled');
} else {
submitBtn.attr('disabled', 'disabled');
}
});
}
};
}
);
ng-disabled
in angular 1.x and [disabled]
in angular 2|4.x that are much better tested than this?. Secondly, why have a directive that is scoped to a form to disable a nested button, it's super specific. An ill thought out solution IMO.
If you want to be a bit more strict
Success story sharing
<div ng-form="myForm"> ... stuff here .. </div>
. Although, if you're submitting a value from inputs, on button push, I highly recommend using a<form/>
tag, if for no other reason than it allows a user to hit [ENTER] and submit the form. But it also likely constitutes better practice because of things like accessibility concerns.