Vue 3 TreeGrid with same filterTemplate for multiple columns

Hi,

I want to create a filter template for TreeGrid component. I created the filter template in SFC, and I want to use it for multiple columns.

In the filter template component I call the TreeGrid filterByColumn with the given column object, but the givven column object is not the correct one.

Filter.vue:

<template>
  <ejs-textbox ref="stringFilterInput" v-model="value" placeholder="No Filter" showClearButton="true" @change="onChange"></ejs-textbox>
</template>

<script>
import { TextBoxComponent } from "@syncfusion/ej2-vue-inputs";

export default { components: {
        'ejs-textbox' : TextBoxComponent, }, data() {
        return {
            value: '',
        } },   methods: {
        onChange({value}) {
            let column = this.data.column
            let fieldName = column.field
            if (value === '') {      this.data.column.parent.clearFiltering([fieldName])
            } else {       this.data.column.parent.filterByColumn(fieldName, "startsWith", value)
            }
        }, },
}
</script>


See the attached project example (when setting filter text for the first column, it do filter the second column).


Attachment: Vue_3_filter_template_20525ae2.zip

5 Replies

PS Pon Selva Jeganathan Syncfusion Team January 28, 2022 12:33 PM UTC

Hi Liraz, 
 
Thanks for contacting syncfusion forum. 
 

Query: Vue 3 TreeGrid with same filterTemplate for multiple columns

We were able to reproduce the isse at our end in shared sample. In shared sampleThe column field value is always taken from the second column field name which is the cause of the issue.  To avoid this issue, we suggest you follow the below code example, 
 
 
Your code: 
onChange({value}) { 
             
  let column = this.data.column 
  console.log('column: ', {column: column}) 
 
  let fieldName = column.field 
  if (value === '') { 
      this.data.column.parent.clearFiltering([fieldName]) 
  } else { 
      this.data.column.parent.filterByColumn(fieldName"startsWith"value) 
  } 
}, 
}, 
Modified code: 
onChange({value}) { 
   
  var task_textbox=document.getElementById("textbox_4").ej2_instances[0];// First column textbox instance 
  var pri_textbox=document.getElementById("textbox_5").ej2_instances[0]; // second column textbox instance 
  var treegrid=document.getElementsByClassName('e-treegrid')[0].ej2_instances[0]; 
  let column = this.data.column 
  let fieldName; 
  console.log('column: ', {column: column}) 
  if(task_textbox.value !=null && task_textbox.value != ""){ 
    fieldName = "taskName"//assign field name 
  } 
  else if(pri_textbox.value!=null && pri_textbox.value != ""){ 
      fieldName = "priority"// assign field name 
  } 
 
  if (value === '') { 
      treegrid.clearFiltering([fieldName]) 
  } else { 
      treegrid.filterByColumn(fieldName"startsWith"value) 
  } 
}, 
}, 
 
                                                                                       
                                                                        } 
 
In the above code snippet, we assign the field name based on the textbox value. 
 
Please refer to the below mmodified sample, 
 
Kindly get back to us for further assistance. 
 
Regards,   
Pon selva   


 



LI Liraz January 31, 2022 11:53 AM UTC

Hi,

I can't use this solution because my application is more complicated: user can choose (from a long list of columns) to have any column he want in the TreeGrid. Therefore, I am searching for a generic solution (the project example is just to show you the problem).

I tried also to pass the column field as a props to the template (see below), and again the passed props is incorrect.

App.vue:

<template>
  <div id="app">
      <ejs-treegrid ref="treegrid" :dataSource="data" height='100%' :allowFiltering='true' :filterSettings="filterSettings">
            <e-columns>
                <e-column field='taskName' headerText='projectName' :filterTemplate="nameFilterTemplate"></e-column>
                <e-column field='priority' headerText='priority' :filterTemplate="priorityFilterTemplate"></e-column>
            </e-columns>
        </ejs-treegrid>
    </div>
</template>

<script>
import {createApp} from 'vue'
import { Filter } from '@syncfusion/ej2-vue-treegrid';
import StringFilter from './components/StringFilter.vue'

const app = createApp();

// Template declaration
var nameColFilter = app.component('template', StringFilter)
var priorityColFilter = app.component('template', StringFilter)

