How can the grid's filter menu be changed so that boolean columns show Yes/No instead of true/false as the filter options?

I am using a GridComponent to render a column whose type is "boolean". I set a template ((row) => row.validated ? "Yes" : "No") so that the data cell renders "Yes" or "No" instead of "true" and "false".

Here are my filter settings for the grid:

{
  mode: "Immediate",
  immediateModeDelay: 1000,
  type: 'Menu',
}


As shown below, the column is now rendering "Yes" or "No" in the data cells but when the user opens the filter menu and clicks the dropdown to select a value to filter by, it is showing true / false instead of yes / no.

How can I also change the filter option display in the filter modal to match Yes/No like my data cells?


7 Replies

RR Rajapandi Ravi Syncfusion Team July 5, 2022 12:22 PM UTC

Hi Justin,


Greetings from Syncfusion support


Based on your query we have prepared a sample and achieved your requirement by using actionBegin and actionComplete event of Grid. Please refer the below code example and sample for more information.


 

actionBegin(args) { //actionBegin event of Grid

        if(args.requestType === 'filtering' && args.currentFilteringColumn === 'Verified') {

            if(args.currentFilterObject.value === 'Yes') {

                args.columns[0].value = true;

            }

            else {

                args.columns[0].value = false;

            }

        }

    }

    actionComplete(args) { //actionComplete event of Grid

        if(args.requestType === 'filterafteropen' && args.columnName === 'Verified') {

            document.getElementsByClassName('e-dropdownlist')[1].ej2_instances[0].dataSource = [{Verified: 'Yes'}, {Verified: 'No'}]; //set the datasource here

        }

    }

 


Sample: https://stackblitz.com/edit/react-5jgrbq?file=index.js,data.js,package.json


Screenshot:



Regards,

Rajapandi R



JS Justin Schnurer July 5, 2022 08:49 PM UTC

Hi, thanks for the sample. I had to change your code a lot so that it would work with multiple filterable columns. Here are my grid actionbegin and actioncomplete events. They check the column being filtered to see if it is a boolean type before applying these customizations.



function gridActionBegin(args: PageEventArgs | GroupEventArgs | FilterEventArgs | SearchEventArgs | SortEventArgs | AddEventArgs | SaveEventArgs | EditEventArgs | DeleteEventArgs | ActionEventArgs) {
  if (args.requestType === 'filtering'
    && 'columns' in args
    && args.columns !== undefined
    && args.currentFilterObject !== undefined) {

    let column = args.columns.find(x => x.field === args.currentFilterObject?.field);

    if (column
      && (column as any)?.parentObj?.parentObj?.columnModel.find((x: any) => x.field === (column as any)?.properties?.field)?.type === "boolean") {
      column.value = args.currentFilterObject.value === 'Yes';
    }
  }
}

function gridActionComplete(args: any) {
  if (args.requestType === 'filterafteropen'
    && args.columnType === "boolean") {
    const ej2Item = (document.getElementsByClassName('e-dropdownlist')[1] as any)
      .ej2_instances[0];

    ej2Item.dataSource = [
      { isValidated: 'Yes' },
      { isValidated: 'No' }
    ];
  }
}


Now I have a new problem. Everything works as expected until the user re-opens the filter. When they do so, it shows no selected value. It would be ideal if the filter modal contained the currently selected filter when it is opened. How can I accomplish this?


As you can see in the below screenshow, my "Validated?" column is currently filtered. However, when I open the filter modal, there is no value shown in the input field.




RR Rajapandi Ravi Syncfusion Team July 6, 2022 12:50 PM UTC

Hi Justin,


Thanks for your update


We have checked your shared information and we could see that you are facing the problem with reopening the filter menu. To resolve the problem, we suggest you use the below way to achieve your requirement. Please refer the below code example and sample for more information.


 

