Reputation: 750
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/
Upvotes: 1
Views: 1744
Reputation: 3186
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.
Upvotes: 0
Reputation: 21
@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
Upvotes: 0