Search code examples
javascriptangularjsangular-ngmodelangular-controller

How to pass data to controller and back to the view in Angular?


I have the following function that adds a comma every 3 characters as you type, so for example 1000 with return 1,000

http://plnkr.co/edit/TL8hlIxyPbwUNCbLiKgs?p=preview

But the function is specific to that input field's ng-model. How do I return the value of $scope.item.price back to the view in a way that I can reuse the function with any input field? Such as using x instead of item.price in the function.

Perhaps using return or maybe writing a directive, but not sure how to do that.

HTML

<input type="text" name='' ng-model='item.price' ng-change='addCommas(item)' />

JS

    $scope.addCommas = function(item){
        price = item.price
        if (price){
            $scope.item.price_clean = price = price.replace(/,/g, '')
            $scope.item.price = price.replace(/(\d)(?=(\d{3})+$)/g, '$1,')
            if (price.indexOf('.') > -1) {
                varSplit = price.toString().split('.');
                varSplit[0] = varSplit[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
                varSplit[1] = varSplit[1].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
                $scope.item.price = varSplit.join('.');
            }
        }
  }

The solution I'm looking for would be something along these lines:

<input ng-model="item.price" ng-change="addCommas(item.price)"/>

$scope.addCommas = function(x) {
  if (x) {
    // functions here, only working with 'x', not with item or price.
    return x
  }
}

Like, for example, the following:

function double(x) {
  return x * 2
}

Solution

  • I think the best way is to convert your function into directive:

    app.directive('addCommas', function() {
        return {
          scope: {
              'ngModel': '='
          },
          link: function ($scope, element, attrs) {
            $scope.$watch('ngModel',function() {
              var value = $scope.ngModel.toString();
              //console.log(value)
              if (value){
                value = value.replace(/,/g, '')
                $scope.ngModel = value.replace(/(\d)(?=(\d{3})+$)/g, '$1,')
                if (value.indexOf('.') > -1) {
                  varSplit = value.toString().split('.');
                  varSplit[0] = varSplit[0].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
                  varSplit[1] = varSplit[1].replace(/(\d)(?=(\d{3})+$)/g, '$1,');
                  $scope.ngModel = varSplit.join('.');
                }
              }
            });
          }
        }
      });
    

    And HTML:

     <input type="text" name='' ng-model='item.price' add-commas/>
    

    The directive "binds" to the input's ng-model, watches for changes and applies the transformation.

    Here is plunker.

    Two more versions: directive which binds to item with price property and stand-alone directive with own template.