0

I have a form where my intent is for required fields to not always be enforced. For example if the user is saving the document as a draft they can enter as little information as they like, if they try and publish the document then they have to enter all the required fields. I'm using a boolean on the controller which changes according to which button has been pressed e.g.

<input type="text" ng-model="field2" ng-required="enforceRequired" />

The problem is that the fields are not re-evaluated when the boolean changes so the form is submitted and then it becomes invalid. Please see this JSFiddle to see what I mean. If you fill in field1 and then click publish it will succeed on the first click and THEN become invalid.

How can I force the validation to run before the form is submitted?

2 Answers 2

1

Yarons is right, you are changing the value too late, by late I mean after the form validations has been run. What you can do as a workaround is, after changing the required value, let angular do another cycle and then show your alert. This can be done via $timeout service, although I must mention that it is usually not a good practise to change the flow of your digest actions. It gets pretty messy pretty soon.

Change your publish function like this (and don't forget to inject $timeout)

$scope.publish = function () {
    $scope.enforceRequired = true;

    $timeout(function () {
        if ($scope.form.$valid) {
            alert("Published!");
        }
    });
};

Working fiddle: http://jsfiddle.net/bh9q00Le/14/

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

1 Comment

I ended up using this solution. Thanks
1

The problem is that you are changing the value of enforceRequired in the middle of the digest loop, so the watchers are not re-rendered before you check the input fields' validity (read about digest here).

If you want to get around it, I suggest one of the following methods:

  1. change the value of enforceRequired before you call saveDraft or publish. see example.

  2. call $scope.$apply() after you change the value of enforceRequired. see another example.

3 Comments

$scope.$apply() was the best solution for me. Thanks very much.
I've actually just noticed that this causes errors in the console (Error: $apply already in progress). Is there any way around this?
I don't think there is a way around it. you can use safe apply, but it will cause the whole workaround not to work... That's why I suggested another approach.

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.