export default {
  name: 'App',
  data() {
    return {
        data: [
            { taskID: 1, taskName: 'Planning', startDate: new Date('02/03/2017'),
                endDate: new Date('02/07/2017'), progress: 100, duration: 5, priority: 'Normal', approved: false },
            { taskID: 2, taskName: 'Plan timeline', startDate: new Date('02/03/2017'),
                endDate: new Date('02/07/2017'), duration: 5, progress: 100, priority: 'Normal', approved: false },
            { taskID: 3, taskName: 'Plan budget', startDate: new Date('02/03/2017'),
                endDate: new Date('02/07/2017'), duration: 5, progress: 100, priority: 'Low', approved: true },
            { taskID: 4, taskName: 'Allocate resources', startDate: new Date('02/03/2017'),
                endDate: new Date('02/07/2017'), duration: 5, progress: 100, priority: 'Critical', approved: false },
            { taskID: 5, taskName: 'Planning complete', startDate: new Date('02/07/2017'),
                endDate: new Date('02/07/2017'), duration: 0, progress: 0, priority: 'Low', approved: true }
        ],
        filterSettings: {
            type: 'FilterBar'
        },
        nameFilterTemplate: () => { return { template: {
            extends: nameColFilter,
            propsData: {
                fieldName: 'taskName',
                treegrid: this.$refs.treegrid
            }
        }}},
        priorityFilterTemplate: () => { return { template: {
            extends: priorityColFilter,
            propsData: {
                fieldName: 'priority',
                treegrid: this.$refs.treegrid
            }
        }}},
    };
  },
  provide: {
    treegrid: [Filter],
  }
};
</script>


StringFilter.vue:

<template>
     <ejs-textbox ref="stringFilterInput" v-model="value" placeholder="No Filter" showClearButton="true" @change="onChange"></ejs-textbox>
</template>

<script>
import { TextBoxComponent } from "@syncfusion/ej2-vue-inputs";

export default {
    name: 'StringFilter',
    components: {
        'ejs-textbox' : TextBoxComponent,
    },
    data() {
        return {
            value: '',
        }
    },
    props: {
        fieldName: {
            type: String
        },
        treegrid: {
            type: Object
        }
    },
    methods: {
        onChange({value}) {
            console.log('column: ', {fieldName: this.fieldName})
            if (value === '') {
                this.treegrid.clearFiltering([this.fieldName])
            } else {
                this.treegrid.filterByColumn(this.fieldName, "startsWith", value)
            }
        },
    },
}
</script>


It seems that there is a real issue here: when using a filter template for multiple columns, the data / props is of the last rendered filter.


Thanks,



PS Pon Selva Jeganathan Syncfusion Team February 2, 2022 04:58 AM UTC

Hi Liraz, 
 
Thanks for the update. 
 
We are working on this query with high priority. And we need time to find a feasible solution of your requirement and will update you with further details on or before 4th February, 2022 
 
Regards,   
Pon selva   



PS Pon Selva Jeganathan Syncfusion Team February 4, 2022 03:15 PM UTC

Hi Liraz, 
 
Thanks for your patience. 
 
Based on your query we suggest you use the filterBarTemplate property of the treegrid. The filterBarTemplate property is used to add a custom component instead of default input component for filter bar. It have create and read functions. 
  • create: It is used for creating custom components.
  • read: It is used to perform custom filter action
Please refer to the below API documentation, 
 
Please refer to the below help documentation, 
 
And We are working on this query (filter template) with high priority. And we need time to find a feasible solution of your requirement and will update you with further details on or before 8th February, 2022 
 
Regards,   
Pon selva   




PS Pon Selva Jeganathan Syncfusion Team February 8, 2022 12:51 PM UTC

Hi Liraz, 
 
Thanks for your patience. 
 

Query: when using a filter template for multiple columns, the data / props is of the last rendered filter.

To avoid this issue, we suggest you follow the below code example, 
 
 
StringFilter.vue 
 
<template> 
{{$data.data.column.field}} 
     <ejs-textbox v-bind:ref="$data.data.column.field" v-model="value" placeholder="No Filter" showClearButton="true"    @change="onChange"></ejs-textbox> 
     
    
</template> 
 
<script> 
  
import { TextBoxComponent } from "@syncfusion/ej2-vue-inputs"; 
 
export default { 
    name: 'StringFilter', 
    
    components: { 
        'ejs-textbox' : TextBoxComponent, 
    }, 
     
    data() { 
return { 
            value:'', 
                  
              
        } 
    }, 
….. 
    methods: { 
         
   
        onChange({value}) { 
             console.log(this.$refs) 
             let fieldName; 
            
             if(this.$refs.taskName != undefined){ 
              fieldName="taskName" 
             } 
             else if(this.$refs.priority != undefined){ 
              fieldName="priority" 
             } else if(this.$refs.duration != undefined){ 
              fieldName="duration" 
             } 
 
            if (value === '') { 
                this.data.column.parent.clearFiltering([fieldName]) 
            } else { 
                this.data.column.parent.filterByColumn(fieldName, "startsWith", value) 
            } 
        }, 
    }, 
} 
 
</script> 
 
<style scoped>  
 
</style> 
                                                  
                                                                        
 
In the above code snippet, we assign the column’s field name into the ref property. In Onchange method, we assign the column’s field name based on ref property. 
 
Please refer to the below modified sample, 
 
Kindly get back to us for further assistance. 
 
Regards,   
Pon selva   

 


Loader.
Up arrow icon