Accessing column filter from outside the grid (save, set, remove)

Hi,

Is there a way to access the filters from outside the grid.
I explain : 

I want to get/retrieve what the user had choosen to filter (ex : checkbox filter 'yes' on one column / or begin with 'toto') for one column.
I want to be able to save : Column / filter -> [yes]
I want to be able to re-apply on loading or when I want : a specific filtering on a column with code/programmation (ex here : column -> filter checkbox -> yes -> launch the filtering).

Is there a way to do that for all the column ? 
(Foreach column -> retrieve the filters currently applied -> save them to be able to re-apply them later in some view)

Thank you !

Jonathan

15 Replies

MS Manivel Sellamuthu Syncfusion Team January 12, 2021 01:55 PM UTC

Hi Jonathan, 

Greetings from Syncfusion support. 

You can access the grid filters externally. You can use getColumns method of  the Grid for your requirement. This method will return the grid columns and you can access the filterType of each column. 
Please refer the below code example or sample for more information. 

<template> 
  <div id="app"> 
    <ejs-button :isPrimary="true" v-on:click.native="btnClick" 
      >Get the columns</ejs-button 
    > 
 
    <ejs-grid 
      ref="grid" 
      :dataSource="data" 
      :allowPaging="true" 
      :allowFiltering="true" 
      :filterSettings="filterSettings" 
    > 
      <e-columns> 
        <e-column 
        . . . 
      </e-columns> 
    </ejs-grid> 
  </div> 
</template> 
 
<script> 
export default { 
  name: "App", 
  data() { 
    return { 
      data: orderData, 
      filterSettings: { type"Menu" }, 
      filter: { 
        type"CheckBox", 
      }, 
    }; 
  }, 
  methods: { 
    btnClick: function () { 
      var grid = this.$refs.grid.ej2Instances; 
// here we can get the columns of  the Grid and you can perform your operation here 
      console.log(grid.getColumns()); 
    }, 
  }, 
  provide: { 
    grid: [PageFilter], 
  }, 
}; 
</script> 



Please let us know, if you need further assistance. 

Regards, 
Manivel 



JO Jonathan January 12, 2021 02:33 PM UTC

Thank you for your answer but this is not exactly what I need.

With getColumns I can get the filterType.

How I get the "values" choosen by filter ?
Ex for you sample : the first column is a filter chekbox. If the user use it to filter with selection [10248, 10249]

