2012-03-09 49 views
6

使用Ext.ux.grid.FiltersFeature編程應用網格過濾器,我有遠程過濾器,我試圖寫一個函數,在表格列申請日期過濾器編程方式(而不是點擊過濾器下拉菜單在列標題中)。我第一次運行這個函數時,網格商店在沒有過濾器的情況下重新加載。當我第二次(以及之後每次)運行該功能時,它都能正常工作,商店會使用過濾器重新加載。這裏是我有功能的要點:從功能

// a filter object for testing 
aFilter = {type: 'date', field: 'a_date_field', comparison: 'gt', value: '2012-03-08 00:00:00'} 

var grid = Ext.create('Ext.grid.Panel', { 
    store: store, 
    features: [{ 
     ftype: 'filters', 
    }], 
    columns[{ 
     header: 'ID', 
     dataIndex: 'id', 
     itemId: 'id',    
     width: 40, 
    }, { 
     xtype: 'datecolumn', 
     header: 'Date', 
     dataIndex: 'a_date_field', 
     itemId: 'a_date_field', 
     width: 75, 
     format:'j-M-Y', 
     filterable: true 
    }], 
    listeners: { 
     'afterrender': function() { 

      // Need to create the filters as soon as the grid renders 
      // rather than waiting for the user to click on the header 
      grid.filters.createFilters(); 
     } 
    }, 
    bbar: [{ 
     text: 'Do a filter', 
     handler: function() { 

      // get the filter that is attached to the grid 
      var gridFilter = grid.filters.getFilter(aFilter.field); 

      // have to do this to create a menu for this filter 
      gridFilter.init({dataIndex: aFilter.field, type: aFilter.type, active: true}); 

      // if this column is a date filter column 
      if (gridFilter.type == 'date') { 
       var dateValue = Ext.Date.parse(aFilter.value, 'Y-m-d H:i:s'); 
       if (filter.comparison == 'gt') { 
        gridFilter.setValue({after: dateValue}); 
       } else { 
        gridFilter.setValue({before: dateValue}); 
       } 
      } 
     } 
    } 
}); 

我還發現,此功能在第一時間,如果我任何網格標題菜單上單擊之前,我運行的功能。

我一直在試圖找出在第一次嘗試失敗後或者點擊任意網格標頭確實能夠工作的情況下,使濾鏡工作的網格發生了哪些更改。但我沒有添加任何東西似乎可以解決它,所以它會第一次運行。有沒有人成功實現了這個?

+0

您是否嘗試過在'FiltersFeature'對象上調用'createFilter()'? – 2012-03-26 23:03:22

回答

9

我有解決方法:

bbar: [{ 
    text: 'Do a filter', 
    handler: function() { 
     var grid = this.up('grid'); 
     var dateValue = Ext.Date.parse(aFilter.value, 'Y-m-d H:i:s'); 
     var value = aFilter.comparison == 'gt' ? {after: dateValue} : {before: dateValue}; 

     var gridFilter = grid.filters.getFilter(aFilter.field); 

     if (!gridFilter) { 
      gridFilter = grid.filters.addFilter({ 
       active: true, 
       type: aFilter.type, 
       dataIndex: aFilter.dataIndex, 
      }); 

      gridFilter.menu.show(); 
      gridFilter.setValue(value); 
      gridFilter.menu.hide(); 
     } else { 
      gridFilter.setActive(true); 
     } 

     Ext.Function.defer(function(){ 
      gridFilter = grid.filters.getFilter(aFilter.field); 
      gridFilter.setValue(value); 
     }, 10); 
    } 
}] 

正如你可以看到我實際應用過濾器的2倍。

+1

謝謝Lolo!這很好。 – Geronimo 2012-03-09 17:01:19

+0

哇@Lolo你是如何到達應用過濾器兩次解決方案的?是否存在針對它的錯誤? – dbrin 2012-03-09 21:52:03

+0

@DmitryB在第二次點擊按鈕後,我來到了它的工作點。所以下一個顯而易見的步驟就是一次嘗試。我不知道這是否是一個錯誤,可能是。設置該值會導致訪問菜單,因此必須進行渲染。最後,在我看來,這第一個'setValue'調用(在if中)是不必要的 – Krzysztof 2012-03-10 07:45:38

1

這裏的東西,可能是值得探討。看來,過濾器插件正在偵聽menucreate事件來初始化過濾器。我不知道是否菜單創建事件被推遲到必要的,因此過濾器不會被初始化?

/** 
* @private Handle creation of the grid's header menu. Initializes the filters and listens 
* for the menu being shown. 
*/ 
onMenuCreate: function(headerCt, menu) { 
    var me = this; 
    me.createFilters(); //<------ 
    menu.on('beforeshow', me.onMenuBeforeShow, me); 
}, 
+0

感謝德米特里,我曾嘗試手動運行此操作,但我似乎沒有做到這一點。我也收到了在此之前觸發的beforeshow事件,但沒有運氣。這是在菜單上的竊聽,但物理顯示和隱藏它,洛洛建議處理它。 – Geronimo 2012-03-09 17:21:35

0

你想申請網格過濾器或可能是store.filter()功能會適合你更好?在這種情況下,只需過濾商店,網格將顯示過濾的記錄。

+0

應用此過濾器後,用戶將繼續以其他方式過濾網格,因此我需要將網格頭與過濾器保持同步。 – Geronimo 2012-03-09 17:24:09

0

我發現了另一種方式來實現這一點。看起來,網格要素只在網格渲染後綁定到網格。這意味着過濾器的任何設置在渲染網格之後纔會生效。商店的初始加載似乎在網格呈現之前啓動。

我用不包含數據的存儲代理創建我的商店解決我的問題。

me.store = Ext.create('Ext.data.Store', { 
    model: 'SummaryData', 
    data: [], 
    proxy: { 
     type: 'memory', 
     reader: 'array' 
    }, 
    remoteSort: true, 
    remoteFilter: true 
}); 

再成立一家afterrender處理程序在網格中正確的代理捅並啓動店裏的負載。

afterrender: function() { 
    var me = this; 

    me.store.setProxy({ 
     type: 'ajax', 
     url : '/print_unallocated/change_site__data', 
     reader: { 
      type: 'json', 
      root: 'rows' 
     }, 
     listeners: { 
      exception: function (proxy, response) { 
       Max.reportException(response); 
      } 
     } 
    }); 

    me.filters.createFilters(); 
    me.store.load(); 
}, 
6

作爲一個更新,我擴展了這個功能,並修改了它與ExtJS的工作4.1.1

這裏是設置網格功能的示例動態過濾器(無需用戶點擊的菜單項)。此後,經過濾項將在網格中列標題菜單的用戶可見,如果他點擊他們和手動設置。

「網格」參數是一個您想要過濾的網格,其格式爲FiltersFeature。另一個參數是一組「過濾器」對象(我將在下面顯示一個示例),該函數只是將所有傳遞的「過濾器」對象應用於網格。

doGridFilter: function(grid, filters) { 

    // for each filter object in the array 
    Ext.each(filters, function(filter) { 
     var gridFilter = grid.filters.getFilter(filter.field); 

     gridFilter.setActive(true); 
     switch(filter.data.type) { 

      case 'date': 
       var dateValue = Ext.Date.parse(filter.data.value, 'm/d/Y'), 
        value; 

       switch (filter.data.comparison) { 

        case 'gt' : 
         value = {after: dateValue}; 
         break; 
        case 'lt' : 
         value = {before: dateValue}; 
         break; 
        case 'eq' : 
         value = {on: dateValue}; 
         break; 
       } 
       gridFilter = log.filters.getFilter(filter.field); 
       gridFilter.setValue(value); 
       gridFilter.setActive(true); 
       break; 

      case 'numeric': 
       var value; 

       switch (filter.data.comparison) { 

        case 'gt' : 
         value = {gt: filter.data.value}; 
         break; 
        case 'lt' : 
         value = {lt: filter.data.value}; 
         break; 
        case 'eq' : 
         value = {eq: filter.data.value}; 
         break; 
       } 
       gridFilter = log.filters.getFilter(filter.field); 
       gridFilter.setValue(value); 
       gridFilter.setActive(true); 
       break; 

      case 'list': 
       gridFilter = log.filters.getFilter(filter.field); 
       gridFilter.menu.setSelected(gridFilter.menu.selected, false); 
       gridFilter.menu.setSelected(filter.data.value.split(','), true); 
       break; 

      default : 
       gridFilter = log.filters.getFilter(filter.field); 
       gridFilter.setValue(filter.data.value); 
       break; 
     } 
    }); 
} 

下面是一個「過濾器」對象數組的示例。

// an example of a "filters" argument 
[{ 
    field: 'some_list_column_data_index', 
    data: { 
     type: 'list', 
     value: 'item1,item2,item3,item4,item5,item6,item7' 
    } 
}, { 
    field: 'some_date_column_data_index', 
    data: { 
     type: 'date', 
     comparison: 'gt', 
     value: '07/07/2007' 
    } 
}] 

一個警告,您需要在使用此功能前手動「創建」過濾器。通常FiltersFeature網格過濾器在用戶第一次點擊其中一個時「創建」,如果用戶只是想應用其中一個預定義的過濾器,則不會發生這種情況。

通過在gridpanel中包含這個afterrender監聽器,可以很容易地進行處理。

listeners: { 

    // must create the filters after grid is rendered 
    afterrender: function(grid) { 
     grid.filters.createFilters(); 
    } 
} 
+0

我正在使用4.1和4.2以下返回錯誤 「filter.data.value.split(',')//不是函數」 - filter.data.value似乎工作得很好 – MarkyRoden 2013-04-01 00:40:23

3

只需添加

filter: true 

到網格列的描述是這樣的:

me.columns = [ 
     {header:"Name", dataIndex:"name", editor:"textfield", filter: true}, 
    ]; 

,如果你想獲得的第一次嘗試後,過濾器的工作,第一個實例創建。

0

在源代碼中,您可以看到與此相關的評論。

// Call getMenu() to ensure the menu is created, and so, also are the filters. We cannot call 
// createFilters() withouth having a menu because it will cause in a recursion to applyState() 
// that ends up to clear all the filter values. This is likely to happen when we reorder a column 
// and then add a new filter before the menu is recreated. 
me.view.headerCt.getMenu(); 

您可以在應用過濾器之前測試菜單是否已創建。如果沒有,請自己動手。

if(!grid.getView().headerCt.menu){ 
    grid.getView().headerCt.getMenu(); 
}