I am facing a challenge in building an AngularJS directive for a currency textbox. The directive should take values (amount and currency code) from the model in the scope and then apply currency formatting to it. I am struggling to build this directive using ngModelController's parsers and formatters.
The issue I am encountering is that the parser is called first, but the modelValue is undefined because the data has not been returned from the server yet. How can I ensure that the parser is called only when the model is populated? Also, my calculation depends on the currency code retrieved from the database. How can I incorporate these two values in the parser?
I am unsure of how the render function should be implemented in my case.
Below is the HTML snippet:
<numericbox caption="RecurringAmount" controltype="currency" currencycode="{{Model.CurrencyCode}}" value="{{Model.RecurringAmount}}" />
And here is the TypeScript directive code:
export class NumericTextbox
{
constructor ()
{
var directive: ng.IDirective = {};
directive.restrict = "E";
directive.require = '^ngModel';
directive.replace = true;
directive.template = '<input type="text" />';
directive.scope = true;
directive.link = function ($scope: any, element: JQuerySE, attributes: any, ngModel: ng.INgModelController) {
var injector = angular.element(document.getElementById('app')).injector();
var currencyCacheService: CurrenciesCacheService;
currencyCacheService = injector.get('currenciesCacheService');
var currency = new Currency();
var currencySymbol: string;
ngModel.$formatters.push(function (modelValue) {
if (modelValue) {
var amount: number = modelValue || 0;
var currencyCode: string = attributes.currency || "";
if (currencyCode) {
currency = currencyCacheService.GetItem(currencyCode);
currencySymbol = currency.CurrencySymbol || currency.ISOCurrencyCode;
var formattedNumber = accounting.formatMoney(modelValue,
currencySymbol,
currency.NumberDecimalDigits,
currency.CurrencyGroupSeparator,
currency.CurrencyDecimalSeparator);
return formattedNumber;
}
return modelValue;
}
return 0;
});
ngModel.$parsers.push(function (viewValue: string) {
if (attributes.currenycode) {
var num = viewValue.substring(attributes.currenycode.len, viewValue.length - attributes.currenycode.len);
return num;
}
return viewValue;
});
$scope.$watch(function () {
var amount: any = {};
amount.currencycode = attributes.currencycode;
amount.value = attributes.value;
return amount;
}, function (newVal, oldVal, scope) {
debugger;
if (newVal != oldVal) {
var amount: number = newVal.value || 0;
var currencyCode: string = newVal.currencycode || "";
ngModel.$setViewValue({ num: amount, curr: currencyCode });
}
});
ngModel.$render = function () {
//$scope.value =
console.log(ngModel.$viewValue);
};
}
return directive;
}
}
This directive code is written in TypeScript.