1. How I get the filter selection [10248, 10249] from external ?
2. How I can re-use it automatically from external (apply the choice [10248, 10249] to the checkbox selector of the first column AND apply the filter.

Thanks,

Jonathan



MS Manivel Sellamuthu Syncfusion Team January 13, 2021 08:54 AM UTC

Hi Jonathan, 

Thanks for your update. 

We suspect that you want to maintain the filter values and apply them automatically. You can use persistence for your requirement. Which will store the grid settings in the local storage and applies then when the grid is rendered again. Please refer the below code example and sample for more information. 

<ejs-grid 
      ref="grid" 
      :dataSource="data" 
      :allowPaging="true" 
      :enablePersistence="true" 
      :allowFiltering="true" 
      :filterSettings="filterSettings" 
    > 



Please let us know, if you need further assistance. 

Regards, 
Manivel 



JO Jonathan January 13, 2021 10:29 AM UTC

Nearly that.

I want to "save" configurations : multiple configurations to create some view.
So if I enable persistence : it's only save the last state.

BUT,

In the link you gave me I see I have 2 solutions : 

1. full persistence model
You speak about : 

//get the Grid model.
let value = window.localStorage.getItem('gridGrid'); //"gridGrid" is component name + component id.
let model = JSON.parse(model);

Can I use this to save myself multiple config of the same grid ? (gridGrid_v1, _v2 etc.)
And how to re-apply the model retrieved ?
let model = Json.parse(model);
And so .... ???


2. Filter details

In the same page :
actionHandler: function (){
        this.$refs.grid.ej2Instances.query.addParams('$filter', 'EmployeeID eq 1');
    }

Is there a way to have the list of params for all the columns (getparams ?)
Is there a documentation for the addParams with more details ?

3. OR more simple question 

How to get current filter used for re-using them with : https://ej2.syncfusion.com/vue/documentation/api/grid/#filterbycolumn

Thanks,

Jonathan







MS Manivel Sellamuthu Syncfusion Team January 14, 2021 11:26 AM UTC

Hi Jonathan, 

Thanks for your update. 

We have validated your queries and we can understand that you want to store the multiple filterSettings and re-apply them as per your requirement. For this we suggest you to store the settings in the local storage and apply the settings through the grid through setProperties method. Please refer the below code example and sample for more information. 

<template> 
  <div id="app"> 
    <ejs-button v-on:click.native="btnClick" :isPrimary="true" 
      >Store Filter1</ejs-button 
    > 
    <ejs-button v-on:click.native="btnClick1" :isPrimary="true" 
      >Store Filter2</ejs-button 
    > 
    <ejs-button cssClass="e-success" v-on:click.native="btnClick2" 
      >Apply Filter1</ejs-button 
    > 
    <ejs-button cssClass="e-success" v-on:click.native="btnClick3" 
      >Apply Filter2</ejs-button 
    > 
    <ejs-grid 
      ref="grid" 
      :dataSource="data" 
      :allowPaging="true" 
      :allowFiltering="true" 
      :filterSettings="filterSettings" 
    > 
       . . . 
      </e-columns> 
    </ejs-grid> 
  </div> 
</template> 
 
<script> 
import Vue from "vue"; 
import { GridPluginPageFilter } from "@syncfusion/ej2-vue-grids"; 
import { orderData } from "./dataSource"; 
import { ButtonPlugin } from "@syncfusion/ej2-vue-buttons"; 
 
Vue.use(GridPlugin); 
Vue.use(ButtonPlugin); 
export default { 
  name: "App", 
  data() { 
    return { 
      data: orderData.slice(050), 
      filterSettings: { type"Menu" }, 
      filter: { 
        type"CheckBox", 
      }, 
    }; 
  }, 
  methods: { 
    btnClick: function () { 
// here you can store the filterSettings in the local storage 
      var grid = this.$refs.grid.ej2Instances; 
      var model = JSON.parse(grid.getPersistData()).filterSettings; 
      window.localStorage.setItem("gridGrid1"JSON.stringify(model)); 
    }, 
    btnClick1: function () { 
      var grid = this.$refs.grid.ej2Instances; 
      var model = JSON.parse(grid.getPersistData()).filterSettings; 
      window.localStorage.setItem("gridGrid2"JSON.stringify(model)); 
    }, 
    btnClick2: function () { 
// here you can retrieve the filterSettings in the local storage and apply to the Grid 
      var grid = this.$refs.grid.ej2Instances; 
      grid.clearFiltering(); 
      var model = window.localStorage.getItem("gridGrid1"); 
      grid.setProperties({ filterSettings: JSON.parse(model) }); 
    }, 
    btnClick3: function () { 
      var grid = this.$refs.grid.ej2Instances; 
      grid.clearFiltering(); 
      var model = window.localStorage.getItem("gridGrid2"); 
      grid.setProperties({ filterSettings: JSON.parse(model) }); 
    }, 
  }, 
  provide: { 
    grid: [PageFilter], 
  }, 
}; 
</script> 
 
<style> 
@import "https://cdn.syncfusion.com/ej2/material.css"; 
</style> 


Please let us know, if you need further assistance. 

Regards, 
Manivel 



JO Jonathan January 18, 2021 10:56 AM UTC

I have tried : JUST PERFECT

Thanks a lot !

Jonathan


MS Manivel Sellamuthu Syncfusion Team January 19, 2021 04:51 AM UTC

Hi Jonathan, 

Thanks for your update. 

We are glad  to hear that the provided suggestion helped you. 

Please get back to us, if you need further assistance. 

Regards, 
Manivel 



JO Jonathan January 21, 2021 08:57 AM UTC

Hi,

I coded the solution in a function that load the filtering configuration.
The function is loaded in ":databound=" of my ejs-grid.

This work perfectly the first time loaded, or on refresh data or on refresh page (f5).

But I have a case that doesn't work.
I have a menu that load/reload "vue component" (not only data) without reloading entirely the page - Created, mounted etc. is re-called.

I that case : 
 - first time loaded : OK
 - change menu and return on the page
 - second time loaded : Failed 

The filtering is good/done BUT icon (triangle) for filtering is not "RED" and when I want to re-use them (change them) that doesn't work anymore (no change in filtering). And when I launch manually a clearFiltering() : at this moment : 

Error : 
vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'field' of undefined
    at Filter.clearFiltering (filter.js?f7f4:536)

    this in code : 
    for (var i = 0, len = filteredcols.length; i < len; i++) {
            this.removeFilteredColsByField(this.parent.getColumnByUid(filteredcols[i]).field, false);
        }


It seems that the table is not well destroyed or re-build during the classical "vue destruction/re-construction process".
Do you have an idea ?

Thanks a lot

Jonathan

Ps : what have I have tried (but doesn't work) : 
1. add destroy call in beforeDestroy
2. add refresh call before the filtering.


MS Manivel Sellamuthu Syncfusion Team January 22, 2021 02:58 PM UTC

Hi Jonathan, 

Thanks for your update. 

Could you please share the code example or sample which is causing the issue to validate at our end. Which will be helpful for us to replicate the reported issue and provide the better suggestion to overcome the issue. 

Regards, 
Manivel 



JO Jonathan March 10, 2021 09:52 AM UTC

Hi,

It's quite difficult to share code but I think I have found the problem.

uid is not a fix value !

I have multiple syncfusion instance in "tabs".
The uid generated seem to change each time, for each instance.

So, when I want to re-apply saved config : get by uid undefined
-> var field = uid ? this.parent.grabColumnByUidFromAllCols(uid).field : fieldName;
==> this.parent.grabColumnByUidFromAllCols(uid) is undefined

Stack : 
TypeError: Cannot read property 'field' of undefined
    at Filter.refreshFilterIcon (filter.js?f7f4:1117)
    at Filter.updateFilter (filter.js?f7f4:1101)
    at Filter.onPropertyChanged (filter.js?f7f4:440)
    at Observer.notify (observer.js?bf28:99)
    at Grid.Component.notify (component.js?183a:245)
    at Grid.extendedPropertyChange (grid.js?aba3:1239)
    at Grid.onPropertyChanged (grid.js?aba3:1152)
    at Grid.Base.dataBind (base.js?488e:112)
    at Grid.Component.dataBind (component.js?183a:195)
    at Grid.Base.setProperties (base.js?488e:60)


I compare previous saved data (with getPersistenceData) and the new grid column : 

Data grid :
{"disableHtmlEncode":false,"allowSorting":true,"allowResizing":true,"allowFiltering":true,"allowGrouping":true,"allowReordering":true,"showColumnMenu":true,"enableGroupByFormat":false,"allowEditing":true,"showInColumnChooser":true,"allowSearching":true,"autoFit":false,"sortDirection":"Descending","field":"2","width":"90","visible":true,"type":"string","format":{},"uid":"grid-column114","foreignKeyField":"2","index":1},

Saved Data :
{"type":"Menu","columns":[{"value":"Signé","field":"2","predicate":"or","uid":"grid-column398","operator":"equal","type":"string","matchCase":false,"ignoreAccent":false}],"ignoreAccent":false,"enableCaseSensitivity":false}

Doesn't mach anymore
I have no column with uid "uid":"grid-column398"

Is there a way to have fixed UID or using other unique field to setProperties who doesn't "match" anymore ?

ps : I see a function getUidByColumnField -> Else I will a to transform my saved data eachtime with that ?

Jonathan






MS Manivel Sellamuthu Syncfusion Team March 12, 2021 12:27 PM UTC

Hi Jonathan, 

Thanks for your update. 

By default while refreshing the columns the column UID will be generated each time. In your previous update you have mentioned that you are using the setProperties method in the dataBound event of the Grid. Could you please explain the purpose for that. Because dataBound event will be triggered each time when the grid data is modified, so flag variable need to be used so that setProperties will be applied only on Grid initial render. 

Could you please share the code example you have used inside the dataBound event of the Grid and video demo of the issue for further validation. 

Regards, 
Manivel 



JO Jonathan March 16, 2021 07:53 AM UTC

Hi,

1. Could you please explain the purpose for that.
I have a complex behavious : 
 - We save user filter/order/visibility preference to create local "views" of a table.
 - The user can create multiple "views" of a table, that can be applyied from a select in live.
 - BUT the user can also select "ONE" view as "favorite" : this view is loading by default with the :dataBound="loadLocalViewsAvailable" of the ejs-grid
 - And last but not list : it can have some different grid in multiple TABS 

 It seem that the first grid loaded uid are "stable" (always begin by 0).
 The other grid, or a reload of the first grid is a disaster.
 I don't understant why uid not restarted from 0 "always" for each grid.
 The grid musn't be linked each other. I don't understand why uid seem to depend of the number of grid or generations.


<ejs-grid :id="pgridtable" :ref="pgridtable" :dataSource="data" height="100%" :allowResizing='true'
:toolbarTemplate='toolbar' :allowSorting='true' :allowFiltering='true' :allowPaging="true"
:filterSettings='filterOptions' :pageSettings="pageSettings" :showColumnChooser='true'
:allowExcelExport='true' :allowPdfExport='true' :recordClick="recordClick" :recordDoubleClick="recordDoubleClick"
:actionBegin="actionBegin" :allowReordering='true' :dataBound="loadLocalViewsAvailable" >

<e-columns>
<e-column v-for="coldefine in columns"
:key="coldefine.field"
:field="coldefine.field.toString()"
:filter="filterMapper(coldefine.filter)"
:headerText='msg(coldefine.headerText)'
:customAttributes="customMapper(coldefine.customAttributes)"
:textAlign="coldefine.textAlign"
width=90
:visible="coldefine.visible === 'false' ? false : (coldefine.visible === 'true' ? true : null)"
:hideAtMedia="coldefine.hideAtMedia"
:disableHtmlEncode="false"
:type="typeof coldefine.colType !== 'undefined' && (coldefine.colType == 3 || coldefine.colType == 4) ? 'date' : undefined"
:format="getFormatByColType(coldefine.colType)"


/>
</e-columns>


</ejs-grid>

pgridtable is "unique" by grid.

You seem to say that refreshColumns of reload of the grid : re-generate other UID so impossible to have multiple views applicable with setproperties ? (uid always different).

The code of the databound view loader (see the refreshColumns because th reorder and hide column problem with the header for example).

loadLocalViewsAvailable() {

if(this.availableLocalViewFull.length > 0) return;

let strArrayLocalView = window.localStorage.getItem(this.localViewKey);
if(strArrayLocalView) {
let $this = this;
let lArrSaver = JSON.parse(strArrayLocalView);
this.availableLocalViewFull = lArrSaver;
let gridInstance = this.$refs[this.pgridtable].ej2Instances;
//-- 1 - filterToApply
//-- cleanFilters - Api function
//-- Apply filters

//-- Apply default
this.availableLocalViewFull.forEach((elm) => {
if(elm.view.fav) {
$this.selectedLocalView = elm.view;
//setTimeout(() => {

//-- Hide
$this.$refs[$this.pgridtable].hideColumns(elm.hiddenCol, "field");
//-- Order
let arrCol = $this.$refs[$this.pgridtable].getColumns().map(f => f.index);
if(elm.orderCol.length == arrCol.length) {
for(let i = 0; i < elm.orderCol.length; i++) {
if(elm.orderCol[i] !== arrCol[i]) {
let indx = arrCol.findIndex(v => v === elm.orderCol[i]);
$this.$refs[$this.pgridtable].reorderColumnByIndex(indx, i);
arrCol = $this.$refs[$this.pgridtable].getColumns().map(f => f.index);
}
}
}
//-- Refresh UI
$this.$refs[$this.pgridtable].refreshColumns();

//-- Filter application
gridInstance.clearFiltering();
if(typeof elm.dateFilterValues !== 'undefined') {
$this.dateValue = elm.dateFilterValues;
}
if(typeof elm.gridProperties !== 'undefined') {
gridInstance.setProperties({filterSettings: elm.gridProperties});
}

//}, 1000);

}
});




}
},



And the function call in the select (to select a particular view of a table to apply) : 
applyView() {

let allCol = this.$refs[this.pgridtable].getColumns().map((c) => c.field);
this.$refs[this.pgridtable].showColumns(allCol, "field");

let arrCol = this.$refs[this.pgridtable].getColumns().map(f => f.index);
//-- Default BDD order 0 -> length
let orderCol = [...Array(arrCol.length).keys()];
//-- ClearFilter
let gridInstance = this.$refs[this.pgridtable].ej2Instances;
gridInstance.clearFiltering();

if(this.selectedLocalView) {
//-- Hide
this.$refs[this.pgridtable].hideColumns(this.availableLocalViewFull[this.selectedLocalView.id].hiddenCol, "field");
//-- Reorder
orderCol = this.availableLocalViewFull[this.selectedLocalView.id].orderCol;
//-- Apply
if(typeof this.availableLocalViewFull[this.selectedLocalView.id].gridProperties !== 'undefined') {
gridInstance.setProperties({ filterSettings: this.availableLocalViewFull[this.selectedLocalView.id].gridProperties });
}

}
if(orderCol.length == arrCol.length) {
for(let i = 0; i < orderCol.length; i++) {
if(orderCol[i] !== arrCol[i]) {
let indx = arrCol.findIndex(v => v === orderCol[i]);
this.$refs[this.pgridtable].reorderColumnByIndex(indx, i);
arrCol = this.$refs[this.pgridtable].getColumns().map(f => f.index);
}
}
}

},









JO Jonathan March 16, 2021 08:29 AM UTC

I will try to make a video today or tomorrow : it will be more clean to understand


JO Jonathan March 17, 2021 12:48 PM UTC

Please find enclosed the demo video of the problem linked to the code above.

Thanks by advance.

Volatile UID is a very big problem with the persistData saving on multiple grid.

Attachment: GridPersistDataBug_44c53f1a.zip


MS Manivel Sellamuthu Syncfusion Team March 19, 2021 09:37 AM UTC

Hi Jonathan,  

We have created a new incident under your Direct trac account to follow up with this query. We suggest you to follow up with the incident for further updates. Please log in using the below link.     

  
Regards,  
Manivel 


Loader.
Up arrow icon