AngularJS-Filters no filter empty attribute - angularjs

I have a problem when the attribute of the object does not exist and I can not filter using "!null", I wonder if filter can validate this or i need to create a new filter for this.
Html ng-repeat
<li ng-repeat="detail in details | filter:{shortDescription: '!null'}">
<p>{{detail.name}}</p>
</li>
JavaScript Array
$scope.details = [{
name: 'Bill',
shortDescription: null
},{
name: 'Bill2',
}, {
name: 'Sally',
shortDescription: 'A girl'
}];
Result
Bill2
Sally
Bill2 have no exist shortDescription but not filter.
expected Result:
Sally
JSFiddle
http://jsfiddle.net/4wxs67yv/28/
AngularJS v.1.3.15
How i can do this?

You could try using double not operator,as
<li ng-repeat="detail in details | filter:{shortDescription: '!!'}">
<p>{{detail.name}}</p>

Related

AngularJS Custom Filter to filter type of items

I am trying to write a filter so that it filters me type of items.. for instance, there will be some dropdown item like rich, poor, very poor, in HTML/frontend... when i click on rich it should filter rich type of filter in ng-repeat
here you go for my object:
$scope.names = [
{name:'Jani',country:'Norway', type: 'RICH'},
{name:'Carl',country:'Sweden', type: 'POOR'},
{name:'Margareth',country:'England', type: 'EXTREM POOR'},
{name:'Hege',country:'Norway', type: 'RICH'},
{name:'Joe',country:'Denmark', type: 'VERY POOR'},
{name:'Gustav',country:'Sweden', type: 'VERY POOR'},
{name:'Birgit',country:'Denmark', type: 'VERY RICH'},
{name:'Mary',country:'England', type: 'RICH'},
{name:'Kai',country:'Norway', type: 'POOR'}
];
the filter i am crafting:
app.filter('typeFilter', function() {
return function(x) {
return #;
};
});
but I failed to do it... can anyone help me to craft it out?
You can use the built-in filter 'filter':
In your html, use this:
Enter your type here:
<input ng-model="type"/>
<div ng-repeat="item in names | filter: type">
{{item.name}} - {{item.type}}
</div>
You can more with this filter, for reference:
https://docs.angularjs.org/api/ng/filter/filter
Edit #01
You can also use a function with the filter:
HTML
<div ng-repeat="item in names | filter: myFilter">
{{item.name}} - {{item.type}}
</div>
JS
$scope.myFilter = function(item){
if (item.type === something){
return item;
}
}
This way you can filter with multiple properties, etc

Two-tier sorting for ng-repeat

For example, I have the following collection used for ng-repeat:
$scope.pokedex = [{
type: "Fire",
pokemon: ["Charizard", "Moltres"]
},{
type: "Rock",
pokemon: []
},{
type: "Fighting",
pokemon: ["Machamp", "Hitmonchan"]
},{
type: "Dragon",
pokemon: []
}];
This collection will be churned out in a ng-repeat directive. In the actual application, the collection will be retrieved from a database, so it may be unsorted. I want to sort it in the following manner: priority sort types with Pokemon to the top, then sort each group by name.
Edit: I need to clarify what the backend data consists of. In the above example, $scope.pokedex consists of a constant number of types - these are categories. The application retrieves Pokemon from the database and fill up each category's list accordingly. The full range of types is intentionally hardcoded into the array and will remain unchanged regardless of whether the list of Pokemon in it is empty or not.
When the web page is generated using ng-repeat, the desired end state is as follows:
An accordion is displayed with each type as a header, and the list of Pokemon in the body as a list/table.
All empty categories shall be disabled but still visible, their headers given a particular CSS format, and all of them PUSHED TO THE BOTTOM beneath the non-empty categories.
The empty group and non-empty group shall individually be sorted by category/type name.
Everything except the pushing of empty groups to the bottom and the sorting by name have been implemented. These are my final requirements to implement.
How can I do that? Is there a way to do it in advance, or via orderBy during ng-repeat, or any other workable solution?
You Can Try like this This
<ul>
<li ng-repeat="people in peoples | orderObjectBy:'pokemon':true">{{ people.name }}</li>
</ul>
Please try the code below
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="pokemonController">
<ul>
<li ng-repeat="people in peoples | orderBy:['-pokemon.length','name']">
name: {{people.name}} - number of Pokemons: {{people.pokemon.length}}
<hr />
</li>
</ul>
</div>
</div>
<script>
var app = angular.module('myApp',[]);
app.controller('pokemonController', ['$scope', function($scope){
$scope.peoples = [{
name: "Obama",
pokemon: ["Charizard", "Dragonite", "Moltres"]
},{
name: "Merkel",
pokemon: []
},{
name: "Putin",
pokemon: ["Machamp", "Hitmonchan"]
},{
name: "Kim",
pokemon: []
}];
}]);
</script>

