Sort the columns if the flag is true-orderby angularJS - angularjs

I have a table which is sorted on the name column by default.I want to enhance it to make that sorting behavior optional based on a isSortingRequired flag.How can i provide a conditional orderby clause in my template.

You can use ternary operator like
orderBy:(isSortingRequired?'CONDITION_FOR_SORT_REQUIRED':'CONDITION_FOR_SORT_NOT_REQUIRED')
Demo

orderBy:(isSortingRequired?'CONDITION_FOR_SORT_REQUIRED':'CONDITION_FOR_SORT_NOT_REQUIRED')
When '' is passed to an orderby filter it tries to sort by hashkey of the object this might create issues in the order of the records.The solution is to use a custom filter as defined below which uses the built in orderBy filter if the flag is true.
.filter('customOrder',function($filter)
{
return function(friend, prediate,isSortRequired){
if(!isSortRequired)
return friend;
else
{
var result = $filter("orderBy")(friend, prediate);
return result;
}
}
});
The solution can be seen here.This has fixed my issue.

Related

angularjs 1.5: How to enable auto-sort on key value object?

I recently upgraded my application from angularjs v1.2 to v1.5. On v1.2 angularjs was auto sorting key/value based objects in drop-down. But now as I upgraded to 1.5 every drown on my web app is showing items in random order (i.e. order coming from db). Is there any global parameter I can enable in 1.5 to get that auto-sort functionality again?
app.controller('MainCtrl', function($scope) {
$scope.days = {
'key1': 'val1',
'key7': 'val7',
'key3': 'val3',
'key9': 'val9',
'key2': 'val2',
'key5': 'val5',
'key4': 'val4',
};
});
I created plunk for both versions to ellaborate the problem clearly,
ver 1.2
https://plnkr.co/edit/o0KJXjW25nlvDoKliHV0?p=preview
ver 1.5
https://plnkr.co/edit/TudDwMhaAREhGVl5vz2c?p=preview
Always have a look at the migration guide before migrating to new version.
On v1.2 angularjs was auto sorting key/value based objects in drop-down. But now as I upgraded to 1.5 every drown on my web app is showing items in random order.
From MDN article
The for...in statement iterates over the enumerable properties of an
object, in arbitrary order.
In AngularJS 1.5.0, ng-options directive used getOptionValuesKeys() method to get the array of keys. In that method, they used for...in that does not guarantee the order of iteration. That is why values in the drop-down are not sorted.
function getOptionValuesKeys(optionValues) {
var optionValuesKeys;
if (!keyName && isArrayLike(optionValues)) {
optionValuesKeys = optionValues;
} else {
// if object, extract keys, in enumeration order, unsorted
optionValuesKeys = [];
for (var itemKey in optionValues) {
if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') {
optionValuesKeys.push(itemKey);
}
}
}
return optionValuesKeys;
}
In AngularJS 1.2.28, ng-options directive used sortedKeys() method to get the array of keys. They also used for...in in this method but sorted the array before returning it.
function sortedKeys(obj) {
var keys = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
keys.push(key);
}
}
return keys.sort();
}
Is there any global parameter I can enable in 1.5 to get that auto-sort functionality again?
Yes, but may be you shouldn't change. To do this, you have to sort the return value of getOptionValuesKeys method in AngularJS source code. Modified method should look like this:
function getOptionValuesKeys(optionValues) {
var optionValuesKeys;
if (!keyName && isArrayLike(optionValues)) {
optionValuesKeys = optionValues;
} else {
// if object, extract keys, in enumeration order, unsorted
optionValuesKeys = [];
for (var itemKey in optionValues) {
if (optionValues.hasOwnProperty(itemKey) && itemKey.charAt(0) !== '$') {
optionValuesKeys.push(itemKey);
}
}
}
return optionValuesKeys.sort();
}
Additional question may arise: Why Angular team made this change?
Migrating from 1.3 to 1.4: Have a look at the changes in ngOptions
Due to 7fda214c, when iterating over an object's properties using the (key, value) in
obj syntax the order of the elements used to be sorted
alphabetically. This was an artificial attempt to create a
deterministic ordering since browsers don't guarantee the order. But
in practice this is not what people want and so this change iterates
over properties in the order they are returned by Object.keys(obj),
which is almost always the order in which the properties were defined.
Note:
This change was made in AngularJS 1.4.0, not in 1.5.0. As you are migrating from 1.2.28, you should consider all changes from version 1.3.0 to 1.5.0.
Check out this plunk.
What you have to do is add one function objectKeys like this
$scope.objectKeys = function(obj){
return Object.keys(obj).sort().map(function(k) { return obj[k] });
};
And then replace the object we were using on the ng-options with this function.
<select ng-model="test" ng-options="k as v for (k,v) in objectKeys(days)" />

How to create complex query parameters in Restangular

