1

I have the following input

<input id="mainOdd1Id" type="number" ng-model="data.mainOdd1" min="0" step="any" ng-attr-placeholder="{{data.mainOdd1}}" ng-focus="focus($event)"  ng-blur="blur($event)">

And the following function which execute on blur

$scope.blur = function($event){

  var id = $event.target.getAttribute('id');

  switch(id) {
    case "mainOdd1Id":
        $scope.data.mainOdd1 = func($scope.data.mainOdd1);
        break;
    case "mainOdd2Id":
        $scope.data.mainOdd2 = func($scope.data.mainOdd2);
        break;
    case "bkOdd1Id":
        $scope.data.bkOdd1 = func($scope.data.bkOdd1);
        break;
    case "bkOdd2Id":
        $scope.data.bkOdd2 = func($scope.data.bkOdd2);
        break;            
    default:
        break;
  } 
}

I would like to avoid the switch command by getting a "pointer" to the data field by the id and changing it. (*pointer = function(*pointer))

Is that possible?

Thanks

A.S.F Studio
  • 43
  • 1
  • 7
  • Is this a function that is supposed to be doing something? What is the "func" function? Some details on this will probably help with a better solution. – 10100111001 Jul 12 '16 at 15:20

2 Answers2

0

You can access properties by name using bracket notation.

Suppose you have a variable containing property name propertyName. Then you can access some object obj property like this var propertyValue = obj[propertyName].

This should do the trick. If you remain the same naming convention that element's id is just propName + 'Id'

$scope.blur = function($event){
  // convert mainOdd1Id -> mainOdd1
  var id = $event.target.id.replace(/Id$/, '');

  if(id in $scope.data) { // check if prop is in scope.data
     $scope.data[id] = func($scope.data[id]); // perform update
  }
}

or you can pass correct property name from within template

<input id="mainOdd1Id" ... ng-focus="focus('mainOdd1')"  ng-blur="blur('mainOdd1')">


$scope.blur = function(propertyName){
  $scope.data[propertyName] = func($scope.data[propertyName]);
}
Yury Tarabanko
  • 44,270
  • 9
  • 84
  • 98
0

The 'better' solution is to write a custom directive which attaches func to ngModelController.$parsers for the element where you use the directive.

module.directive('applyFunc', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
            ngModel.$parsers.push(func);

            function func() { ... }
        }
    };
});

Then your html becomes:

<input id="mainOdd1Id" type="number" ng-model="data.mainOdd1"
     min="0" step="any"
     ng-attr-placeholder="{{data.mainOdd1}}" ng-focus="focus($event)"
     apply-func >

You can either write a separate directive for each parser or you could write a generic one that takes the function as from the attribute.

See https://stackoverflow.com/a/12947995/107660 for more on this and https://docs.angularjs.org/api/ng/type/ngModel.NgModelController for the full documentation.

Community
  • 1
  • 1
Duncan
  • 92,073
  • 11
  • 122
  • 156
  • Thanks, does apply-func translate to the directive name? applyFunc? – A.S.F Studio Jul 13 '16 at 06:17
  • Yes, give your directive in a name in camel case and convert that to any of the Angular naming conventions for attributes the simplest of which is to lowercase and hyphen separate the words. – Duncan Jul 13 '16 at 08:22
  • Hey, I tried this method, and I see the function is only being called on a valid input from the user. What can I use so it will be called on blur? – A.S.F Studio Jul 13 '16 at 10:40
  • I think I got it, I bound between the blur element and a function in the controller. Thanks – A.S.F Studio Jul 13 '16 at 11:49