Angularjs Input text appending number instead of adding it - angularjs

When user type in number then click on "+", it will append the count instead of perform addition for the counter.
But it is working fine when performing "-" or "+" action without key in number in the input box.
<div ng-app="myApp" ng-controller ="myCtrl">
<span ng-click="count = count + 1">+</span>
<input type="text" ng-model="count" valid-number>
<span ng-click="count = count - 1" ng-show="count > 0">-</span>
</div>
fiddle : http://jsfiddle.net/shenglim/Lyugypqk/4/
Anybody can help out on this? Thanks !

simple example will work if uses ng-click="test()" and perform basic addition, if you need to retrieve from existing json which return string, Try to use parseInt() on the JSON object.

Try <input type="number">.
The data type for type="text" makes it a string and "1" + 1 = "11"
JSFiddle ~ http://jsfiddle.net/Lyugypqk/2/

Alternatively you can add two methods to increase and decrease the values into the controller and use them,
$scope.increment = function(){
$scope.count++;
};
$scope.decrement = function(){
$scope.count--;
};
<span ng-click="increment()">+</span>
<input type="text" ng-model="count" valid-number>
<span ng-click="decrement()" ng-show="count > 0">-</span>

Related

Calculate percentage based on input fields in Angularjs

I am using AngularJS. I have two input fields: total marks and marks obtained, as well as a 3rd field which is percentage. Now after entering total marks and marks obtained, I need to calculate the percentage automatically.
Here is my html :
<div class="form-group">
<label class="control-label">Total Marks</label>
<input type="text"
class="form-control input_field"
name="totalMarks"
data-ng-model="student.totalMarks" />
</div>
<div class="form-group">
<label class="control-label">Marks Obtained</label>
<input type="text"
class="form-control input_field"
name="marksObtained"
data-ng-model="student.marksObtained" />
</div>
<div class="form-group">
<label class="control-label">Percentage</label>
<input type="text"
class="form-control input_field"
value={{ ((student.marksObtained/student.totalMarks)*100).toFixed(2) }}
name="rank"
data-ng-model="student.rank" />
</div>
Can anyone tell me how to auto generate rank field with percentage as soon as I enter marks obtained. Currently, I am doing as shown above but it is not working.
Not sure that your calcul for percentage is exact, but this Plunkr is working with a watcher on student properties.
app.controller('MainCtrl', function($scope){
$scope.$watchGroup(['student.totalMarks', 'student.marksObtained'], function(){
if($scope.student.marksObtained !== undefined && $scope.student.totalMarks !== undefined)
$scope.student.rank = (($scope.student.marksObtained/$scope.student.totalMarks)*100).toFixed(2);
})
});
https://plnkr.co/edit/NsNge0mzrgjjUgBZ332p?p=preview
You can try assigning your calculation inline, like this:
<input ng-model="student.rank" ng-value="student.rank = ((student.marksObtained/student.totalMarks)*100).toFixed(2)">
Running Example on JsFiddle
It does not work because your input is linked to a ng-model.
There is two ways to solve this problem :
Setup a watcher on student.totalMars and student.marksObtained, and update student.rank with new value.
Do not link your percentage to student.rank and just set the value as you did.
You can check here for the second way.
In your controller, add the following function and variable :
function getPercentage() {
// dividing by zero is bad !!!
let ratio = $scope.student.marksObtained / ($scope.student.totalMarks || 1);
return (ratio * 100).toFixed(2);
}
$scope.student.percentage = getPercentage();
Then change the last <input /> of your view to :
<input type="text"
class="form-control input_field"
ng-value="student.percentage"
name="rank" />
If you want your input to have two-way data binding, use ng-model instead of ng-value.

Angularjs $viewValue.length for form validation

I have a simple from to which I am trying to add validation. I am comparing the $viewValue in the form with the value of ng-min/mg-max to notify the user if he is trying to enter values that are over the max and under the min allowed. The issue is that if I use ng-if="myform.$viewValue.length > maxvalue" the error does not appear. However, the error DOES appear when I exclude .length() However, in this case it is checking every integer in of $viewValue string with maxvalue number, which is not intended. I understand that $viewValue.length would give me a number instead of a string so that I may compare a number with a number, but in this case the error never appears.
I even have a JSFiddle example that works https://jsfiddle.net/up2qxcxe/
But it does not in my app.
Here is my form:
<form name="modelParamsForm" novalidate>
<div class ="row">
<div class="form-group col-md-4" ng-repeat="modelParam in
modelParams" ng-class="{ 'has-error' :
modelParamsFieldForm.value.$invalid }">
<ng-form name="modelParamsFieldForm">
<label form-group>{{modelParam.label}}</label>
<input type="number" class="form-control input-sm"
ng-model="modelParam.value" name="value"
ng-min="modelParam.minvalue" ng-max="modelParam.maxvalue" >
<span ng-show="modelParamsFieldForm.value.$invalid"></span>
//MIN-MAX VALIDATOR
<div ng-if="modelParamsFieldForm.value.$viewValue.length >
modelParam.maxvalue">Max exceeded:{{modelParam.maxvalue}}
</div>
</ng-form>
</div>
</div>
My controller is nothing special:
$scope.modelParams = {};
$scope.loadModelParams = function(modelName) {
var req = {
method : 'GET',
url : urlPrefix + 'PB_OPTIMISER_GET_MODEL_PARAMS',
params: {modelName : modelName}
};
$scope.loading = true;
$http(req).then(function(response) {
$scope.loading = false;
$scope.modelParams = response.data;
$scope.modelParamsOld = angular.copy($scope.modelParams);
}, function() {
$scope.loading = false;
});
};
EDIT: In my JSON modelParam.maxvalue is a string. I think the problem was that I am comparing a myform.$viewValue.length with modelParam.maxvalue which is string type. I am not sure how to get around this...do I have to parse maxvalue?
You do not need $viewValue. Your ng-ifs are wrong. Change to
<input type="number" class="form-control input-sm col-md-5" ng-model="modelParam.value" name="test" min="modelParam.minvalue" max="modelParam.maxvalue">
<span ng-if="modelParam.value > modelParam.maxvalue">Too Many!!</span><br>
<span ng-if="modelParam.value < modelParam.minvalue">Too Few!!</span>
It should work fine. Here is your Plunker working the way I think you want.
The problem here is that the modelParam.maxvalue was coming from the database as a string, rather than integer. So when comparing ng-if="myform.$viewValue.length > modelParam.maxvalue" I was comparing an integer with a string, and that obviously did not produce the desired results. The solution was to go to the table and make maxvalue an integer.
Alternatively one can have a second variable for maxvalue in the controller that parses the string like so: $scope.mpMaxValue = parseInt($scope.modelParams.maxValue)
See this post for a longer discussion: AngularJS comparing $viewValue against ng-model or object param

