1
votes

I have a custom angular directive that I'm using to change the display of price on an item. It's stored as a yearly value and I need to toggle between allowing users to see/edit as yearly or as monthly. So my custom directive is working on my input boxes (not able to use it for a label, div, span, but that's another issue).

I'm able to see that when I toggle the attribute, it picks up the change, but the value in the input doesn't change and I assume it's because not re-rendering the element. Is there any way I can force that to happen?

Here's my directive

angular.module('common.directive').directive('priceMonthly', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
            var perMonth = false;

            attr.$observe('priceMonthly', function(isMonthly) {
                perMonth = (isMonthly.toLowerCase() === "true");
                console.log("per month is " + perMonth); //updating perMonth correctly at this point
                //guessing I need to do something here or in the function that changes the value of the attribute
            });

            function fromView(value){
                return perMonth ? value * 12 : value;
            }

            function toView(value){
                return perMonth ? value / 12 : value;
            }

            ngModel.$parsers.push(fromView);
            ngModel.$formatters.push(toView);
        }
    };
});

Here's where I'm using it.

<input type="text" price-monthly="{{monthlySqftView}}"
       class="form-control no-animate" name="item.priceLow"
       ng-model="item.priceLow" ui-money-mask="2"/>

Here's a jsfiddle of where I'm currently at. So if the dropdown is on monthly, and I type in say 12, the price is correctly 144 which would be the full year price. Now if you change the dropdown to yearly, I need the input to update to 144. https://jsfiddle.net/6tnbonzy/

3
Can you post the HTML as well (i.e the HTML which uses the directive)Thangaraja

3 Answers

0
votes

Try scope.$apply() after you made required changes

0
votes

@rschlachter, i am not sure if this can help you. AngularJS uses scope.digest() to clean the dirty data. you might need to put this line of code into your method

        attr.$observe('priceMonthly', function(isMonthly) {
            perMonth = (isMonthly.toLowerCase() === "true");
            console.log("per month is " + perMonth); //updating perMonth correctly at this point
            //guessing I need to do something here or in the function that changes the value of the attribute
            //put it here, if you instantiated scope already. 
            scope.digest();
            //scope.apply();
        });

hope it works

0
votes

It seems you want to do something like this jsfiddle?

<form name="ExampleForm">
 <select ng-model="period">
  <option value="monthly">monthly</option>   
  <option value="yearly">yearly</option>     
 </select>
 <pre>
   period = {{period}}
 </pre>
 Edit as {{period}}: <input price-monthly="obj.price" period="period" ng-model="obj.price" >
 <pre>
   price = {{obj.price}}
 </pre>
</form>

And JS controller

.controller('ExampleController', function($scope) {
$scope.period = 'monthly';})

And JS directive

.directive('priceMonthly', function() {
return {
    restrict: 'A',
    scope:{
      priceMonthly:"=",
      period:"="
    },
    link: function(scope) {
       scope.$watch('period',function(newval){
        if(newval=='monthly')
          scope.priceMonthly = scope.priceMonthly*12;
        if(newval=='yearly')
          scope.priceMonthly = scope.priceMonthly/12;
       })
    }
};});

I hope this will help you.