How to have select filter in ngtable?
Asked Answered
E

3

0

I am trying to have a select filter in ngtable. I followed this example but looks like if the select item has a space (eg: Not Installed or Not Running), then it does not work (filter). I am putting up a plunker for help.

There are couple of things I need help with

  1. Select does not work with space in the select item.
  2. Need exact filter match. Eg: Running select should only show Running and not Not Running.
  3. Also in ngtable example when user clicks on the select it gives an extra blank entry which is removed once user selects and clicks the select filter again.
  4. Auto width of ngtable w.r.t it's data.

Updated code

	var app = angular.module('main', ['ngTable'])
	.controller('DemoCtrl', function($scope, $filter, ngTableParams, $log) {
		$scope.tableData = [{"host":"UST490","org":"00ABHI","status":"images/icon/not_installed.png","selectId":"notInstalled","name":"Not Installed"},{"host":"UST4205","org":"00ABHI","status":"images/icon/not_installed.png","selectId":"notInstalled","name":"Not Installed"},{"host":"UST4089","org":"00ABHI","status":"images/icon/not_installed.png","selectId":"notInstalled","name":"Not Installed"},{"host":"UST4492","org":"00ABHI","status":"images/icon/not_installed.png","selectId":"notInstalled","name":"Not Installed"},{"host":"Bhan-1","org":"00ABHI","status":"images/icon/not_installed.png","selectId":"notInstalled","name":"Not Installed"},{"host":"UST1102","org":"00ABHI","status":"images/icon/x_mark-red.png","selectId":"notRunning","name":"Not Running"},{"host":"UST5202","org":"00ABHI","status":"images/icon/tick.png","selectId":"running","name":"Running"}];
		
		$scope.tableParams = new ngTableParams({
			page: 1, // show first page
			count: 10 // count per page
		}, {
			total: $scope.tableData.length, // length of data
			getData: function($defer, params) {
				var filterData = params.filter() ? $filter('filter')($scope.tableData, params.filter()) : $scope.tableData;
				var orderedData = params.sorting() ? $filter('orderBy')(filterData, params.orderBy()) : filterData;
				var table_data = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count());
				params.total(orderedData.length);
				$defer.resolve(table_data);
			}
		});
		
		//Took help from http://ng-table.com/#/demo/3-2
		/*var inArray = Array.prototype.indexOf ?
			function(val, arr) {
				var temp = arr.indexOf(val);
				return temp;
			} :
			function(val, arr) {
				var i = arr.length;
				while (i--) {
					if (arr[i] === val) return i;
				}
				return -1
			};*/
		$scope.filterAgentStatus = function(column) {
			var def = $q.defer(),
				arr = [],
				filterAgentStatus = [];
			angular.forEach($scope.tableData, function(item) {
				//if (inArray(item.name, arr) === -1) {
					//arr.push(item.name);
                if (jQuery.inArray(item.selectId, arr) === -1) {
                    arr.push(item.selectId);
					filterAgentStatus.push({
						'id': item.selectId,
						'title': item.name
					});
				}
			});
			def.resolve(filterAgentStatus);
			return def;
		};
	});
<link href="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.3.3/ng-table.min.css" rel="stylesheet"/>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-table/0.3.3/ng-table.min.js"></script>

<body ng-app="main" ng-controller="DemoCtrl">

  <table ng-table="tableParams" show-filter="true" class="table agentStatusTable text-center">

<tr ng-repeat="item in $data" height="10px" class="animate" ng-animate="{enter: 'animate-enter', leave: 'animate-leave'}">
  <td data-title="'Agent Name'" class="text-center" header-class="text-center" width="60px" filter="{ 'host': 'text' }" sortable="'host'">{{ item.host }}</td>
  <td data-title="'Org Id'" class="text-center" header-class="text-center" width="40px" filter="{ 'org': 'text' }" sortable="'org'">{{item.org}}</td>
  <td data-title="'Status'" class="text-center" header-class="text-center" width="40px" filter="{ 'name': 'select' }" sortable="'status'" filter-data="filterAgentStatus($column)"><img ng-src="{{ item.status }}" /></td>
</tr>
  </table>

</body>
Screenshot Below enter image description here
Erminia answered 13/7, 2015 at 12:19 Comment(4)
You say "but looks like if the select item has a space, then it does not work (filter)". What do you mean by that. Have in mind that in javascript space can have different meaning depending on context. Inside an boolean expression ' ' equals undefined equals falseAleman
@cleftheris: In my example "status" select filter only works for "NotInstalled" since it does not a space, but if I give "Not Installed" (which is what I need), it does not filter data, also when I select "Running" it also shows "NotRunning".Erminia
@cleftheris: Need exact match for filters as currently "Running" returns both "Running" and "Not Running". I have made some progress on matching items which have space in it and updated my code aboveErminia
the plunker has no filters and there is no clear solution to the 'exact match' problemGebhart
V
1
  1. Need exact filter match

ng-table doesn't actually apply the filters the data - it's only responsible for collecting the filter values from the user.

In your getData function you've configured ng-table with, you are using the angular $filter service to apply the filter. It's this service that is responsible for doing the actual filtering. Therefore if you want an exact match behaviour you will need to use something other than $filter.

  1. ...extra blank entry which is removed once user selects and clicks the select filter again

UPDATE: I have edited my previous answer.

I've fixed this particular issue with ng-table. Here's a conversation about the problem: https://github.com/esvit/ng-table/pull/654#issuecomment-127095189

The commit for the fix: 1ee441

  1. Auto width of ngtable w.r.t it's data.

Column widths for the rendered html table are controlled using css. ng-table does not add anything specific. You should create your own style rules to change the widths. Tip: you can also use colgroup in the html markup and assign a specific width to each <col> tag

Vergos answered 15/7, 2015 at 8:41 Comment(1)
Actually the 3rd parameter to $filter's 'filter' filter can be used to compare using angular.equals() which should give you the exact matches you're looking for. Just pass true for the 3rd parameter.Vaivode
G
0

if Okonomy is saying that you could just do the following

filter="{ 'name': 'select' : true }"

<td data-title="'Status'" class="text-center" header-class="text-center" width="40px" filter="{ 'name': 'select' : true }" sortable="'status'" filter-data="filterAgentStatus($column)"><img ng-src="{{ item.status }}" /></td>

i did not find this to be true. You would need to go into the .js file controlling that page and do something more like the below.

var newStudies = $filter('filter')(controller.TableData, params.filter(), true);

But this forces all filters in the table to exact match (and therefore your table would be empty). So you have to make a custom filter. There are examples of custom attributes here in the below link. Not great examples, but it is an example: custom filter example for ng-table

Gebhart answered 19/6, 2017 at 20:24 Comment(0)
R
0
  • In order for filterAgentStatus to run, you have to change 'select' to 'select-multiple'. (You probably can override the default template of 'select-multiple' in order to have single select at 'select-multiple'):

<td data-title="'Status'" class="text-center" header-class="text-center" width="40px" filter="{ 'name': 'select-multiple' }" sortable="'status'" filter-data="filterAgentStatus($column)"><img ng-src="{{ item.status }}" /></td>

Note: I think you better pass item to filterAgentStatus, instead of $column: filterAgentStatus(item).

Relegate answered 21/12, 2017 at 12:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.