I'm writing an Angular app that will read a magnetic stripe card from a USB device. When I swipe a test card, I get a string back containing the card number. For example, ;12345?, where 12345 is the card number.
The data my app uses doesn't include these "control characters", so I'd like to strip them out of the search string if the string starts with a ; and ends with a ?.
When I write a custom filter:
angular.module('app.filters', [])
.filter('stripcardcontrolcharacters', function() {
return function(text) {
if(text.substring(0, 1) === ";" && text.substring(text.length - 1) === "?") {
return text.substring(1, text.length - 1);
}
};
});
It fails because I'm ng-repeating over an array, and not the string that I've searched for.
How would I get what string I'm filtering for and strip the characters from it?
EDIT: Current suggestion is to use a filter to modify the array to ADD in the control characters so filter: can find it. I might go with that for now, but I'm still curious to know if you can write such a filter
You're passing the entire array to your filter via
ng-repeat="user in users | stripcardcontrolcharacters ...
If that's how you want it to work, you would need to treat it as an array, for example
return function(textArray) {
var invalidChars = /\D/g; // just an example
return textArray.map(text => {
console.log(text);
return text.replace(invalidChars, '');
});
}
You are probably applying the filter to the array, not the string itself.
Look at this example:
angular.module('test', [])
.controller('testController', function($scope){
$scope.names = ['John Doe', 'Jane Doe'];
})
// The test filter
.filter('strip', function(){
return function(str) {
return str.substring(1, str.length - 1);
};
});
And here is how to use it:
<body ng-app="test" ng-controller="testController">
<p ng-repeat="name in names">
{{name | strip }}
</p>
</body>
Note that I'm applying the filter where I use the value, not in the ng-repeat statement.
And here is the working plunker
Related
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
I am new to AngularJS. I have 3 input fields to enter up to 3 keywords for a single post:
<input type="text" ng-model="Keyword1"></input>
<input type="text" ng-model="Keyword2"></input>
<input type="text" ng-model="Keyword3"></input>
I am displaying the posts using ng-repeat:
ng-repeat="post in posts | filter: searchKeyword"
...
and searching by:
Search Keyword: <input ng-model="searchKeyword.Keyword1">
As you can see, this currently only searches the first keyword of every post. How can I have only one search field that searches all three keywords of a post? I know I cannot just do
<input ng-model="searchKeyword.Keyword1.Keyword2.Keyword3">
Thanks!
Not sure if the intention is to return all posts that match at least one keyword or all posts that match all keywords. Here is how you could create a custom filter for matching at least one word:
<div ng-controller="theController">
<input ng-model="inputText"/>
<!-- Use a custom filter to determine which posts should be visible -->
<ul>
<li ng-repeat="post in posts | filter:myFilter">{{post}}</li>
</ul>
</div>
angular.module('theApp', [])
.controller('theController', ['$scope', function($scope) {
$scope.inputText = 'test';
$scope.posts = [
'test test2;lksdf asdf one asdf poo',
'arm test test2 asdf',
'test head arm chest'
];
$scope.myFilter = function(post) {
// default to no match
var isMatch = false;
if ($scope.inputText) {
// split the input by space
var parts = $scope.inputText.split(' ');
// iterate each of the words that was entered
parts.forEach(function(part) {
// if the word is found in the post, a set the flag to return it.
if (new RegExp(part).test(post)) {
isMatch = true;
}
});
} else {
// if nothing is entered, return all posts
isMatch = true;
}
return isMatch;
};
}]);
And here is the plunkr: http://plnkr.co/edit/d17dZDrlhY2KIfWCbKyZ?p=preview
NOTE: this solution does not limit the keywords to 3. Any number of keywords can be entered, separate by the space character. If nothing is entered (or just spaces), everything is returned.
Here is what i will do
write a custom filter (https://docs.angularjs.org/guide/filter)
in filter split the input by space (which will give you separate words)
search all words in input one by one
I'm new to AngularJS and trying to create a simple app that will allow me to upload files to my Laravel driven website. I want the form to show me the preview of what the uploaded item will look like. So I am using ng-model to achieve this and I have stumbled upon the following:
I have an input with some basic bootstrap stylings and I am using custom brackets for AngularJS templating (because as I mentioned, I am using Laravel with its blading system). And I need to remove spaces from the input (as I type it) and replace them with dashes:
<div class="form-group"><input type="text" plaeholder="Title" name="title" class="form-control" ng-model="gnTitle" /></div>
And then I have this:
<a ng-href="/art/[[gnTitle | spaceless]]" target="_blank">[[gnTitle | lowercase]]</a>
And my app.js looks like this:
var app = angular.module('neoperdition',[]);
app.config(function($interpolateProvider){
$interpolateProvider.startSymbol('[[').endSymbol(']]');
});
app.filter('spaceless',function(){
return function(input){
input.replace(' ','-');
}
});
I get the following error:
TypeError: Cannot read property 'replace' of undefined
I understand that I need to define the value before I filter it, but I'm not sure where to define it exactly. And also, if I define it, I don't want it to change my placeholder.
There are few things missing in your filter. First of all you need to return new string. Secondary, regular expression is not correct, you should use global modifier in order to replace all space characters. Finally you also need to check if the string is defined, because initially model value can be undefined, so .replace on undefined will throw error.
All together:
app.filter('spaceless',function() {
return function(input) {
if (input) {
return input.replace(/\s+/g, '-');
}
}
});
Demo: http://plnkr.co/edit/5Rd1SLjvNI18MDpSEP0a?p=preview
Bravi just try this filter
for eaxample {{X | replaceSpaceToDash}}
app.filter('replaceSpaceToDash', function(){
var replaceSpaceToDash= function( input ){
var words = input.split( ' ' );
for ( var i = 0, len = words.length; i < len; i++ )
words[i] = words[i].charAt( 0 ) + words[i].slice( 1 );
return words.join( '-' );
};
return replaceSpaceToDash;
});
First, you have to inject your filter in you module by adding it's name to the array :
var app = angular.module('neoperdition',['spaceless']);
Secondly, the function of the filter have to return something. The String.prototype.replace() return a new String. so you have to return it :
app.filter('spaceless',function(){
return function(input){
return input.replace(' ','-');
}
});
Edit: dfsq's answer being a lot more accurate than mine.
I have a simple string array coming from a server:
[{"things":["me", "my"]}]
In my page, to display the array I have:
{{things}}
And it prints:
["me", "my"]
How do I control the printing, for instance, if I want to eliminate the brackets and quotes?
You can implement a scope function to display arrays as comma separated strings like shown in this fiddle.
$scope.array = ["tes","1","2","bla"];
$scope.arrayToString = function(string){
return string.join(", ");
};
Now you can call this function within the template:
{{arrayToString(array)}}
Update
You can also use the join() method of arrays directly within the template without using an extra function inbetween as displayed within the updated fiddle.
{{array.join(", ")}}
I think you'll want ngRepeat for something like:
<div class="list" ng-repeat="thing in things">
{{ thing }}
</div>
You can also create custom angular filter optionally with some advanced formatting:
module.filter('formatArray', ['OptionalInjection', function(OptionalInjection) {
return function(value) {
if (!angular.isArray(value)) return '';
return value.map(OptionalInjection.formatter).join(', '); // or just return value.join(', ');
};
}])
Then in html just write {{yourArrayValue | formatArray}}.
I am having trouble ordering strings containing characters that are not in the English alphabet ( š,č,ž,..)
Here is the fiddle: http://fiddle.jshell.net/vhhgh/
The letters are from the Slovenian alphabet.
It's been a while, but I found other solution: fiddle
HTML:
<div ng-app='test'>
<h2>Users</h2>
<div ng-controller="UsersCtrl">
<ul>
<li ng-repeat="user in users | localeCompareString">
{{user.surname}} {{user.name}}
</li>
</ul>
</div>
</div>
JS:
(function(angular) {
'use strict';
var test=angular.module('test',[])
.controller('UsersCtrl', ['$scope',function($scope) {
$scope.users = [
{name:'Ben', surname:'Živkovič'},
{name:'Ken', surname:'AlGore'},
{name:'Erica', surname:'Červ'},
{name:'Jane', surname:'Šinigoj'},
{name:'Kevin', surname:'Sort'},
{name:'Roger', surname:'Willson'},
{name:'Kim', surname:'Zorro'}
];
}]).filter('localeCompareString',function(){
return function (items) {
//window.console.log(items);
items.sort(function (a, b) {
return a.surname.localeCompare(b.surname);
});
return items;
};
});
})(window.angular);
Ordering arrays of strings with "foreign" letters isn't as easy to do as you might think. Actally, it can be a right pain in the ... to get right. The problem boils down to the fact that the Unicode charset contains (pretty much) all charactrers in existance, so a universal lexicographical sorting isn't possible since different countries all have different ways they expect the sorting to be handled.
To get around this, I've found TCollator, a small library aiming at fixing that issue, very useful.
You can compare two strings with the String.localeCompare() method. It's then easy to create your own filter to sort your array:
MyApp.filter('myOrderBy', function () {
return function (array, property, reverse) {
var result = array.sort(function (object1, object2) {
if (angular.isUndefined(property)) {
return object1.localeCompare(object2);
}
return object1[property].localeCompare(object2[property]);
});
return reverse ? result.reverse() : result;
};
});
Starting from AngularJS 1.5.7, orderBy takes an optional comparator function. The docs contain an example involving a locale-sensitive comparator.