javascript - component - angular grid
ngGrid Multi Column Filtering (1)
Estoy usando el módulo ngGrid para AngularJS para mostrar algunos datos paginados. Quiero poder buscar en varias columnas, sin embargo, utilizando una búsqueda OR.
Digamos que tengo una columna con los siguientes encabezados: Id, Name, Description. Cuando busco, quiero devolver todas las filas donde Id o nombre O descripción contienen el término de búsqueda.
$scope.pagingOptions = {
pageSizes: [20, 50, 100],
pageSize: 20,
totalServerItems: 0,
currentPage: 1
};
$scope.gridOptions =
{
data: ''myData'',
columnDefs: [
{ field: ''id'', displayName: ''Id'' },
{ field: ''name'', displayName: ''Name'' },
{ field: ''description'', displayName: ''Description'' },
{ displayName: ''Actions'', cellTemplate: ''<input type="button" data-ng-click="doSomething(row.entity)" value="Do Something" />''}],
enablePaging: true,
showFooter: true,
showFilter: true,
pagingOptions: $scope.pagingOptions,
filterOptions: {
filterText: "",
useExternalFilter: false
}
};
He intentado usar el cuadro de búsqueda predeterminado, y también el uso de un cuadro de entrada externo vinculado a $ scope.filterText para definir un filtro personalizado como:
$scope.filterUpdated = function () {
$scope.gridOptions.filterOptions.filterText = ''id:'' + $scope.filterText + '';name:'' + $scope.filterText + '';description:'' + $scope.filterText;
};
Sin embargo, esto parece hacer un AND en todas las columnas. ¿Es posible lograr lo que quiero usando el módulo ngGrid?
Gracias por adelantado,
Chris
Sí, es posible hacer un filtro OR, pero después de buscar en el código fuente de ng-grid no puedo ver cómo se puede hacer usando su filterOptions.filterText
. Eso se puede hacer y solo filtrar.
La solución sería utilizar filterOptions.useExternalFilter:true
Tampoco encontré ningún ejemplo de eso, pero después de jugar un poco con eso, obtuve la idea de que el filtro realmente se realiza al volver a crear la gridOptions.data
objetos gridOptions.data
. Ese es el único inconveniente de este filtro .
Así que básicamente tu código se vería como este index.html :
<body ng-controller="MyCtrl">
<strong>Filter Name:</strong> </string><input type="text" ng-model="filterName"/>
</br>
OR
</br>
<strong>Filter Age:</strong> </string><input type="text" ng-model="filterAge"/>
</br>
<button ng-click="activateFilter()">Run Filter</button>
<br/>
<br/>
<div class="gridStyle" ng-grid="gridOptions"></div>
</body>
Y en tu controller.js :
app.controller(''MyCtrl'', function($scope) {
$scope.filterOptions = {
filterText: '''',
useExternalFilter: true
};
$scope.activateFilter = function() {
var name = $scope.filterName || null;
var age = ($scope.filterAge) ? $scope.filterAge.toString() : null;
if (!name && !age) name='''';
$scope.myData = angular.copy($scope.originalDataSet, []);
$scope.myData = $scope.myData.filter( function(item) {
return (item.name.indexOf(name)>-1 || item.age.toString().indexOf(age) > -1);
});
};
$scope.originalDataSet = [{name: "Moroni", age: 50},
{name: "Tiancum", age: 43},
{name: "Jacob", age: 27},
{name: "Nephi", age: 29},
{name: "Enos", age: 34}];
$scope.myData = angular.copy($scope.originalDataSet, []);
$scope.gridOptions = {
data: ''myData'',
filterOptions: $scope.filterOptions
};
});
Eso es solo un filtrado básico (use regex y / o conviértalo a minúsculas para una mejor correspondencia). También tenga en cuenta que si tanto el nombre como la edad están vacíos, establezco el nombre como '''' y luego cada elemento devolverá verdadero dentro del filtro (dando como resultado el retorno del conjunto de datos completo).
Esta opción es mucho más adecuada para el conjunto de datos dinámico ( alimentado por servidor de lectura ), pero funciona igual de bien pero replicando el conjunto de datos original y aplicando los filtros.