actionBegin(args) {

         if(args.action === 'clearFilter') {

             if(args.currentFilterColumn.field === 'Verified') {

                document.getElementsByClassName('e-dropdownlist')[1].ej2_instances[0].value = '';

                args.currentFilterObject.value = null;

             }

        }

        if(args.requestType === 'filtering' && args.currentFilteringColumn === 'Verified') {

            if(args.currentFilterObject.value === 'Yes') {

                args.columns[0].value = true;

            }

            else {

                args.columns[0].value = false;

            }

        }

    }

    actionComplete(args) {

        if(args.requestType === 'filterafteropen' && args.columnName === 'Verified') {

            document.getElementsByClassName('e-dropdownlist')[1].ej2_instances[0].dataSource =

                [{Verified: 'Yes'}, {Verified: 'No'}];

                if(args.filterModel.filterObj.currentFilterObject != undefined) {

                    document.getElementsByClassName('e-dropdownlist')[1].ej2_instances[0].value = args.filterModel.filterObj.values.Verified;

                }

       }

      

    }

 


Sample: https://stackblitz.com/edit/react-5jgrbq-mjkeir?file=index.js,data.js,package.json


Regards,

Rajapandi R



JS Justin Schnurer July 6, 2022 08:47 PM UTC

Thanks! It works!

I made a change to the example actionComplete function so that it will work with any column, rather than a hard-coded column named "Verified". I am sharing it here for anyone that might want it in the future.

Note: My code is Typescript.

I'm also sharing the actionBegin function that I use.

function gridActionBegin(args: PageEventArgs | GroupEventArgs | FilterEventArgs | SearchEventArgs | SortEventArgs | AddEventArgs | SaveEventArgs | EditEventArgs | DeleteEventArgs | ActionEventArgs) {
  if (args.requestType === 'filtering'
    && 'columns' in args
    && args.columns !== undefined
    && args.currentFilterObject !== undefined) {

    let column = args.columns.find(x => x.field === args.currentFilterObject?.field);

    if (column
      && (column as any)?.parentObj?.parentObj?.columnModel.find((x: any) => x.field === (column as any)?.properties?.field)?.type === "boolean") {
      column.value = args.currentFilterObject.value === 'Yes';
    }
  }
}

function gridActionComplete(args: any) {
  if (args.requestType === 'filterafteropen') {
    if (args.columnType === "number"
      || args.columnType === "string") {
      window.setTimeout(() => {
        // Wait 0ms then focus on the input field.
        // Only focus for string and number columns.
        args
          .filterModel
          ?.dlgDiv
          ?.querySelector(args.columnType === "number"
            ? ".e-numerictextbox"
            : ".e-autocomplete")
          ?.focus();
      });
    }

    if (args.columnType === "boolean") {
      const ej2Item = (document.getElementsByClassName('e-dropdownlist')[1] as any)
        .ej2_instances[0];

      ej2Item.dataSource = [
        { isValidated: 'Yes' },
        { isValidated: 'No' }
      ];

      if (args.filterModel.filterObj.currentFilterObject != undefined) {
        ej2Item.value = args.filterModel.filterObj.values[args.filterModel.filterObj.currentFilterObject.field];
      }
    }
  }
}


RR Rajapandi Ravi Syncfusion Team July 7, 2022 11:11 AM UTC

Most Welcome



AC Amalia Chrysanthakopoulou December 10, 2024 03:36 PM UTC

Isn't there a simpler way to accomplish this? Maybe if the API provided us a filter value template for example?

Cause I would like to add this functionality in all my grids and it seems like a complex workaround to depend on. 

Are there any plans in supporting this functionality out of the box?
Thank you!



DM Dineshnarasimman Muthu Syncfusion Team December 11, 2024 09:56 AM UTC

Hi Amalia Chrysanthakopoulou,


By reviewing your query, we understand your requirement to change the boolean values in the filterMenu without using complex code.


This requirement can be achieved using column.filter params of the grid. In the filterParams, we can set the custom dataSource directly. The code snippet of the implementation and sample have been attached for your reference.


let booleanFilterParams = {

  params: {

    dataSource: new DataManager([

      { Verified: true, booleanText: 'Yes' },

      { Verified: false, booleanText: 'No' },

    ]),

    fields: { text: 'booleanText', value: 'Verified' },

    query: new Query(),

    actionComplete: () => false,

  },

};

 

<ColumnDirective

              field="Verified"

              headerText="Verified"

              type={'boolean'}

              width="150"

              editType="booleanedit"

              template={booleanTemplate}

              filter={booleanFilterParams}

            ></ColumnDirective>

 

 


Sample: https://stackblitz.com/edit/react-zjdgwlmy-qztrnu7h?file=index.js


Please let us know if you need any further assistance.


Regards,

Dineshnarasimman M



Loader.
Up arrow icon