Update a span in a ng-repeat using ng-keyup

In a repeater and I display some records with some data, input field and a span tag in each row. When the user enters numeric value into the input field,
I want to do a calculation on it and display the result in the span tag. This will happen on keypress using ng-keyup
I’ve tried this but its not working, probably becuse I'm not using the model correctly...
<div ng-repeat="bet in $ctrl.bets">
<input class="form-control input-sm" ng-model="$index" type="text" ng-keyup="$ctrl.getReturn($index)">
<span>Return: </span><span id="$index" ng-model="$index"></span>
</div>
And in my controller I have this
vm.getReturn = function(index){
document.querySelector('#' + index ).html(value / 2);
}
I know its way off, but can someone tell me how to do this? Ta.
1st thing you can use ng-model only with input, select & special bootstrap components, Not span element. You could use ng-bind do bind value one way.
Other thing is don't play with $index which is added & managed by ng-repeat directive itself. I'd say rather add new property inside bet(each element of bets).
Markup
<div ng-repeat="bet in $ctrl.bets">
<input class="form-control input-sm" ng-model="bet.myValue" type="text" ng-keyup="$ctrl.getReturn(bet.myValue)">
<span>Return: </span><span id="$index" ng-bind="vm.getReturn(bet.myValue)"></span>
</div>
Accordingly manage calculation in getReturn function.
vm.getReturn = function(val) {
return (val > 0 ? (val / 2): 0);
}

Angularjs Adding two numbers

Hi I want to add two field and put in another field
<input type="text" ng-model="pfi.value1">
<input type="text" ng-model="pfi.value2">
<input type="text" ng-model="pfi.sum" >
its working fine in label
<label>{{ pfi.value1 + pfi.value2}}</label>
but how to do same thing in text field
You should set pfi.sum = pfi.value1 + pfi.value2; inside your controller. I'm not positive what the two-way binding would do if you then edited the text field attached to pfi.sum, but I suspect it wouldn't be good. However, for display purposes, this should work.
You can do it in the template
<input type="number" ng-model="pfi.value1">
<input type="number" ng-model="pfi.value2">
<input type="number" ng-model="pfi.sum" >
<p>{{ pfi.sum = pfi.value1 + pfi.value2}}</p>
The $interpolation service evaluates the exoression on each change to the inputs and updates the sum.
The DEMO on JSFiddle.
you should do it on the controller
pfi.sum = pfi.value1 + pfi.value2
also,you need to add the controller to your html file.
you should do that operation in your controller,
assuming you are using pfi for controllerAs attribute?
x.controller('xctrl', function() {
var pfi = this;
pfi.sum = pfi.value1 + pfi.value2;
});

Validating length in AngularJS

I have a directive which is used for text field and the directive has a validation like below which should show a message when the textfield length is less than 5 characters.
attrs.$observe('useNumberRegex', function( val ) {
scope.useNumberRegex = GenericFieldUtils.castBoolean(val, false);
if(scope.useNumberRegex)
{
scope.regExp = /^\d+$/;
}
});
and the directive template URL points to html as shown below
<li ng-if="editable && (cssClass == 'text_style_filter' || cssClass == 'drp_down_style')" style="float:left;width:42%" class="{{$parent.cssClass}}">
<input id="{{$parent.uniqueId}}" name="{{$parent.name}}" type="{{$parent.textType}}" class="field-control {{$parent.numCssClass}}" ng-pattern="$parent.regExp" autocomplete="off" ng-required="mandatory" ng-maxlength="{{maxLength}}" maxlength="{{maxLength}}" ng-model="$parent.value" ng-disabled="disabled" ng-blur="$parent.onBlur($parent.value)" ng-keyup="$parent.onKeyup($parent.value)" aria-label="{{$parent.ariaLabelInput}}" min="{{min}}" max="{{max}}" validate>
<div ng-if="$parent.formController.submitController.attempted">
{{$parent.regExp}}
<span class="error-message" ng-repeat="error in errors" translate>{{error}}fdsfsdfsdf</span>
</div>
</li>
Can you please help me what is going wrong in displaying a message when the length is less than 5 characters long.
You can use ng-minlength to actually validate the length of the input.
You could also use the regex pattern to validate the same. Instead of /^\d+$/ use /^\d{5,}$/

Resources