0

I have an angular form as part of a single page App. The 'Continue' button moves a user to the next section of the app, and has an ng-click. I would like to prevent this ng-click from happening when the button is clicked and the form is invalid, but I don't want to disable the Continue button.

Example: A user comes to the page and immediately clicks the Continue button without providing a first name. The error message "You should provide a first name" is shown and the user remains on the page.

How can I do this? Here is the code:

<form name="form" novalidate >

<div ng-show="form.FirstName.$touched && form.FirstName.$error.required" class="errorMessage">
    You must enter a first name
</div>

<div class="form-group">
    <label for="firstName" class="form-label">First Name</label>
    <input id="firstName" class="form-control" name="FirstName" ng-model="vm.user.firstName" required />
</div>

<div class="btn-group">
    <button ng-click="vm.next()">Continue</button>
</div>
</form>
2

2 Answers 2

8

Just add form.$valid && before the function call:

<form name="form" novalidate >

<div ng-show="form.FirstName.$touched && form.FirstName.$error.required" class="errorMessage">
    You must enter a first name
</div>

<div class="form-group">
    <label for="firstName" class="form-label">First Name</label>
    <input id="firstName" class="form-control" name="FirstName" ng-model="vm.user.firstName" required />
</div>

<div class="btn-group">
    <button ng-click="form.$valid && vm.next()">Continue</button>
</div>
</form>
Sign up to request clarification or add additional context in comments.

3 Comments

Works good, is there a way to show the error messages when clicking the Continue button?
Just check if the user already tried: ng-show="tried && form.FirstName.$touched && form.FirstName.$error.required" + ng-click="tried = true; form.$valid && vm.next()"
But since you are now adding a lot of logic to the view you should consider putting it into a controller function.
2

Either a button is disabled or it's clickable, you can't have it both ways.

What you could do in your controller for vm.next() is say:

myApp.controller('Page1Controller'),  ['$scope', function ($scope)
{
    $scope.vm = {};

    $scope.vm.next = function()
    {
        if (! $scope.vm.isFormValid())            
            return;            
        //move to the next page with your current code
        ...
    }

    $scope.vm.isFormValid()
    {
        $scope.vm.shouldShowError = $scope.form.valid; //add vm.shouldShowError to your error message ng-show in the view so it will display only after clicking continue
        return $scope.form.valid;
    }
}]);

5 Comments

I agree if a button is not supposed to take you to the next page/form/etc. it should appear that way to the user that the button will not work. Best to disable the button using vm.form.$invalid.
Do I need to write an isFormValid() function? i figured there might be something built in to angular to determine this.
No, you can use only $scope.form.valid. I found in bigger forms I almost always had to do some sort of custom validation so I got into the habit of always including an isValid function for readability.
Having trouble defining $scope as I don't currently use it in my controller.
Added example controller declaration with $scope to my answer

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.