Issue
This is what I currently have implemented and works in IE 11 now we are trying to move away from IE11 and fix some of the issues popping up.
<input type="number" evaluate-input="model.personalNumber" ng-model="model.personalNumber" maxlength="50" ng-change="..." ng-blur="..." />
angular.module("myApp")
.directive("evaluateInput", [
function () {
return {
restrict: "A",
replace: true,
scope: {
evaluateInput: "="
},
link: function ($scope, elem, attrs, ctrl) {
/* Need to grab the input from the element because if the input is a number type and it has non-numeric values then the model will be empty. */
var inputValue;
elem.bind("keyup", function (e) {
inputValue = elem[0].value;
if (e.keyCode === 13) {
$scope.$apply(function () {
calculateFormula();
});
}
})
elem.bind("blur change", function (e) {
inputValue = elem[0].value;
$scope.$apply(function () {
calculateFormula();
});
})
/* Uses the javascript eval function but catches and swallows any errors and returns null */
function calculateFormula() {
var result = null;
try {
result = eval(inputValue);
result = Number(result.toFixed(2));
}
catch (e) {
// No need to generate an error on invalid input.
// Just leave the result as null
}
$scope.ngModel = result;
}
}
};
}]);
The way this works is you can type an expression like 100*2 into the input and it will evaluate the expression and return the result. When running this in Edge or Chrome the elem[0].value doesn't have a value set.
I have tried getting the value using other methods such as elem.val() and attr.evaluateInput but these either return null or the name of the model. it seems as though ng-model hasn't been set when this directive is hit.
Any help or information in the right direction would be greatly appreciated.
Solution
Your main issue lies with the HTML5 constraint validation.
As mentionned in the AngularJS documentation:
If a non-number is entered in the input, the browser will report the value as an empty string, which means the view / model values in ngModel and subsequently the scope value will also be an empty string.
To counter this, you have to set your input as a text input.
I've fixed this issue and some others small mistakes in the following example
const app = angular.module("myApp", []);
app.controller('TestCtrl', function() {
const ctrl = this;
ctrl.personalNumber = 2;
})
app.directive("evaluateInput", [
function() {
return {
restrict: "A",
scope: {
ngModel: '='
},
link: function($scope, elem, attrs, ctrl) {
/* Need to grab the input from the element because if the input is a number type and it has non-numeric values then the model will be empty. */
var inputValue;
elem.bind("keyup", function(e) {
inputValue = elem[0].value;
if (e.keyCode === 13) {
calculateFormula();
}
})
elem.bind("blur change", function(e) {
inputValue = elem[0].value;
calculateFormula();
})
/* Uses the javascript eval function but catches and swallows any errors and returns null */
function calculateFormula() {
var result = null;
try {
result = eval(inputValue);
result = Number(result.toFixed(2));
} catch (e) {
// No need to generate an error on invalid input.
// Just leave the result as null
}
$scope.ngModel = result;
}
}
};
}
]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.8/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="TestCtrl as model">
<input type="text" evaluate-input ng-model="model.personalNumber" maxlength="50" />
<div>
{{model.personalNumber}}
</div>
</div>
</div>
Answered By - Julien
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.