Make a negative number appear positive, but maintain actual value - angularjs

I'm going out on a whim here, but I figured I'd ask here to check.
I have an integer value that I use to determine how other elements on the page act, the actual value of the integer is important (whether it is negative or positive), however actually displaying the prefixed hyphen when it's negative isn't desired.
Is there any way to "hide" the hyphen without altering the actual value of the integer? Keeping in mind that the value is being $watched so multiplying it by -1 is out of the question.
Template:
<p>{{ value }}</p>
Directive:
scope.$watch('value', function()
{
if (scope.value > 0)
{
//do something
}
else
{
//do something else
}
});
Added code, not that I believe it's really necessary

you can use filter
.filter('positive', function() {
return function(input) {
if (!input) {
return 0;
}
return Math.abs(input);
};
})
so in your template use
{{value | positive}}

Pass it through a function like this:
View
<p>{{ positiveLookingValue() }}</p>
Controller
$scope.positiveLookingValue = function(){
return Math.abs($scope.value);
}

Related

Protractor ng-if condition and element availability

I want to check whether element displayed or not depends upon ng-if condition,
<div id="discount_percent" ng-if="data.isDiscount">
<div id="dis_available"> Discount: {{data.discount}} % </div>
</div>
I want to check if data.isDiscount is true than div "discount_percent" & dis_available should display.
Note: div "discount_percent" and "dis_available" won't be present in DOM if data.isDiscount is false.
I did following way, but I'm not fully satisfied with my solution.
var discountPercentId = element(by.id('discount_percent'));
discountPercentId.isPresent().then(function (present){
if(present){
expect(discountPercentId.evaluate("data.isDiscount")).toBeTruthy();
expect(discountPercentId.element(by.id("dis_available")).isDisplayed()).toBeTruthy();
}
});
Any better approach to do? If condition true than check its availability!!!
try this:
var elem = element(by.css('[ng-if="data.isDiscount"]'));
elem.isPresent().then(function(fnct){
if(fnct){
//do whatever
}
else{
//do something else
}
});
also, I am not sure, but you might want to get the value of data.IsDiscount first. You can get the value of this with the following function:
elem.getAttribute('value').then(function(value) {
//do something with the value
});

Sorting minus number strings with AngularJS 'orderBy'

I am reverse ordering some number strings with the orderBy directive that can be used in conjunction with ngRepeat.
<div ng-repeat="item in standings| orderBy:['-points', '-gd', 'team_name']">
<p>{{item.gd}}
</div>
So it is ordering (in order of priority) 'points', then 'gd' (goal difference), then 'team_name' (alphabetically).
The gd value correctly orders by descending value. The problem I have is with negative number values. In this instance, numbers are returned as strings, and the orderBy function doesn't understand "-2" as being less than "-1", but the opposite.
How can I get ng-repeat to parse the number values into integers, particularly to solve this ordering issue with minus numbers?
I considered making a filter, e.g: {{item.gd | *filterHere* }}, but this wouldn't be seen by the initial ng-repeat directive, which needs to take the source value as an integer.
Any help would be appreciated.
UPDATE:
I tried this filter, but when I call it in my ng-repeat, it returns nothing:
app.filter('stringToInteger', function() {
return function(input) {
angular.forEach(input, function(value) {
parseInt(value.gd);
})
};
return input;
});
In the View:
<p ng-repeat="item in standings | orderBy: '-gd' | stringToInteger">GD = {{item.gd}}</p>
the filter should be like this.
app.filter('stringToInteger', function() {
return function(input) {
angular.forEach(input, function(value) {
value.gd = parseInt(value.gd);
})
return input;
};
});
Use it like this .
<tr ng-repeat="team in teams | stringToInteger | orderBy:'-gd'">
Plunker link for more reference.
https://plnkr.co/edit/GRfMJnRdT1Gu5RXO9elA?p=preview

How to bind a {{}} to the return value of a angular js $scope method?

