Filter on Onsen UI lazy repeat? - onsen-ui

Is there a way to apply a search filter on an Onsen UI lazy repeat list ?
If we use for instance <input ng-model="search.$">
We can't directly apply | filter:search as it is not an ng-repeat.
Any idea ?
Thank you.

You need to filter the results return by the delegate object:
Simple example:
$scope.MyDelegate = {
configureItemScope: function(index, itemScope) {
itemScope.name = $scope.filteredItems[index].name;
},
calculateItemHeight: function(index) {
return 44;
},
countItems: function() {
return $scope.filteredItems.length;
}
};
In this codepen a large list of countries is filtered in this way:
http://codepen.io/argelius/pen/VLdGxZ

Related

How to query a JSON object

In my AngularJS web app, How can I query a JSON object ?
For example in the below JSON object how can I find the value of reportTypeLabel where reportTypeId=3
JSON:
[
{
reportTypeId:5,
reportTypeCode:"FINREP",
reportTypeLabel:"Financial Reporting"
},
{
reportTypeId:9000002,
reportTypeCode:"REM HE",
reportTypeLabel:"High Earners"
},
{
reportTypeId:3,
reportTypeCode:"COREP LE",
reportTypeLabel:"Large Exposures - COREP"
}
]
You can require $filter service and do
var elements = $filter('filter')(arrayOfObjects,{reportTypeId: 3});
elements will be an array of all the elements with that 'reportTypeId'
i would recommend reading about angular filters and https://docs.angularjs.org/api/ng/service/$filter
If you're going to use data manipulation extensively, I'd highly recommend using a JS library, like underscore or lodash.
For example, using underscore:
// assuming your object is called data
var result = _.findWhere(data, {
reportTypeId: 3
}).reportTypeLabel;
// result === 'Large Exposures - COREP'
You could do this
<div ng-repeat="report in reports | filter:{reportTypeId:'3'}">
{{report.reportTypeCode}}
</div>
Working Fiddle
You can use regular filter function on array:
var items = [
{reportTypeId:5, reportTypeCode:"FINREP"},
{reportTypeId:9000002, reportTypeCode:"REM HE"}
];
var onlyMatching = items.filter(function(item){ return item.reportTypeId == 3; });
Or an angular filter in html
<div ng-repeat="item in items | filter: {reportTypeId: '3'}">{{item. reportTypeLabel}}</div>
Or an angular filter through $filter service
module.controller('ItemsCtrl', function($filter){
$scope.filtered = $filter('filter')($scope.items,{ reportTypeId: '3' });
});

Can I filter promise when using Angular Material Autocomplete (md-autocomplete)

I have the following in my autocomplete
md-autocomplete(flex-gt-sm="50"
placeholder="Select label or enter new label",
md-selected-item="ctrl.node.label",
md-items="item in ctrl.getLabels() | filter:ctrl.labelSearchText",
md-item-text="item",
md-search-text="ctrl.labelSearchText",
md-floating-label="Label")
md-item-template
span {{item}}
With the following as getLabels
this.getLabels = function() {
return Restangular.all('label').getList();
};
When I run this code it does not filter the results instead I get the entire list. Is there a way to filter these results?
I am not sure if you can filter with angular filters in the tag itself. But you can do this with lodash.filter or angular filters in the javascript function.
md-autocomplete(flex-gt-sm="50"
placeholder="Select label or enter new label",
md-selected-item="ctrl.node.label",
md-items="item in ctrl.getLabels(ctrl.labelSearchText)",
md-item-text="item",
md-search-text="ctrl.labelSearchText",
md-floating-label="Label")
md-item-template
span {{item}}
And the getLabels function.
this.getLabels = function(searchText) {
return this.$q(function (resolve) {
Restangular.all('label').getList().then(function (result) {
resolve(_.filter(result.data, function(label) {
// filter here, simple case string equality
return label === searchText;
}));
});
});
};

remove double results value from forEach (angular js)

there is this thing who i am not figuring out,
i have a controller that return me an array of products propriety, that populate a field, so far i have done this:
$scope.categoryForFilter=[];
//product load
ProductService.listProducts().then(function(data) {
$scope.products = {
count: data.count,
list: data.aaData,
length: data.aaData.length
};
$scope.products.list.forEach(function (element) {
$scope.categoryForFilter.push({"id": element.category.id, "label": element.category.label})
});
});
but in this way i have multiple element.category.label in the options field that in my view is the following:
<select ng-model="categoryForFilter" ng-options="cat.label for cat in categoryForFilter" st-search="cat.label">
<option></option>
</select>
so how can i filter the results who have the same value in the array? anyone can help please?
You can use the unique filter, which is part of Angular UI.
You can also use this filter using lodash:
app.filter('unique', function() {
return function (arr, field) {
return _.uniq(arr, function(a) { return a[field]; });
};
});
Source
There is a real easy way to this by using lib like lodash with the function "uniq":
$scope.categoryForFilterWithUniqLabel = _.uniq($scope.categoryForFilter, 'label');

AngularMaterial md-chips : Dont show selected item in <md-autocomplete>

I'm trying the <md-autocomplete> example from here md-chips
To prevent the selected items from coming inside <md-autocomplete> I've modified the querySearch function like this:
function querySearch (query) {
var results = query ? self.searchData.filter(createFilterFor(query)) : [];
var finalResults = [];
angular.forEach(results, function(result) {
if($scope.selectedItems.indexOf(result.name) < 0) {
finalResults.push(result);
updateSelectedItems(result);
}
});
return finalResults;
}
But my problem is that the control does not come inside this function once we select an item. Can someone please explain how to solve this ?
I found the solution from this documentation: md-autocomplete
We just need to add md-no-cache="true" for calling the querySearchfunction each time we search for a query item
The solution that worked for me:
The md-no-cache="true" on md-autocomplete still is a must to force the autocomplete to reinitialize the md-items;
Md-chips should have md-on-remove and md-on-append set and implemented as to remove a chip from the list, or add a chip to the list;
My code looks something like this:
HTML:
md-on-remove="removeTagChip($chip)"
md-on-append="appendTagChip($chip)"
JS:
$scope.removeTagChip = function (chip) {
var chipPos = $scope.getPosition(chip.Id, $scope.ChipTags);
if (chipPos < 0) {
$scope.ChipTags.push(chip);
}
};
$scope.appendTagChip = function (chip) {
var chipPos = $scope.getPosition(chip.Id, $scope.ChipTags);
if (chipPos > -1) {
$scope.ChipTags.splice(chipPos, 1);
}
return chip;
};
$scope.getPosition just returns the position of the chip in the list of chips;

How to create a new list based on an old one in AngularJS

I have the list in my controller:
$scope.newsLists = [
{ newsName: list1, newsStatus: isOpen },
{ newsName: list2, newsStatus: isOpen },
{ newsName: list3, newsStatus: isOpen },
{ newsName: list4, newsStatus: isClosed }
];
then I'd like to create another list based on this $scope.newsList.
such as:
$scope.valueNewsLists = $scope.newsLists(list.newsStatus == isOpen);
But I don't know how to create the $scope.valueNewsLists in a correct way.
I do need this list because I have to write a function for pages.
If somebody have a explication for this problem, I would be very appreciated !
You can filter existing array with built in Javascript Array.prototype.filter function:
var isOpen = function(element) {
return element.newsStatus == isOpen
}
$scope.valueNewsLists = $scope.newsLists.filter(isOpen);
You can use filter on template in order to get the result you wanted.
<div ng-repeat="list in newsList| filter:{newsStatus:'isOpen'}">
<input ng-model="list.newsName" />
</div>

Resources