Filter ng-repeat table with multiple filter values for one column

I've generated a dynamic table from array of objects and paginated the rows with angular-ui-bootstrap. I also need to implement row filter functionality in table based on user selections. For example, I would select one or more Cities from check-boxes and only the rows with matching Cities should be shown, or user will select certain names, or a combination of both. Below is sample data:
ctrl.data = [{
id: 1,
name: 'Ram Kumar',
city: 'Delhi',
date: new Date("October 13, 2014 11:13:00")
}, {
id: 2,
name: 'Raman Kumar',
city: 'Mumbai',
date: new Date("November 13, 2014 11:13:00")
}, {
id: 3,
name: 'Raghav Kumar',
city: 'Chennai',
date: new Date("December 13, 2014 11:13:00")
}];
I've also created a metadata which will contain information about all properties of data such as property name, it's unique values, the kind of filter which this property would require i.e. check-box or a slider. Below is the metadata:
ctrl.metadata = [{
name: "ID",
values: [1, 2, 3],
type: "checkbox",
showFilter: false
}, {
name: "Name",
type: "checkbox",
values: ["Ram Kumar", "Raman Kumar", "Raghav Kumar"],
showFilter: false
}, {
name: "City",
type: "checkbox",
values: ["Delhi", "Mumbai", "Chennai"],
showFilter: true
}, {
name: "Birth Date",
type: "date",
showFilter: false
}, {
name: "Age",
type: "slider",
values: [18,26],
showFilter: false
}];
I've currently made a one-value static filter query variable for some attributes such as ID, Name and City.
<div ng-repeat="attr in metadata">
<div ng-if="attr.name === 'ID'">
Enter Filter:
<input type="textbox" ng-model="search.id" />
</div>
<div ng-if="attr.name === 'City'">
Enter Filter:
<input type="textbox" ng-model="search.city" />
</div>
<div>
And I am applying this filter to table rows in this way:
<tr ng-repeat="row in data | filter: search | pages: currentPage : itemsPerPage">
<td ng-repeat="item in row">{{ item }}</td>
</tr>
But firstly, I want the filter query variable (search) to be dynamically generated, as the data and metadata might change. Something like below if possible:
<div ng-repeat="attr in metadata">
<div ng-if="attr.name === 'ID'">
Enter Filter:
<input type="textbox" ng-model="attr.searchQuery" />
</div>
</div>
I attached the search query to metadata object property called searchQuery. But when I am trying to use it in filter, I see no result:
<tr ng-repeat="row in data | filter: metadata[$index].searchQuery | pages: vm.currentPage : vm.itemsPerPage">
<td ng-repeat="item in row">{{ item }}</td>
</tr>
Secondly, the search query can take only one string, but as I want the filter to be based on more than one value, how can I achieve it? I've researched about custom filter but the problem is, how do I 'record' the selected values, and then send it to the filter (for example, get all the selected cities from check-boxes) ? I have to make every variable dynamic or part of metadata so that it does not break when either number of properties, or name of properties or values are changed. There might be no Cities but States when data is changed, so can't make anything static.
Please suggest some ideas for implementation.
Here is a working plunker.
First you should change your <input> to:
<input type="checkbox" ng-model="vm.selected[$index]" ng-true-value="'{{value}}'" ng-false-value="" /> {{value}}
Then your ng-repeat:
<tr ng-repeat="row in vm.data | filter: vm.search | customFilter: vm.selected | pages: vm.currentPage : vm.itemsPerPage">
And finally you can implement a custom filter to achieve what you want, like this:
.filter('customFilter', function() {
return function(items, search) {
if (!search || (Object.keys(JSON.parse(JSON.stringify(search))).length === 0 && search.constructor === Object)) {
return items;
}
var selected = Object.keys(search).map(function(key) {
return search[key]
});
items = items.filter(function(value) {
return selected.indexOf(value.city) != -1;
});
return items;
}
});
Check the complete code
I hope it helps.
Tip: I don't know if you're using these things of ui-bootstrap in your real project, but they're deprecated, as you can see in console:
PaginationController is now deprecated. Use UibPaginationController
instead. pagination is now deprecated. Use uib-pagination instead.

