angular ui-用户按下回车键时的网格过滤器
angular ui-grid filter when user presses enter key
我已经实现了 ui-grid,具有服务器端过滤、排序和分页功能。
我使用 gridApi.core.on.filterChanged 来检测筛选器更改以及 $timeout
以等待用户完成输入。使用 $timeout
是个不错的主意,但我只想在 enter
键上过滤网格,但是 filterChanged
事件会监视字段的值,我认为它无法访问按键也没有按键事件来检测 enter
键。
如何在 enter
键上调用 ajax 过滤器?
filterChanged 事件仅告诉您它已更改,它不会过滤单个按键。最好的选择是使用新的自定义过滤器选项实现自定义过滤器模板:http://ui-grid.info/docs/#/tutorial/306_custom_filters,然后直接在您提供的过滤器指令上实现您的逻辑。请注意,为此您需要最新的不稳定版 - 它将在 RC21 或 3.0 中发布,以先到者为准。
已找到解决方案!
正如我之前所说,我正在寻找 "CLEAN" 解决方案,以避免将 headerCellTemplate
添加到所有列并更改我的大量代码。
此解决方案以某种方式基于覆盖 ui-grid 的 cellHeaderTemplate
以使用我的自定义指令作为输入过滤器,并且效果很好。我还可以将不同类型的过滤器添加到我的网格中。
angular
.module('ui.grid')
.run(['$templateCache', function ($templateCache) {
// Override uiGridHeaderCell template to replace "input" field with "grid-filter" directive
$templateCache.put('ui-grid/uiGridHeaderCell',
"<div ng-class=\"{ 'sortable': sortable }\"><div class=\"ui-grid-cell-contents\" col-index=\"renderIndex\"><span>{{ col.displayName CUSTOM_FILTERS }}</span><span ui-grid-visible=\"col.sort.direction\" ng-class=\"{ 'ui-grid-icon-up-dir': col.sort.direction == asc, 'ui-grid-icon-down-dir': col.sort.direction == desc, 'ui-grid-icon-blank': !col.sort.direction }\"> </span></div><div class=\"ui-grid-column-menu-button\" ng-if=\"grid.options.enableColumnMenus && !col.isRowHeader && col.colDef.enableColumnMenu !== false\" ng-click=\"toggleMenu($event)\" ng-class=\"{'ui-grid-column-menu-button-last-col': isLastCol}\"><i class=\"ui-grid-icon-angle-down\"> </i></div><div ng-if=\"filterable\" class=\"ui-grid-filter-container\" ng-repeat=\"colFilter in col.filters\"><grid-filter type=\"{{colFilter.type}}\"></grid-filter><div class=\"ui-grid-filter-button\" ng-click=\"colFilter.term = null\"><i class=\"ui-grid-icon-cancel\" ng-show=\"!!colFilter.term\"> </i><!-- use !! because angular interprets 'f' as false --></div></div></div>"
);
// Add custom templates to use in "grid-filter" directive
$templateCache.put('ui-grid-filters/text',
"<input type=\"text\" class=\"ui-grid-filter-input\" ng-model=\"colFilter.term\" ng-attr-placeholder=\"{{colFilter.placeholder || ''}}\">"
);
$templateCache.put('ui-grid-filters/dropdown',
"<select class=\"ui-grid-filter-input\" ng-model=\"colFilter.term\" ng-options=\"option.text for option in colFilter.dropdownOptions \"><option value=''></option> </select>"
);
$templateCache.put('ui-grid-filters/date',
"<input type='text' class=\"ui-grid-filter-input\" ng-model=\"colFilter.term\" mask=\"1399/99/99\" mask-options=\"{placeholder:' '}\" placeholder='{{colFilter.placeholder}}' />"
);
}])
.directive('gridFilter', ['$templateCache', '$compile', function ($templateCache, $compile) {
return {
restrict: 'AE',
replace: true,
link: function (scope, elem, attrs) {
var type = attrs['type'] || 'text';
var grid = scope.$parent.$parent.grid;
var filter = function () {
// Filtering comes here. We have full access to grid and it's filter terms here.
};
var template = $compile($templateCache.get('ui-grid-filters/' + type))(scope);
elem.replaceWith(template);
elem = template;
elem.keypress(function (e) {
if (e.which == 13) {
filter();
}
});
if (type == 'dropdown') {
elem.change(function (e) {
filter();
})
}
// Handle clear button click action
scope.$watch('$parent.colFilter.term', function (newVal, oldVal) {
if (newVal === null && oldVal !== null) {
filter();
}
});
}
}
}]
);
这是一个示例 gridOptions
对象。
$scope.gridOptions = {
enableFiltering: true,
enableRowSelection: true,
enableGridMenu: true,
paginationPageSizes: [25, 50, 75],
paginationPageSize: 25,
useExternalSorting: true, // Sorting is handled using gridApi.core.on.sortChanged() event
useExternalFiltering: true, // Filtering is handled in custom directive
useExternalPagination: true, // Pagination is handled using gridApi.pagination.on.paginationChanged() event
columnDefs: [
{
field: 'username',
displayName: "Username"
},
{
field: 'status',
displayName: 'Status',
cellTemplate: '<div class="text-center">' +
'<span ng-show="row.entity.status==1">Enabled</span>' +
'<span ng-show="row.entity.status==2">Disabled</span>' +
'</div>',
filter: {
type: 'dropdown',
dropdownOptions: [
{
id: 1,
text: 'Enabled'
},
{
id: 2,
text: 'Disabled'
}
]
}
},
{
field: 'birthDate',
displayName: 'Birth Date',
filters: [
{
type: 'date',
placeholder: 'From'
},
{
type: 'date',
placeholder: 'To'
}
]
},
]
}
ui 网格调用的过滤事件与模态的 watch 调用,但 watch 方法在按键上调用,因此我们可以通过添加指令将按键事件更改为文本框的模糊事件
directive('ngModelOnblur', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elm, attr, ngModelCtrl) {
elm.unbind('input').unbind('keydown').unbind('blur');
elm.bind('change', function () {
scope.$apply(function () {
ngModelCtrl.$setViewValue(elm.val());
});
});
}
};
});
在 uigrid
的 textbox
和 ui 网格中添加指令 filter.api 仅在 textbox
的更改事件或输入键时调用。
我已经实现了 ui-grid,具有服务器端过滤、排序和分页功能。
我使用 gridApi.core.on.filterChanged 来检测筛选器更改以及 $timeout
以等待用户完成输入。使用 $timeout
是个不错的主意,但我只想在 enter
键上过滤网格,但是 filterChanged
事件会监视字段的值,我认为它无法访问按键也没有按键事件来检测 enter
键。
如何在 enter
键上调用 ajax 过滤器?
filterChanged 事件仅告诉您它已更改,它不会过滤单个按键。最好的选择是使用新的自定义过滤器选项实现自定义过滤器模板:http://ui-grid.info/docs/#/tutorial/306_custom_filters,然后直接在您提供的过滤器指令上实现您的逻辑。请注意,为此您需要最新的不稳定版 - 它将在 RC21 或 3.0 中发布,以先到者为准。
已找到解决方案!
正如我之前所说,我正在寻找 "CLEAN" 解决方案,以避免将 headerCellTemplate
添加到所有列并更改我的大量代码。
此解决方案以某种方式基于覆盖 ui-grid 的 cellHeaderTemplate
以使用我的自定义指令作为输入过滤器,并且效果很好。我还可以将不同类型的过滤器添加到我的网格中。
angular
.module('ui.grid')
.run(['$templateCache', function ($templateCache) {
// Override uiGridHeaderCell template to replace "input" field with "grid-filter" directive
$templateCache.put('ui-grid/uiGridHeaderCell',
"<div ng-class=\"{ 'sortable': sortable }\"><div class=\"ui-grid-cell-contents\" col-index=\"renderIndex\"><span>{{ col.displayName CUSTOM_FILTERS }}</span><span ui-grid-visible=\"col.sort.direction\" ng-class=\"{ 'ui-grid-icon-up-dir': col.sort.direction == asc, 'ui-grid-icon-down-dir': col.sort.direction == desc, 'ui-grid-icon-blank': !col.sort.direction }\"> </span></div><div class=\"ui-grid-column-menu-button\" ng-if=\"grid.options.enableColumnMenus && !col.isRowHeader && col.colDef.enableColumnMenu !== false\" ng-click=\"toggleMenu($event)\" ng-class=\"{'ui-grid-column-menu-button-last-col': isLastCol}\"><i class=\"ui-grid-icon-angle-down\"> </i></div><div ng-if=\"filterable\" class=\"ui-grid-filter-container\" ng-repeat=\"colFilter in col.filters\"><grid-filter type=\"{{colFilter.type}}\"></grid-filter><div class=\"ui-grid-filter-button\" ng-click=\"colFilter.term = null\"><i class=\"ui-grid-icon-cancel\" ng-show=\"!!colFilter.term\"> </i><!-- use !! because angular interprets 'f' as false --></div></div></div>"
);
// Add custom templates to use in "grid-filter" directive
$templateCache.put('ui-grid-filters/text',
"<input type=\"text\" class=\"ui-grid-filter-input\" ng-model=\"colFilter.term\" ng-attr-placeholder=\"{{colFilter.placeholder || ''}}\">"
);
$templateCache.put('ui-grid-filters/dropdown',
"<select class=\"ui-grid-filter-input\" ng-model=\"colFilter.term\" ng-options=\"option.text for option in colFilter.dropdownOptions \"><option value=''></option> </select>"
);
$templateCache.put('ui-grid-filters/date',
"<input type='text' class=\"ui-grid-filter-input\" ng-model=\"colFilter.term\" mask=\"1399/99/99\" mask-options=\"{placeholder:' '}\" placeholder='{{colFilter.placeholder}}' />"
);
}])
.directive('gridFilter', ['$templateCache', '$compile', function ($templateCache, $compile) {
return {
restrict: 'AE',
replace: true,
link: function (scope, elem, attrs) {
var type = attrs['type'] || 'text';
var grid = scope.$parent.$parent.grid;
var filter = function () {
// Filtering comes here. We have full access to grid and it's filter terms here.
};
var template = $compile($templateCache.get('ui-grid-filters/' + type))(scope);
elem.replaceWith(template);
elem = template;
elem.keypress(function (e) {
if (e.which == 13) {
filter();
}
});
if (type == 'dropdown') {
elem.change(function (e) {
filter();
})
}
// Handle clear button click action
scope.$watch('$parent.colFilter.term', function (newVal, oldVal) {
if (newVal === null && oldVal !== null) {
filter();
}
});
}
}
}]
);
这是一个示例 gridOptions
对象。
$scope.gridOptions = {
enableFiltering: true,
enableRowSelection: true,
enableGridMenu: true,
paginationPageSizes: [25, 50, 75],
paginationPageSize: 25,
useExternalSorting: true, // Sorting is handled using gridApi.core.on.sortChanged() event
useExternalFiltering: true, // Filtering is handled in custom directive
useExternalPagination: true, // Pagination is handled using gridApi.pagination.on.paginationChanged() event
columnDefs: [
{
field: 'username',
displayName: "Username"
},
{
field: 'status',
displayName: 'Status',
cellTemplate: '<div class="text-center">' +
'<span ng-show="row.entity.status==1">Enabled</span>' +
'<span ng-show="row.entity.status==2">Disabled</span>' +
'</div>',
filter: {
type: 'dropdown',
dropdownOptions: [
{
id: 1,
text: 'Enabled'
},
{
id: 2,
text: 'Disabled'
}
]
}
},
{
field: 'birthDate',
displayName: 'Birth Date',
filters: [
{
type: 'date',
placeholder: 'From'
},
{
type: 'date',
placeholder: 'To'
}
]
},
]
}
ui 网格调用的过滤事件与模态的 watch 调用,但 watch 方法在按键上调用,因此我们可以通过添加指令将按键事件更改为文本框的模糊事件
directive('ngModelOnblur', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, elm, attr, ngModelCtrl) {
elm.unbind('input').unbind('keydown').unbind('blur');
elm.bind('change', function () {
scope.$apply(function () {
ngModelCtrl.$setViewValue(elm.val());
});
});
}
};
});
在 uigrid
的 textbox
和 ui 网格中添加指令 filter.api 仅在 textbox
的更改事件或输入键时调用。