26

I am unable to find a solution in the existing answers, hence i am posting this.

I have a form which has many input fields, many of them are required.

There are buttons (more than 2) in the form and are tied to functions in controllers using ng-click.

I need to have form validated on ng-click before the function is executed.

By default, form validation is happening after function execution. Function should not run if required fields are not filled.

I have created a fiddle. https://jsfiddle.net/z1uyyqg9/

<script>
    var app = angular.module('myApp', []);
    app.controller('myCtrl', function($scope) {
        $scope.name=undefined;
        $scope.preview = function(){
            alert("Previewed");
        };
        $scope.update = function(){
            alert("Updated");
        }
    });
</script>

<div ng-app="myApp" ng-controller="myCtrl">

    <form>
        <input type="text" ng-model='name' required>
        <button ng-click='preview()'>Preview</button>
        <button ng-click='update()'>Update</button>
    </form>

</div>
6
  • Not get your point. Did you mean HTML 5 validation on fields ? Commented Jul 1, 2015 at 10:43
  • @Vineet Yeah, HTML 5 validation. Commented Jul 1, 2015 at 10:44
  • take a look at angular docs.angularjs.org/guide/forms Commented Jul 1, 2015 at 10:49
  • 3
    Most often in AngularJS you'll find that it is a common pattern to disable the buttons unless the form is valid. So, add a form name and then you can just add: ng-disabled="myFormName.$invalid" to your buttons. Commented Jul 1, 2015 at 10:49
  • 2
    @jme11 That is one option. But since there can be many input and select fields in the form. I wanted to let user know what he is missing on button click instead of him figuring out what he is missing. Commented Jul 1, 2015 at 10:53

2 Answers 2

66

A very-very simple solution is to give the form a name so you can refer to it and then tweak the ng-click to fire only if the form is valid:

<form name="myform">
    <input type="text" ng-model='name' ng-required="true" />
    <button ng-click="myform.$valid && preview()">Preview</button>
    <button ng-click="myform.$valid && update()">Update</button>
</form>

Forked fiddle: https://jsfiddle.net/r8d1uq0L/

I like separating validation (a business concern) from the view, to that end I created egkyron that lets you define the model constraints in code and use programmatic validation along with standard Angular form validation.

Sign up to request clarification or add additional context in comments.

5 Comments

That is one option. But since there can be many input and select fields in the form, I wanted to let user know what he is missing on button click instead of him figuring out what he is missing and why button is disabled.
Display a marker on the invalid fields then? Angular is giving the tools to do it - starting with the ng-invalid CSS class.
Above code doesn't ignore ng-disabled fields. How can i make it ignore ng-disabled fields (even if it has ng-required).
You will have to repeat the ng-disabled condition to the ng-required, only negated, as: <input ... ng-disabled="foo.condition" ng-required="!foo.condition" />.
Looks like pain in the back. Thanks for helping :)
4

You could set a flag so that you can show some kind of a required message or set some css class when the form is invalid.

var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
    $scope.name=undefined;
    $scope.showMsgs = false;
    $scope.preview = function(form){
        if ($scope[form].$valid) {
            alert("Previewed");
        } else {
            $scope.showMsgs = true;
        }
    };
    $scope.update = function(form){
        if ($scope[form].$valid) {
            alert("Updated");
        } else {
            $scope.showMsgs = true;
        }    
    };
});
.error {
  border-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">

    <form name="myform" novalidate ng-init="disabled=false">
        <p ng-show="showMsgs && myform.name.$error.required">This field is required</p>
        <input type="text" name="name" ng-model='name' ng-required="!disabled" ng-disabled="disabled" ng-class="{error: showMsgs && myform.name.$error.required}" />
        
        <button ng-click="preview('myform')">Preview</button>
        <button ng-click="update('myform')">Update</button>
        <button ng-click="disabled=!disabled">toggle disabled</button>
    </form>

</div>

3 Comments

Above code doesn't ignore ng-disabled fields. How can i make it ignore ng-disabled fields (even if it has ng-required=true).
Use ng-required on the fields instead of required and set the expression to check if the field is not disabled. Technically, it has nothing to do with the code above. Validation is going to fail if something is required and not filled in regardless if it's disabled or not. Make sense?
Updated the example, so you can toggle disabled.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.