1

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/

2

3 Answers 3

0

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

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

2 Comments

Tried this, and I get the following error. docs.angularjs.org/error/$rootScope/inprog?p0=$digest
Remove scope.$apply() and add name atribute to the input box with the same name of ng-model and try.
0

@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

1 Comment

Tried this but I get scope.digest() is not a function. Tried scope.$digest() but I get the following error. docs.angularjs.org/error/$rootScope/inprog?p0=$digest
0

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.

3 Comments

Not quite it. I've updated my original post to include what I'm currently doing based on your jsfiddle
If the dropdown is on monthly, and I type in say 12, the price need to update in input?
Maybe, you need this jsfiddle?

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.