GridPanel 为列提供“仅显示空白” 的支持
(function () { // ============================================================ // 安装函数 // // 使用: // // installBlankFilter(Ext.getCmp('gcDay')); // // 其它 Grid: // // installBlankFilter(Ext.getCmp('其它GridID')); // // ============================================================ function installBlankFilter(grid) { if (!grid) { return; } var view = grid.getView(); if (!view) { return; } var headerCt = view.headerCt; if (!headerCt) { return; } var menu = headerCt.getMenu(); if (!menu) { return; } // ======================================================== // 防止同一个 Grid 重复安装 // ======================================================== if (grid.__blankFilterInstalled) { return; } grid.__blankFilterInstalled = true; // ======================================================== // 当前菜单正在操作的列 // ======================================================== var currentColumn = null; // ======================================================== // FilterHeader 高亮颜色 // ======================================================== var BLANK_FILTER_COLOR = '#ffe6e6'; // ======================================================== // 保存“仅显示空白”的状态 // // 不依赖 Store Filters。 // // ======================================================== var blankFilterState = {}; // ======================================================== // 防止恢复 Filter 时递归触发 filterchange // ======================================================== var restoringBlankFilters = false; // ======================================================== // 防止 clearFilter 包装函数递归 // ======================================================== var clearingAllFilters = false; // ======================================================== // 获取当前 Grid 中的 FilterHeader TextField // // 查询范围限定为当前 Grid。 // ======================================================== function getFilterHeaderFields() { return Ext.ComponentQuery.query( 'textfield', grid ); } // ======================================================== // 获取当前 Grid 所有 Column // ======================================================== function getColumns() { var columns = []; headerCt.items.each( function (column) { if ( column && column.dataIndex ) { columns.push( column ); } } ); return columns; } // ======================================================== // 根据 dataIndex 找 FilterHeader TextField // ======================================================== function getFilterHeaderField(dataIndex) { var fields = getFilterHeaderFields(); if ( !fields || !fields.length ) { return null; } var columns = getColumns(); var columnIndex = -1; for ( var i = 0; i < columns.length; i++ ) { if ( columns[i].dataIndex === dataIndex ) { columnIndex = i; break; } } if (columnIndex < 0) { return null; } return fields[columnIndex] || null; } // ======================================================== // 设置 FilterHeader 背景色 // ======================================================== function setFilterHeaderColor( dataIndex, enabled ) { var field = getFilterHeaderField( dataIndex ); if (!field) { return; } if (enabled) { field.setFieldStyle({ 'background-color': BLANK_FILTER_COLOR, 'background-image': 'none' }); } else { field.setFieldStyle({ 'background-color': '', 'background-image': '' }); } } // ======================================================== // 获取空白 Filter ID // ======================================================== function getFilterId(dataIndex) { return ( '__blank_filter_' + dataIndex ); } // ======================================================== // 判断 Boolean 字段 // ======================================================== function isBooleanField(dataIndex) { var store = grid.getStore(); if (!store) { return false; } var model = store.getModel(); if (!model) { return false; } var field = model.getField( dataIndex ); return ( field && field.type === 'boolean' ); } // ======================================================== // 创建空白 Filter // ======================================================== function createBlankFilter(dataIndex) { return new Ext.util.Filter({ id: getFilterId( dataIndex ), filterFn: function (record) { var value = record.get( dataIndex ); return ( value === null || typeof value === 'undefined' || value === '' || ( typeof value === 'string' && Ext.String.trim( value ) === '' ) ); } }); } // ======================================================== // 恢复所有“仅显示空白” Filter // ======================================================== function restoreBlankFilters() { if (restoringBlankFilters) { return; } if (clearingAllFilters) { return; } var store = grid.getStore(); if (!store) { return; } restoringBlankFilters = true; try { Ext.Object.each( blankFilterState, function ( dataIndex, enabled ) { if (!enabled) { return; } var filterId = getFilterId( dataIndex ); var existingFilter = store.getFilters() .get( filterId ); if (existingFilter) { return; } store.addFilter( createBlankFilter( dataIndex ) ); } ); } finally { restoringBlankFilters = false; } } // ======================================================== // 清除所有“仅显示空白” // // 这是给 clearFilter() 使用的。 // ======================================================== function clearAllBlankFilters() { var store = grid.getStore(); if (!store) { return; } clearingAllFilters = true; try { // ----------------------------------------------- // 清除状态 // ----------------------------------------------- Ext.Object.each( blankFilterState, function ( dataIndex ) { setFilterHeaderColor( dataIndex, false ); } ); blankFilterState = {}; // ----------------------------------------------- // 删除所有我们自己的 Filter // ----------------------------------------------- var filters = store.getFilters(); var removeList = []; filters.each( function (filter) { if ( filter && filter.id && String( filter.id ).indexOf( '__blank_filter_' ) === 0 ) { removeList.push( filter ); } } ); Ext.Array.each( removeList, function (filter) { filters.remove( filter ); } ); } finally { clearingAllFilters = false; } } // ======================================================== // ★ 包装 Ext.NET 的 clearFilter() // // 原来的: // // grid.filterHeader.clearFilter() // // 现在变成: // // 先清除我们自己的“仅显示空白” // 再执行 Ext.NET 原来的 clearFilter() // // ======================================================== if ( grid.filterHeader && grid.filterHeader.clearFilter && !grid.filterHeader.__blankClearFilterWrapped ) { var originalClearFilter = grid.filterHeader.clearFilter; grid.filterHeader.clearFilter = function () { // 清除“仅显示空白” clearAllBlankFilters(); // 再执行 Ext.NET 原来的 clearFilter return originalClearFilter.apply( this, arguments ); }; grid.filterHeader.__blankClearFilterWrapped = true; } // ======================================================== // 监听 Store Filter 改变 // // 当用户: // // 1. 输入“店铺” // 2. 清空“店铺” // 3. 修改其它列筛选 // // 都会经过这里。 // // ======================================================== var store = grid.getStore(); if (store) { store.on( 'filterchange', function () { if ( restoringBlankFilters || clearingAllFilters ) { return; } Ext.defer( function () { restoreBlankFilters(); }, 10 ); } ); } // ======================================================== // 创建菜单分隔线 // ======================================================== var blankFilterSeparator = menu.add('-'); // ======================================================== // 创建“仅显示空白” // ======================================================== var blankFilterItem = menu.add({ itemId: '__blank_filter_checkbox__', text: '仅显示空白', xtype: 'menucheckitem', checked: false, // ================================================== // Checkbox 点击 // ================================================== handler: function (item) { var column = currentColumn || menu.activeHeader; if ( !column || !column.dataIndex ) { return; } var dataIndex = column.dataIndex; var store = grid.getStore(); var filterId = getFilterId( dataIndex ); // ========================================== // 勾选 // ========================================== if (item.checked) { // 记录状态 blankFilterState[ dataIndex ] = true; // 删除旧 Filter var oldFilter = store.getFilters() .get( filterId ); if (oldFilter) { store.getFilters() .remove( oldFilter ); } // 添加 Filter store.addFilter( createBlankFilter( dataIndex ) ); // 输入框变色 setFilterHeaderColor( dataIndex, true ); } // ========================================== // 取消勾选 // ========================================== else { delete blankFilterState[ dataIndex ]; var filter = store.getFilters() .get( filterId ); if (filter) { store.getFilters() .remove( filter ); } // 恢复输入框 setFilterHeaderColor( dataIndex, false ); } menu.hide(); } }); // ======================================================== // 打开列菜单时同步状态 // ======================================================== menu.on( 'beforeshow', function (menu) { currentColumn = menu.activeHeader; if ( !currentColumn || !currentColumn.dataIndex ) { blankFilterSeparator.hide(); blankFilterItem.hide(); return; } var dataIndex = currentColumn.dataIndex; // Boolean 字段不显示 if ( isBooleanField( dataIndex ) ) { blankFilterSeparator.hide(); blankFilterItem.hide(); return; } blankFilterSeparator.show(); blankFilterItem.show(); // 从独立状态读取 var checked = !!blankFilterState[ dataIndex ]; // 同步 Checkbox blankFilterItem.setChecked( checked, true ); // 同步背景色 setFilterHeaderColor( dataIndex, checked ); } ); // ======================================================== // 初始化已有 Filter // ======================================================== Ext.defer( function () { var store = grid.getStore(); if (!store) { return; } var columns = getColumns(); Ext.Array.each( columns, function (column) { if ( !column || !column.dataIndex ) { return; } var dataIndex = column.dataIndex; // Boolean 跳过 if ( isBooleanField( dataIndex ) ) { return; } var filterId = getFilterId( dataIndex ); var filter = store.getFilters() .get( filterId ); if (filter) { blankFilterState[ dataIndex ] = true; setFilterHeaderColor( dataIndex, true ); } } ); restoreBlankFilters(); }, 100 ); } // ============================================================ // 对外暴露 // ============================================================ window.installBlankFilter = installBlankFilter; // ============================================================ // 安装到指定 Grid // ============================================================ installBlankFilter( Ext.getCmp('gcid') ); })();
PS: 如果想要筛选显示某列 有值的数据行,则只需要在筛选处 输入:!= 即可
浙公网安备 33010602011771号