ng-repeat and orderBy a String

I'm getting two items back from my API, one has a startDate and one has an endDate and I was wondering if it's possible to order them by their parameter string?
Data:
[
{
name: "Item 1",
type: "Start Time"
},
{
name: "Item 2",
type: "End Time"
}
]
Something like so:
<li ng-repeat="item in items | orderBy: type='Start Time'">{{ item.name }}</li>
Is is possible using Angular's orderBy filter?
Any help is appreciated.
No need to specify StartTime,
<li ng-repeat="item in items | orderBy: 'type'>{{ item.name }}</li>
Here is the working Application
You only need to specify the key by which you want to order in your orderBy:
orderBy: 'type'
And if you want to reverse the order use -:
orderBy: '-type'

angularJS - How to filter by one item in object only

In this JSFiddle (https://jsfiddle.net/eug0taf9/9/), I select a rating and expect an image to be displayed.
What is happening?
When I select rating 'High', 2 images show up instead of 1 because the filter is catching category 'High' and also description 'High' of an image in category 'Low'.
What do I expect to happen?
On selecting rating "High", I only want the category to be filtered. I don't need it to be filtered by description too.
Any suggestions on how to solve this?
HTML code:
<div ng-app="myApp" ng-controller="myCtrl">
<span>Select a rating</span>
<select ng-model="catselect"
ng-options="category for category in imageCategories"
ng-change="valueSelected(catselect)">
<option value>All</option>
</select>
<!--<p>Select <input ng-model="categories"/></p>-->
<ul class="photosmenu">
<li ng-repeat="image in images | filter : catselect" ng-click="setCurrentImage(image)">
<img ng-src="{{image.image}}" alt="{{image.stars}}" width="300px"/>
</li>
</ul><!-- End of List -->
</div>
Angular Code:
var mod = angular.module("myApp", []);
mod.controller("myCtrl", function($scope){
$scope.images = [
{category: 'High', image: 'img/1.png', description: 'Random Photo', stars: '4/5'},
{category: 'Medium', image: 'img/6.png', description: 'ApplePhoto', stars: '3/5'},
{category: 'Low', image: 'img/13.png', description: 'High Top Photo', stars: '2/5'},
{category: 'None', image: 'img/16.png', description: 'Kilt Photo', stars: '0/5'}];
$scope.currentImage = $scope.images[0];
$scope.imageCategories = ["High", "Medium", "Low", "None"];
$scope.valueSelected = function (value) {
if (value === null) {
$scope.catselect = undefined;
}
};
});
That is because you have a global match filter which will match on all properties, if you want to filter on specific property set your filter object accordingly. i.e
<li ng-repeat="image in images | filter :{category: catselect}"
Demo
or you could also set your ng-model to an object,
<select ng-model="catselect.category"
and do:
<li ng-repeat="image in images | filter :catselect"
Demo
Check out documentation:
string: The string is used for matching against the contents of the array. All strings or objects with string properties in array that match this string will be returned. This also applies to nested object properties. The predicate can be negated by prefixing the string with !.
Object: A pattern object can be used to filter specific properties on objects contained by array. For example {name:"M", phone:"1"} predicate will return an array of items which have property name containing "M" and property phone containing "1". A special property name $ can be used (as in {$:"text"}) to accept a match against any property of the object or its nested object properties. That's equivalent to the simple substring match with a string as described above. The predicate can be negated by prefixing the string with !. For example {name: "!M"} predicate will return an array of items which have property name not containing "M".

Resources