Don't record invalid values with ng-model


I really like how the ng-model attribute binds directly to my model and users get instant feedback on their changes. For my use case that's perfect. However, I don't want invalid values to be put into the model where they can throw a wrench into the calculations. I somehow want the model to only be updated if the value in the form control is valid. For invalid values, it's fine for the control value to change while the model value stays fixed.

If I change the source of angular (1.2rc) NgModelController's $setViewValue implementation:

this.$setViewValue = function(value) {
  if (this.$modelValue !== value) {
    this.$modelValue = value;

To this:

this.$setViewValue = function(value) {
  if (this.$modelValue !== value && this.$valid) {
    this.$modelValue = value;

It seems to do exactly what I want, however I don't know how to do this in a proper way. What's the right way to change this behavior? Or are my attempts doomed to failure for some reason?

Update: Added example.

For example look at HTML:

<div ng-controller="MyCtrl">

And the JS:

var myApp = angular.module('myApp',[]);

function MyCtrl($scope) {
    $scope.validNumber = 15;

The number shows properly for values between 10 and 20, but I want it so that if you suddenly type '8' into the box, or delete the second digit leaving '1' the last valid number still shows above. That is, the model always has a valid value, even if the control does not.

Problem courtesy of: traveling_matt


I believe the default behaviour of AnugularJS validators are not to update the model if the value passed is invalid. If you look at the developer guide and go through Custom Validation these samples also show that the model is not update or is cleared on invalid value provided in the UI

Solution courtesy of: Chandermani


As Chandermani said, it is the default behavior, here is a example that shows it in action :

<form name="myform">
    <input type="text" name="myinput" ng-model="myvalue" ng-minlength="4" required>

Is the input valid ? {{ myform.myinput.$valid }} <br />
Input's value : {{ myvalue }}

{{ myvalue }} doesn't show anything until you write at least 4 characters in the input.

Best Regards.


If you need a default value, I guess you could break down your value into 2 values, using a computed value :

   var validNumber = 15;
    $scope.validNumber = function () {
        if ($scope.myform.myNumber.$valid) return $scope.myNumber;
        else return validNumber;

I set up an example here :

Discussion courtesy of: Prezbar

This recipe can be found in it's original form on Stack Over Flow.