Ricc
Ricc

Reputation: 341

Hide Value in input when it's zero in angular Js

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?

Upvotes: 4

Views: 10849

Answers (7)

George I.
George I.

Reputation: 582

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);
};

Upvotes: 0

R. Kazeno
R. Kazeno

Reputation: 113

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.

Upvotes: 7

Ricc
Ricc

Reputation: 341

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 />

Upvotes: 0

dubadub
dubadub

Reputation: 3342

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.

Upvotes: 2

dfsq
dfsq

Reputation: 193291

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

Upvotes: 4

sylwester
sylwester

Reputation: 16498

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>

Upvotes: 1

agconti
agconti

Reputation: 18123

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" />

Upvotes: 1

Related Questions