I have the following form:
<form name="formuser" action='/signup' method='post' novalidate>
<input type="text" name="firstname" ng-model="firstname" ng-class="{ 'has-error' : (formuser.firstname.$invalid && !formuser.firstname.$pristine) || hasSubmitted}" required />
<button type="submit" ng-disabled="formuser.$invalid" ng-click="hasSubmitted=true">Submit</button>
</form>
I'm trying to add the class 'has-error' to the input field that is invalid after the user has either typed in something or hit the submit button while the input is still pristine. I've added ng-disabled to the submit button to disable the form submition but I still want the ng-click to fire to change the hasSubmitted scope. The problem is that ng-disable on the button also disabled the ng-click.
I know I could always use ng-submit on the form, do validation in my controller, and then fire off an ajax request but my authentication framework requires that I actually submit the form and redirect the browser.
Well, instead of making hacks the most clean solution would be to make the button enabled and just handle the submit using simple directive:
angular.module('common', []).directive('preventSubmit', function () {
return {
restrict: 'A',
scope: {
preventSubmit: '='
},
link: function (scope, element) {
element.bind('submit', function(e) {
if (scope.preventSubmit) {
e.preventDefault();
}
});
}
}
});
So what it does it binds to the submit event and if the form is invalid it prevents the form from submitting. If you don't use action attribute Angular handles it automatically and you can handle this but in case of specified action and normal submit this directive can be very useful.
And in the markup:
<form name="formuser" action='/signup' method='post'
novalidate prevent-submit="formuser.$invalid">
...
<button type="submit" ng-click="hasSubmitted=true">Submit</button>
</form>
And using ng-style or ng-class you can style your button as expected depending on your form state.