Pass index to custom orderBy function - javascript

This might be simple and stupid but I can't seem to figure it out. I have created a ng-repeat structure that I use multiple times on different objects. Basically, I iterate through elements in an array inside those objects and depending on some variable I either need to apply custom orderBy, or leave it in the original order.
So I've created that custom orderBy like that:
<li ng-repeat="tag in filter.tags | orderBy: customSort(filter.customSort)">
Basically, filter object contains array of tags and a boolean variable that states if custom sort needs to be applied. Within my customSort function I check if passed on parameter is true and perform that custom sort. But if it's false - I cannot seem to be able to output tags in their original order in that array.
I cannot pass $index because at that point it is always 0, it only becomes index inside that ng-repeat tag. I cannot do something like that filter.tags.indexOf(tag) because tag doesn't exist yet.
I'm kinda stuck, is there a way to apply orderBy conditionally?
Further explaination:
I iterate over an array of tags and print their localized values, some of those tags should be in their original order, some should be ordered alphabetically in their localized version. So my stripped custom sort does something like this:
$scope.customSort = function(language) {
return function(tag) {
return $scope.tags.[language][tag];
}
}

So far this is the only solution I came up with, I will wait a little to see if anyone answers with a better one before I mark this one as correct.
I had to pass the entire array to the sorting function, along with boolean variable used to determine whether original order or custom sort is desired and then used indexOf like this:
$scope.customSort = function(perform, tags, language) {
return function(tag) {
if (!perform) return tags.indexOf(tag);
return $scope.tags.[language][tag];
}
}

Related

Mixing logical AND and OR in jQuery selector

I have to filter a list of items, that contain two crucial data attributes:
<li class="song" data-title="freedom" data-id="7" data-tags="tag-18-eot,tag-2-eot" data-category="1">Freedom</li>
Category
Tags
Filtering by category should be by logical OR but filtering by tags should be by logical AND.
Filtering using one of these two is not a problem.
I applied, for example:
$(collection).filter('li[data-tags*="tag-50-eot"][data-tags*="tag-51-eot"]');
to filter by tags. Or:
$(collection).filter('[data-category="1"], [data-category="2"]);
to filter by category.
This works fine. However, i could not find a way to combine these two selectors into one single query that i can pass to the filter() function, and chaining two filter() calls does not lead to the desired result, because the first call might filter out items that the second call would leave behind.
I found this question with a similar topic, but the problem is a little different and the approach as well.
How can I filter those items correctly?
You should be able to get what you are looking for with chaining, as long as you use the AND condition first. For example:
var res = $('#collection li')
.filter('li[data-tags*="tag-50-eot"][data-tags*="tag-51-eot"]')
.filter('[data-category="1"], [data-category="2"]');
Fiddle here.
the filter function can receive a function as input...
You may end up with a construct like:
var set = $(collection).filter(
function( index, element )
{
return ($(element).attr(...) == "...");
}
);

linqjs intersect comparer issue

I am using linqjs and I have one array full of ids to include in a list, and an array full of complex objects which have a property userId.
Problem is when I do an intersection it never seems to return anything, however there is very little information around the compareSelector.
So here is an example of what I am doing:
enumerableOfUsers.intersect(listOfIdsToInclude, "$.userId");
So in the above example enumerableOfUsers would be an existing enumerable created from an array of users (which contain the userId field), the listOfIdsToInclude is an array of id values, like ["12345", "213213", "2124"] etc.
The intersect seems to work but never returns anything and I know the userIds match so am I doing anything wrong here?
The thing is that the compare selector is applied to items of both the first and second sets. The second set is a list of ids already so the compare selector doesn't apply. The projection yields undefined values which will always result in no results found.
You need to apply the selector only to the first set of values. Try this instead:
// using linqjs 2.x syntax
var query = enumerableOfUsers.Select("$.userId").Intersect(listOfIdsToInclude);

How to iterate elements from an array and translate them using angular-translate

I have a json file that contains a few variables, including an array. In my template I use ng-repeat to iterate through this array and display each element. The number of elements in the array can change, because the json is retrieved through a web service call.
Now I want to use angular-translate to enable multiple languages. I am trying to use angular-translate-loader-url for this.
The problem is that I don't see how I can use it with ng-repeat. The values can be accessed by specifying their keys. In the usual case you know the key, and the number of keys, but that's not so in my case where it's all dynamic. I don't really care about the key names. What I need is a scope variable that holds all these keys, so that I can iterate. I don't see a way to get the data in a scope variable...
I can see that the fundamental problem is that I have the strings in an ordered array, and that doesn't seem to be supported by angular-translate. What would be a good solution?
You're going to want to create a custom filter and then pass the filter through your repeater...
E.g...
myApp.filter('translateFilter', function($translate){
return function(input, param){
//Iterate through each item, translate using $translate, then return the translated items
}
});
Then use you can use your filter however you wish:
<li ng-repeat="car in cars | translateFilter:search">
{{ car.name | translate }}
</li>
etc.
Please see the following for a full example: AngularJS and i18n : apply ng-repeat filters after translating list items properties

Ember filterBy - using more than one value to filter

How can I use more than one value to filter a list using the filterBy function?
My scenario is - I have a list of consoles which I want to filter based on the console_id.
Unfortunately, I don't have control over the JSON so each consoles has a different ID. I would like to loop through the Console IDs within the nested assignedConsole JSON and then filter through the root assignedConsole JSON.
I can get the console ID of the first object and place it into the filter but I don't know how I can use two values
I have created a emberjs bin to demonstrate my problem: http://emberjs.jsbin.com/kojute/2/
After some clarification from my previous answer, I realized you want to filter by console instead of filtering the assignedConsole values. My suggestion is to add a selectedConsole property on the controller, and display the array of assignedConsoles for the selected console.
Working JSBin: http://jsbin.com/nuroyuvuta/9
EDIT: See my other answer for the working solution!
I would suggest creating a computed property on your model or your controller that flattens that nested structure for you:
allConsoles: function() {
return this.get('consoles')
.mapProperty('assignedConsoles').reduce(function(a, b) {
return a.concat(b);
})
.uniq();
}.property('consoles.#each')
This will first get all of the items from the consoles property, then map all of their assignedConsoles to an intermediate value, which is then reduced by adding all the assignedConsoles together. The final uniq() call just removes any duplicates found in the array.

Underscore JS, Grouping by an array Attribute.

I'm trying to use Javascript to group an array by one of it's attributes.
Essentially I have a list of e-mail templates, and I'm trying to group them by the category that they are in so that I can make a collapsible accordion with it later.
I think I might have the syntax of underscore JS wrong, or I'm addressing my array incorrectly. Currently I am calling groupby using the following command:
console.log(_.groupBy(result, 'im_category'));
but my array looks like the 'im_category' property is hidden under the attributes function. I'm not sure how to get there.
I've attached my console.log of what the array looks like and what happens when I run that command. (I get three different objects when I should get 2 if it's working correctly. )
Your im_category is a property of the attributes object in your businessEntity - _.groupBy is looking for properties of businessEntity. You need to create a function as iteratee:
var grouped = _.groupBy(result, function (item) {
return item.attributes.im_category;
});
http://jsfiddle.net/jwnzh8w0/

Categories

Resources