4

I have an angular object item.add_value = 0 bind into the

<input type="number" ng-model="item.add_value"   ng-change="sumUp(item)" min="0" max="10000000000" />

In order to do the calculation I have to use type="number" not type="text"

Then my question is how to hide the content of the input when the value is 0?

1
  • Converting strings to numbers in JavaScript is trivial. As to your second question: I'm not of the opinion that this is a good idea. Why wouldn't you want to display the value if it equals zero? Commented Oct 23, 2014 at 21:45

7 Answers 7

7

I just had this same problem and found a way to fix/improve on @dubadub's answer, so I'm sharing my version of his directive:

.directive('hideZero', function() {
    return {
        require: 'ngModel',
        restrict: 'A',
        link: function (scope, element, attrs, ngModel) {
            ngModel.$formatters.push(function (inputValue) {
                if (inputValue == 0) {
                    return '';
                }
                return inputValue;
            });
            ngModel.$parsers.push(function (inputValue) {
                if (inputValue == 0) {
                    ngModel.$setViewValue('');
                    ngModel.$render();
                }
                return inputValue;
            });
        }
    };
})

You just use it by adding the hide-zero attribute to your inputs.

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

1 Comment

This is the better solution as the cursor remains (setting text-indent you lose the cursor), and you don't modify the actual value (we just want to change was is displayed, not the underlying model).
4

The simplest (and the weirdest) way to do it is to use ... CSS! Consider this:

<input type="number" ng-model="item.add_value" 
        ng-class="{zero: item.add_value === 0}"
        ng-change="sumUp(item)" 
        min="0" 
        max="10000000000" />

and CSS:

.zero {
   text-indent: -7px;   
}

Not sure it will be appropriate for you, but this is definitely fun and can work if you adjust indent for your font size and input padding.

Demo: http://plnkr.co/edit/2gRzdY7DVwrPdNGoD0Fq?p=preview

UDP. One more version using directive:

.directive('hideZero', function() {
    return {
        link: function(scope, element) {
            element.on('input change', function() {
                if (this.value === '0') {
                    this.value = '';
                }
            })
        }
    };
});

and use it like:

<input type="number" ng-model="item.add_value" 
       ng-change="sumUp(item)" 
       hide-zero
       min="0" 
       max="10000000000" />

Demo: http://plnkr.co/edit/nrE3vEW2NSuLYeZuKIjO?p=preview

6 Comments

Yes, that's why I said this is simplest approach. If it was not a 1am I would try to make a directive with $parsers and $formatters. This is how you should attempt to solve this problem.
@Ricc Here is one more simple version with custom directive: plnkr.co/edit/nrE3vEW2NSuLYeZuKIjO?p=preview
I am not so sure about the syntax but in the <input> is hide-zero but in the directive is call 'hideZero'? so directive will the Cap letter and auto separate the word?
Yes, in HTML you use snake-case, but in javascript it's translated to camelCase.
Do you mind answer this question for me ? stackoverflow.com/questions/26552647/…
|
2

I think, the most best approach is in using ngModelController because it is not uses DOM (we just in data layer, not in view, we need bind as usual except 0) and very strait-forward. It helps adjust binding between model and it's view in way we need:

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

app.controller('MainCtrl', function($scope) {
    $scope.name = 'World';
});

app.directive('hideZero', function() {
    return {
        require: 'ngModel',
         link: function(scope, element, attrs, modelCtrl) {

           modelCtrl.$parsers.push(function (inputValue) {

             if (inputValue === 0) {
               return '';
             }         

             return inputValue;         
           });
         }
    }
});

See more https://docs.angularjs.org/api/ng/type/ngModel.NgModelController.

Working plunker http://plnkr.co/edit/Zatou8lLx23xwXd1x9hd?p=preview.

2 Comments

thanks for the Answer, but I think @dfsq 's solution is what I try to get, urs is a bit inversed
Do you mind answer this question for me ? stackoverflow.com/questions/26552647/…
1

You could use ng-show or ng-hide depending on how you want the semantics.

I would recommend ng-hide, because its more intuitive and semantic in my opinion:

 <input type="number"
        ng-hide="item.add_value == '0'"
        ng-model="item.add_value"
        ng-change="sumUp(item)"
        min="0" 
        max="10000000000" />

but you could use:

ng-show:

 <input type="number"
        ng-show="item.add_value != '0'"
        ng-model="item.add_value"
        ng-change="sumUp(item)"
        min="0" 
        max="10000000000" />

4 Comments

But if you do ng-hide, it will hide the whole input right? I only want to hide the 0 value. And my calculation doesnt work after add in "ng-if" I think that will recreate the object which let item.add_value lose its refferece
@Ricc right, it would hide the entire input element.
What do you mean by hide only the zero value?
The correct solution, I think, is to trap the error when you perform the calculation.
1

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

app.controller('firstCtrl', function($scope) {

  $scope.item = {
    add_value: 0
  };

  $scope.$watch('item.add_value', function() {
    if ($scope.item.add_value === 0) {
      $scope.item.add_value = "";

    }

  });
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app">
  <div ng-controller="firstCtrl">
    <input type="number" ng-model="item.add_value" ng-change="sumUp(item)" min="0" max="10000000000" />


  </div>
</div>

1 Comment

@Ricc you can use $scope.$watch
0

Actually the easiest solution would be setting the min value to > 0 like 10?

<input type="number" ng-model="item.add_value" ng-change="sum_Up(item)" min="10" max="10000000000" /> <br />

Comments

0

I let it be string, but parse it when calculating:

<input type="number" ng-model="item.add_value"   ng-change="sumUp(item)" min="0" max="10000000000" />
{{total}}

JS:

var getRealValue = function(val){
    if(val === ''){
        return 0;
    }else{
        return parseFloat(val);
    }
};
$scope.sumUp = function(val){
   $scope.total = getRealValue(val);
};

Comments

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.