ChatGPT解决这个技术问题 Extra ChatGPT

Disable submit button when form invalid with AngularJS

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?


B
Ben Lesh

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>

Sorry, I use it now. Yet, it is still disabled even when the textbox contains text
+1 Coincidentally, I was just reading this great post of yours: benlesh.com/2012/11/angular-js-form-validation.html
what if I don't have a form? Can I do that also on div element?
@MichaelCwienczek technically, you can add ng-form to a div tag: <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.
@BenLesh, what if the submit button is not inside my form and still I have to disable it if the form in invalid.
w
wvdz

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>

Yes, the form name should be in camel case for any AngularJS form validations.
as a rule of thumb, all js like expressions will recognise objects in the camelcase form, while dash is for html like syntax
So, what happens if the form is a member of a formset, and therefore is required to have a name w/ a hyphen in it (like "my_formset_name-0")?
In the example above, I believe myForm.$invalid should still work, so in your case, I would think my_formset_name0.$invalid should work.
I
Ivan Sokalskiy

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>

Thank you very much for the async validation solution!
You should just use !myForm.$valid that handles async Pending issues as well. itnext.io/valid-and-invalid-in-angular-forms-61cfa3f2a0cd
N
Nelul

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>

Although this is valid advice for "Angular", this answer is invalid for "AngularJS". Namely, (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
P
Prashobh

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');
    }
   });
  }
 };
}
);

For More Info click here


Your method of solution works for me with little tweak. Thank you
Why would you do this when there are native directives 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.
Above is a sample directive , original have many scenarios like nested check box etc and I dont want to messy my html code by adding in every form,instead this directive will take care all the things.
C
Cengkuru Michael

If you want to be a bit more strict