I have method :
$scope.resortLocation=function(resort_id){
$scope.resorts.forEach(function(sel_resort){
if(sel_resort.resort_id===resort_id){
console.log(sel_resort.name );
return sel_resort.name;
}
});
}
And the html is :
<tr ng-repeat="x in bookings | filter:{membership_id:user.membership_id} | filter:upcomingFilter">
<td><a ng-href="#!/bookings/{{x._id}}">{{x.booking_id}} </a>
</td>
/*I want the result here*/ <td>{{resortLocation(x.resort_id)}}</td>
<td>{{x.checkin_time | date : "mediumDate"}}</td>
<td>{{x.checkout_time | date : "mediumDate"}}</td>
<td>{{x.points}}</td>
<td>{{x.cancelled}}</td>
</tr>
While the "resortLocation" function is getting called successfully the return value is not appear on the screen at the location of {{resortLocation(x.resort_id)}}. What am I doing wrongly?
As JAAulde mentioned resortLocation doesn't return a value only the foreach does.
In addition, my guess is that when you find the required resort you don't want to keep on iterating the entire resorts array.
In that case you can use Array.prototype.every in a nice way: stop "every" iteration process by returning false.
So you can use this code (If resort wasn't found, the name returned will be an empty string):
$scope.resortLocation=function(resort_id){
var resortName = "";
$scope.resorts.every(function(sel_resort){
if(sel_resort.resort_id===resort_id){
console.log(sel_resort.name );
resortName = sel_resort.name;
return false; //Stopping the "every" loop
}
else{
return true;
}
});
return resortName; //returning resort name if exists, if not empty string
}
EDIT:
Corrected the code and added a working Plunker with the same logic.
You have to return the value in order to expose this to scope and return true to avoid extra loop iterations. I Addition, I'm using ngBind to avoid momentarily displayed by the browser in its raw state before Angular compiles it.
$scope.resortLocation = function(resort_id){
var resortName = '';
for (var i = 0; i < $scope.resorts.length; i++){
if($scope.resorts[i].resort_id===resort_id){
console.log($scope.resorts[i].name);
resortName = $scope.resorts[i].name;
break;
}
};
return resortName;
}
Here your example in a plunker

AngularJS smart-table strict search

Smart-table has a built in functionality to search through columns (st-search). Is it possible to perform a strict search for words, so with an exact match? For example: if I have table like this: id, name, status:
1, John, address somewhere
2, Johnny, another address
3, Jane, address
and do a search for 'John' only the first row should show. Is this possible?
I had the same problem. My solution was to use the undocumented stSetFilter feature to pass in my own custom filter.
<table st-set-filter="myFilter" st-table="myData">
Then you just create an angular filter.
angular.module('myApp').filter('myFilter',
function($filter) {
return function(input, predicate) {
return $filter('filter')(input, predicate, true);
};
}
);
In my case I needed to only do strict searches some of the time so I put some additional logic in the filter, but this will do you for doing strict searches all the time.
Mine looks more like this:
angular.module('myApp').filter('myFilter',
function($filter) {
return function(input, predicate) {
var strict = false;
if (predicate) { // some conditional if I want strict
strict = true;
}
return $filter('filter')(input, predicate, strict);
};
}
);
Old, but still relevant.
If you have multiple input fields, but want strict only on some.
#elthrasher gave me the idea.
angular.module('app').filter('myStrictFilter', function($filter) {
return function(input, predicate) {
var response = input,
strict = false,
custom_predicate = {};
// some input fields must be strict
angular.forEach(predicate, function(value, key) {
custom_predicate = {};
custom_predicate[key] = value;
strict = false;
if (key === 'completion_status') { // strict it is.
strict = true;
}
response = $filter('filter')(response, custom_predicate, strict);
});
return response;
};
});
Yo should use strict comparator:
<input type="text" ng-model="query" />
<ul>
<li data-ng-repeat="user in users | filter:{ name:query }:true">
{{ user.id }}, {{ user.name }}, {{ user.address }}
</li>
</ul>
Comparator which is used in determining if the expected value (from
the filter expression) and actual value (from the object in the array)
should be considered a match.
Can be one of:
function(actual, expected): The function will be given the object
value and the predicate value to compare and should return true if
both values should be considered equal.
true: A shorthand for function(actual, expected) { return
angular.equals(actual, expected)}. This is essentially strict
comparison of expected and actual.
false|undefined: A short hand for a function which will look for a
substring match in case insensitive way.
Primitive values are converted to strings. Objects are not compared
against primitives, unless they have a custom toString method (e.g.
Date objects).

rounding a number in input but keep full decimal value in model

I hope that title made sense. Basically I have an small app that does various social security calculations. A user can enter information like birth date, gender, salary etc, and click "calculate social security" and their monthly social security payouts display in an input field. The user can also, if they choose, enter that number in manually. The problem is that the value for that calculation is used elsewhere in the app, so for accuracy, i think I need the full decimal value. But cosmetically, i only need it to the dollar value (2046 vs 2046.3339228485938 bla bla bla). I've seen several tutorials on writing directives for that but that will change the value in the model. It's crossed my mind that i may be going about this the wrong way entirely but i'm turning to stackoverflow in the hopes that this is a common issue that I just cant seem to find the right words for to google.
thanks,
John
Yes, no need of custom filter for this purpose. Angular has its own filter to do this job.
Try this one
<div ng-controller="Ctrl">{{dollar | number:2}}</div>
You can create specific filter, something like:
var app = angular.module("MyApp",[]);
app.filter("rounded",function(){
return function(val,to){
return val.toFixed(to || 0);
}
});
function Ctrl($scope){
$scope.dollar=2046.3339228485938;
}
And use it like:
<div ng-controller="Ctrl">{{ dollar | rounded:2 }}</div>
Example: http://jsfiddle.net/RdgR2/
The other answers aren't quite correct for this because the OP wants it on an input field, but the rounding to be display only.
Using parsers and formatters is a working approach. I found this snippet (https://www.snip2code.com/Snippet/43223/angular-directive-to-format-a-number-in-) and modified it.
Working fiddle is here: http://jsfiddle.net/2akaxojg/
.directive('inputCurrency', function ($filter, $locale) {
return {
terminal: true,
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, ngModel) {
if (!ngModel)
return; // do nothing if no ng-model
// get the number format
var formats = $locale.NUMBER_FORMATS;
// fix up the incoming number to make sure it will parse into a number correctly
var fixNumber = function (number) {
if (number) {
if (typeof number !== 'number') {
number = number.replace(',', '');
number = parseFloat(number);
}
}
return number;
}
// function to do the rounding
var roundMe = function (number) {
number = fixNumber(number);
if (number) {
return $filter('number')(number, 2);
}
}
// Listen for change events to enable binding
element.bind('blur', function () {
element.val(roundMe(ngModel.$modelValue));
});
// push a formatter so the model knows how to render
ngModel.$formatters.push(function (value) {
if (value) {
return roundMe(value);
}
});
// push a parser to remove any special rendering and make sure the inputted number is rounded
ngModel.$parsers.push(function (value) {
return value;
});
}
};
});
Angular has a native number and currency filter:
http://docs.angularjs.org/api/ng.filter:number
http://docs.angularjs.org/api/ng.filter:currency

Resources