I need to be able to temporarily persist data that isn't fully validated yet, then enforce validation when I'm ready to make it permanent. But Angular is preventing that.
I have a form. The user can saveDraft()
on early versions of the form, which are persisted to the server. Then, when the user is ready, they can submit()
the form, which will persist it with different flags, thus beginning the actual processing of that data.
The problem I'm running into is with Angular's built-in validations. When a user enters some data into an input with validations on it, that data is cached on the $viewValue
property. But if validation fails, it's never copied to the $modelValue
property, which is a reference to the actual $scope
property I bound the input to. And hence the 'invalid' value will not be persisted.
But we need to persist it. We'll deal with forcing the user to correct their validation failures later, when they submit(). Also, we have no way to know whether the user is going to saveDraft()
or submit()
on a particular instance of the view/controller, so we can't setup the views and validation differently beforehand.
My thinking is that we need to somehow iterate the form elements and get Angular to somehow let the data go through. But I can't find a way that's flexible and scalable.
I've tried setting $scope.formName.inputName.$modelValue = $scope.formName.inputName.$viewValue
, but that seems to just upset the gods, as both values are then null'ed.
I've tried using $scope.formName.inputName.$setValidity('', true)
, but that only updates the UI state. It never touches $modelValue
.
I can successfully use $scope.model.boundPropertyName = $scope.formName.inputName.$viewValue
but that feels very imperative and won't allow any variance between the identifiers for boundPropertyName
and inputName
. In other words, you either need individual functions for all form controls, or you need to rely on naming conventions. Both of which are super-brittle.
So... how can I get that $modelValue
updated elegantly? And/Or, is there another, better way to obtain the same results, whereby sometimes I can persist with validation, and sometimes persist without?
Other options I'm considering, but not happy with:
$modelValue
regardless of validity. But that hacks the framework when there should be a more elegant path. See CodePen here.
(Side-note: Angular appears to be filtering the data according to the validator in both directions. If you set a default value on the model for formData.zip of '1234', which isn't enough characters to validate, Angular doesn't even show it. It never reaches the initial $viewValue
.)
1 Answer. Show activity on this post. $('#form_id'). trigger("reset");
With Angular 1.3 and ng-touched , you can now set a particular style on a control as soon as the user has visited and then blurred, regardless of whether they actually edited the value or not.
The following solution can be used since Angular version 1.3:
You can set ng-model-options="{ allowInvalid: true }"
in the input field of the model where you want to persist invalid attributes.
allowInvalid: boolean value which indicates that the model can be set with values that did not validate correctly instead of the default behavior of setting the model to undefined
https://docs.angularjs.org/api/ng/directive/ngModelOptions
Then, when you are ready to show the user their validation errors, you are free to do it your way. Just remember to give your inputs and forms name
attributes, so that you can reference them in your scope.
E.g. if($scope.myFormName.my_input_name.$invalid) { ... }
A relevant tutorial: http://blog.thoughtram.io/angularjs/2014/10/19/exploring-angular-1.3-ng-model-options.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With