Angular Filter based on Multiselect-Dropdown - angularjs

I use nya-bootstrap-select directive (http://nya.io/nya-bootstrap-select/)
for a Multiselect-Dropdown ( Angular 1.5.8 ).
Now I would like to filter a collection based on the selected options.
Example:
https://jsfiddle.net/mrtzdev/2z6xfo5w/18/
<ol id="dynamic-options" class="nya-bs-select" ng-model="model2" multiple >
<li nya-bs-option="(key,value) in companyList" >
<a>{{ value.name}}</a>
</li>
</ol>
Filtered Collection:
<tbody>
<tr ng-repeat="client in clients | filter:{ name: model1.name, company: { name: model2.name } } ">
<td>{{$index + 1}}</td>
<td><em>{{client.name}}</em>
</td>
<td>{{client.designation}}</td>
<td>{{client.company.name}}</td>
</tr>
</tbody>
This obviously does not work for the multiselect. How can use a custom filter, to filter on multi-selected options ?

I modified your fiddle and make it work. This filter is not good in dynamic handling but it will allow you to filter your data by the exact filter attribute name.
View
<tr ng-repeat="client in clients | filter:{ name: model1.name} | inArrayExact : { myArray: model2, searchKey: 'name', filterKey: 'company' }">
<td>{{$index + 1}}</td>
<td><em>{{client.name}}</em>
</td>
<td>{{client.designation}}</td>
<td>{{client.company.name}}</td>
</tr>
AngularJS custom filter
App.filter('inArrayExact', function($filter){
return function(list, arrayFilter, element){
if((angular.isArray(arrayFilter.myArray) && arrayFilter.myArray.lenght > 0) && || angular.isObject(arrayFilter.myArray)){
var itemsFound = {};
angular.forEach(list, function (listItem, key) {
angular.forEach(arrayFilter.myArray, function (filterItem) {
if (angular.isDefined(filterItem[arrayFilter.searchKey])
&& angular.isDefined(listItem[arrayFilter.filterKey])
&& angular.isDefined(listItem[arrayFilter.filterKey][arrayFilter.searchKey])) {
if (angular.isUndefined(itemsFound[key])
&& listItem[arrayFilter.filterKey][arrayFilter.searchKey] == filterItem[arrayFilter.searchKey]) {
itemsFound[key] = listItem;
}
}
});
});
return itemsFound;
} else {
return list;
}
};
});

model2 is an array objects not a string, you need to create a custom filter where you pass model2 and loop over the objects and check the name.
you can check this link on how to build custom filters
https://toddmotto.com/everything-about-custom-filters-in-angular-js/

Related

how to filter in with a comparition between 2 fields

I want filter servers on the condition for those records with serverState and the initialstate in them are not equal.
{{servers | filter : serverState != initialState}}
You can create your own custom filter which has logic to filter the server which don't have initial state matching with initalState variable value.
Your Custom filter
myApp.filter('filterServer', function () {
return function (servers,initialState) {
var filteredArray=[];
for (var k = 0; k < servers.length; ++k) {
var server = servers[k];
if (server.state != initialState) filteredArray.push(server);
}
return filteredArray;
};
});
Your HTML
<tr ng-repeat="server in Servers | filterServer : initialState">
<td style="width:50%;fload:left">
<span ng-bind="server.server"></span>
</td>
<td style="width:40%;fload:left">
<span ng-show="server.state==1">State 1</span>
<span ng-show="server.state==2">State 2</span>
</td>
</tr>
For sample please check this link
http://fiddle.jshell.net/zxr0qa1k/5/

In table, get selected row id in array

In table every row assosiated with checkbox and have option to check all row.
I want to get selected rows id of table in array.
Here is plunker code.
HTML:
<table id="datatable-buttons" class="table table-striped table-bordered">
<thead>
<th>
<input type="checkbox" ng-model="selectRowId" ng-click="selectedAll()">
</th>
</thead>
<tbody ng-init="get_product()">
<!--step 6-->
<tr ng-repeat="product in filtered = (pagedItems| filter:search | orderBy : predicate :reverse) | startFrom:currentPage * entryLimit | limitTo:entryLimit | findobj:multipleVlaue | searchFor:searchString"> <!-- searchFor:searchString -->
<td>
<input type="checkbox" ng-model="selctedIds[product.id]" ng-checked="product.deleted">
</td>
</tr>
</tbody>
</table>
Controller:
$scope.selectedAll = function () {
$scope.pagedItems.forEach(function (product) {
if ($scope.selectRowId) {
product.deleted = true;
} else {
product.deleted = false;
}
});
}
If you want something scalable that accommodates things like complex filtering, pagination, etc. then I suggest you write an angular property to each object. So for the checkbox we'd want to toggle this boolean value like so:
<input type="checkbox" ng-model="item.$selected"/>
For your toggle all/none, you'll need to tap a controller function:
$scope.toggleAll = function(bSelect){
itemArray.forEach( function(item){ item.$selected = bSelect; })
}
The reason I suggest prepending your selected value with a $ like $selected is that any HTTP calls you make with the objects, Angular will strip any $property before converting to JSON, just in case your backend has issue.
I'd recommend using a filter to pull the IDs:
<div>{{ itemArray | getSelIds }}</div>
and the filter
.filter( 'geSeltIds', function(){
return function(items){
//if you happen to use lodash
return _.chain(items).filter({$selected:true}).map('id').value()
//manual
ids = []
items.forEach(function(item){
if(item.$selected)
ids.push(item.id)
})
return ids
}
})
This filter is cleaner:
.filter( function (item) {
return item.$selected;
}).map(function (item) { return item.id });

AngularJS - orderBy value when ng-repeat by key, value pair

I have counted the ocurrences of each item in a set of data with countBy function in lodash, and the result is this:
$scope.colors= {
"Orange": 3,
"Blue": 2,
"Pink": 1,
"Red": 1,
"Black": 2,
};
Now I would like to display the data and order it by its value. I've tried with
<div ng-controller="myCtrl" ng-app="myApp">
<ul>
<li ng-repeat="(key,value) in colors | orderBy:value">
{{key}} ({{value}})
</li>
</ul>
</div>
But the orderBy filter doesn't seem to do the trick (see the plunkr here)
Is there any way to do it with the current data form, or is it a better way to structure the data in order to achieve the desired result? Thanks in advance!
As the documentation says, orderBy expects an array as input, not an object. In general, although it's supported, I've never met a use-case where using an object with ng-repeat was a good idea.
Just transform your object into an array:
$scope.colors = [];
angular.forEach(occurrences, function(value, key) {
$scope.colors.push({
color: key,
count: value
});
});
and then use
<li ng-repeat="element in colors | orderBy:'count'">
{{ element.color }} ({{ element.count }})
</li>
See your updated plunkr.
After multiple tries, I found a way to iterate an object and have it ordered by the key.
<div ng-repeat="key1 in keys(obj1) | orderBy: key1">
I would instead use an array like so:
colors = [{color: 'red', value: 1}, {color: 'blue', value: 2}]
Then you can use
ng-repeat="color in colors | orderBy:'value'"
Plunkr
different approach - for
string from JsonConvert.SerializeObject(DataTable), so basically List<Dictionary<string, string>>
Example is combination of few solutions (sorry for no references)
In AngularJs controller:
vm.propertyName = '\u0022Spaced Column Name\u0022';
vm.reverse = true;
vm.sortBy = function (propertyName) {
vm.reverse = (vm.propertyName === '\u0022' + propertyName +'\u0022') ? !vm.reverse : false;
vm.propertyName = '\u0022' + propertyName + '\u0022';
};
vm.Data = JSON.parse(retValue.Data);
for (var i = 0; i < vm.Data.length; i++) {
var obj = {};
angular.forEach(vm.Data[i], function (value, key) {
obj[key] = value;
});
vm.DataArr.push(obj);
}
By ng-if="key != 'Id'" I'm hiding Id column with Guid
And then in html:
<table border="1">
<tr>
<td ng-repeat="(key, value) in vm.Data[0]" ng-if="key != 'Id'">
<button ng-click="vm.sortBy(key)">{{key}}</button>
<span ng-show="vm.propertyName == '\u0022'+key+'\u0022' && !vm.reverse" class="fa fa-arrow-up"></span>
<span ng-show="vm.propertyName == '\u0022'+key+'\u0022' && vm.reverse" class="fa fa-arrow-down"></span>
</td>
</tr>
<tr ng-repeat="row in vm.DataArr |orderBy:vm.propertyName:vm.reverse track by $index" ng-init="rowInd0 = $index">
<td ng-repeat="(key, value) in vm.Data[0]" ng-if="key != 'Id'">
<span>{{row[key]}}</span>
</td>
</tr>
</table>

Sorting array in asc desc

I am new to angularjs here is my code i want to get data from url and also sort it by dynamically by selecting an item from select element but could't get the required result please help me out
Html
<tr ng-repeat="x in names | orderBy: sortBy ">
<td><a ng-href="{{ x.data.url}}">{{x.data.title}}</a>
</td>
<td>{{x.data.score}}</td>
</tr>
Code
$scope.$watch(function () {
return $scope.sortExpression
}, function (newSort) {
$scope.sortBy = 'data.' + $scope.sortExpression
})
$http.get("https://www.reddit.com/r/worldnews/new.json")
.success(function (response) {
$scope.names = response.data.children
})
Fiddle
https://jsfiddle.net/rr6q0umb/1/
Add input for the direction
<label><input type="checkbox" ng-model="direction">Reverse</label>
Add to your orderBy filter the direction value (true for reverse)
<tr ng-repeat="x in names | orderBy:sortBy:direction">

How to remove object from array within ng-repeat with AngularJS?

I am having an array with objects like [{...}, {...}] which I am outputting with ng-repeat. Then I have a delete button with a function to delete it.
Is there a simple way to delete it in AngularJS, perhaps with $index? Or I need to specify an ID on every object as an property?
If you don't apply a filter to reorder or filter your array, you can do this:
<div ng-repeat="item in items" ng-click="delete($index)">{{item}}</div>
And the delete function:
$scope.items = [...];
$scope.delete = function (index) {
$scope.items.splice(index, 1);
}
Another way to do it without filter problems: (ONLY IE9+)
<div ng-repeat="item in items | orderBy: 'id'" ng-click="delete(item)">{{item}}</div>
And the delete function:
$scope.items = [...];
$scope.delete = function (item) {
$scope.items.splice($scope.items.indexOf(item), 1);
}
http://jsfiddle.net/oymo9g2f/2/
Here is another example, using Jade too:
template.jade:
label All Items
ul.list-group
li.list-group-item(ng-repeat="item in items | orderBy: '_id'")
strong {{item.name}}
a.trash(ng-click='deleteItem(item)')
//a.trash is a bootstrap trash icon, but you don't need to use it.
controller.js:
$scope.deleteItem = function (item) {
$scope.items.splice($scope.items.indexOf(item),1);
}
removeWith
comparison for each element in a collection to the given properties object,
returning an array without all elements that have equivalent property values.
$scope.collection = [
{ id: 1, name: 'foo' },
{ id: 1, name: 'bar' },
{ id: 2, name: 'baz' }
]
<tr ng-repeat="obj in collection | removeWith:{ id: 1 }">
{{ obj.name }}
</tr>
<tr ng-repeat="obj in collection | removeWith:{ id: 1, name: 'foo' }">
{{ obj.name }}
</tr>
First try to do it this way, but the listing was not actualized at runtime.
$scope.delete = function (index) {
delete $scope.items[index];
}
Then with the answer given above by Facundo Pedrazzini did work properly for me.
$scope.delete = function (index) {
$scope.items.splice(index, 1);
}
Version: AngularJS v1.6.4
In blade.php
<table style="width:100%;">
<tr ng-repeat="name in planFormData.names track by $index">
<td>
<div class="form-group">
<label>Plan Name<span style="color:red;">*</span> </label>
<input type="text" class="form-control" ng-model="planFormData.names[$index].plan_name" name="plan_name" id="status-name" placeholder="Plan Name" autocomplete="off" required>
</div>
</td>
<td>
<i class="icon-plus" ng-click="addRow($index)" ng-show="$last"></i>
<i class="icon-trash" ng-click="deleteRow($event,name)" ng-show="$index != 0"></i>
</td>
</tr>
</table>
In controller.js
$scope.deleteRow = function($event, name) {
var index = $scope.planFormData.names.indexOf(name);
$scope.planFormData.names.splice(index, 1);
};
In Angular 6, I did similar for Multi Dimensional Array. It's working
RemoveThisTimeSlot(i: number, j: number) {
this.service.formData.ConsultationModelInfo.ConsultationWeekList[i].TimeBlockList.splice(j, 1);
}

Resources