I need to create a fairly complex query string in Restangular.
http://vdmta.rd.mycompany.net//people?anr=Smith&attrs=givenName,displayName,name,cn
How do I do this?
So far I am OK getting as far as ?anr=Smith using this:
return Restangular.all('/people').getList({anr:searchTerm});
The last part attrs=x,y,x lets me control which attributes I want back in the search and could change per request I make.
Any advice appreciated.
Regards
i
You should be able to simply add another query parameter where the value is your comma separated list of attributes.
var attributes = ['givenName' , 'displayName']; // attributes you require for the request
var attributesAsString = attributes.join();
return Restangular.all('/people').getList({
anr : searchTerm,
attrs: attributesAsString
});

How create a dynamic filter with multiple checkboxes in angularJS

I've been looking for severeal days how to create a dynamic filter with multiple checkboxes in AngularJS easily and none of the solutions I found satisfied me.
Here is an example of a filter that will display everything when the checkboxes are unchecked and filter the data when checkboxes are checked. (Good for search engine to look for a hotel with wifi, balcony... for example)
Filter :
app.filter('conveniences_filter', function() {
return function( items, types) {
var filtered = [];
var displayItem;
angular.forEach(items, function(item) {
displayItem = true;
angular.forEach(types, function(type, key) {
if(type == true && item[key] == false) {
displayItem = false;
}
});
if(displayItem == true) {
filtered.push(item);
}
});
return filtered;
};
});
In your controller :
$scope.types = {wifi: false, balcony: false}
In your HTML
ng-repeat="property in properties | conveniences_filter:types"
Important : Your keys in your $scope.types have to be the same as your key in your properties items or it's not gonna work.
Example of a property here :
Object { name: property, wifi: false, balcony: true }
I hope it's gonna be useful :)
I think it's not 100% clear what your requirements are here. At least from what I get from the code you've written is that you'd like to filter a list of objects based on their property values and that you use a "schema" object that is used to compare against the objects.
To fill the gaps in the requirements I'm assuming you want to validate against an "schema" object that contains properties that also need to match in your items. I'm also assuming that if a property is not in the "schema" object then it will not be relevant for the comparison. Also I assumed that you want all present properties in the "schema" to be valid / matching otherwise the item is not considered.
I've put together a small example solving the above requirements. In general you should use the array extra functions that come with ECMA5.1 and make things much simpler and functional style.
Example: http://jsbin.com/velobi/1/edit
Cheers
Gion

how to make full text combination filter in angularjs

I tried to make angularjs full text search like in this plunker
http://plnkr.co/edit/PwcteF6WAtuAOj3ZDKLe?p=preview
I've tried many combination but none works..
e.g I want to search cross column like 'alex big-mary' or 'alex 800' or 'mary big' but not works
alex 555 works because 555 exist right after alex word
I dont know any built-in filter that would perform an OR-like search. You can define your own filter that would fit your needs:
angular.module('App', []).filter('search', function($filter){
return function(items, text){
if (!text || text.length === 0)
return items;
// split search text on space
var searchTerms = text.split(' ');
// search for single terms.
// this reduces the item list step by step
searchTerms.forEach(function(term) {
if (term && term.length)
items = $filter('filter')(items, term);
});
return items
};
});
See this code in action using this Plunkr: simple OR search filter
You will need to create a custom filter that will take your data and tokenize it on per row basis and only display those rows that match the strings that you enter.
Here are the docs for creating custom filters:
http://docs.angularjs.org/guide/dev_guide.templates.filters.creating_filters

How to apply angular filter to an array

I am trying to apply Angular filter to the following array after following the instructions here http://docs.angularjs.org/api/ng.filter:filter:
[{"id":"compute-1.amazonaws.com_Delivery","id":"compute-1.amazonaws.com_TaskJob","id":"UpdateFiles","id":"TaskRequest"}]
Say the filter values are:
filter = "TaskRequest";
filter = "Taskjob";
filter = "UpdateFiles";
filter = "Delivery";
How can I apply Angular filter:
I have tried:
conData = JSON.stringify(data);
results = $filter('filter')(conData, filter, false);
I have also tried :
results = $filter('filter')(conData, filter, true);
results = $filter('filter')(conData, filter);
When I examine the results of the filter nothing changes and I get back the same array.
So if the filter applied was "Delivery"
The results array would be :
[{"id":"compute-1.amazonaws.com_Delivery"}]
What am I doing wrong here?
Not sure if it is a copy/paste mistake but the array you provide in your first source extract is wrong (or at least won't do what you expect). If you look closely the key id is repeated inside the same JSON object. Try with the following array :
[
{"id":"compute-1.amazonaws.com_Delivery"},
{"id":"compute-1.amazonaws.com_TaskJob"},
{"id":"UpdateFiles"},
{"id":"TaskRequest"}
];
BTW I assembled a lighter version of your code accessible here where the filtering is working.

Resources