Custom numeric filter cell with filter operator DropDownList

0 Answers 34 Views
DropDownList Filter 
Christian
Top achievements
Rank 1
Iron
Iron
Iron
Christian asked on 27 Nov 2023, 08:19 AM | edited on 27 Nov 2023, 08:37 AM

Hello KendoReact Team,

is there an example that shows how to fully customise a numeric filter cell? I have the case that I need a filter cell for integers and one for decimals. The creation of the component is done, but I can't find an example that also implies the filter operator. The following questions arise from the problem.

1. Where can I view all the CSS classes of KendoReact that I can use for component styling? E.g. `k-icon k-i-filter-clear k-buttonicon` With this class I can style a clear button, including automatic assignment of the icon.

2. Which element is necessary to display the selection list of the filter operator?

3. Is it possible to implement the filter element in the standard display?

 

Thank you for the help

Screen capture

 

Code

import { NumericTextBox, NumericTextBoxChangeEvent } from "@progress/kendo-react-inputs";
import { GridFilterCellProps } from "@progress/kendo-react-grid";
import { Button } from "@progress/kendo-react-buttons";
import React, { useState } from "react";
import { DropDownList } from "@progress/kendo-react-dropdowns/dist/npm/DropDownList/DropDownList";
import { DropDownListChangeEvent } from "@progress/kendo-react-dropdowns";

type CustomNumericFilterCellProps = {
  gridFilterCellProps: GridFilterCellProps;
  format: string;
};

type NumericFilterOperatorType = {
  text: string;
  operator: string;
};

const numericFilterOperators: NumericFilterOperatorType[] = [
  { text: "Is equal to", operator: "eq" },
  { text: "Is not equal to", operator: "neq" },
  { text: "Is greater than or equal", operator: "gte" },
  { text: "Is greater than", operator: "gt" },
  { text: "Is less than or equal", operator: "lte" },
  { text: "Is less than", operator: "lt" },
  { text: "Is null", operator: "isnull" },
  { text: "Is not null", operator: "isnotnull" },
];

export const CustomNumericFilterCell = ({
  gridFilterCellProps,
  format,
}: CustomNumericFilterCellProps) => {
  const { onChange: filterCellPropsOnChange } = gridFilterCellProps;

  const [filterCellValue, setFilterCellValue] = useState<number | null>(null);
  const [isFilterActive, setIsFilterActive] = useState<boolean>(false);
  const [selectedOperator, setSelectedOperator] = useState<NumericFilterOperatorType>(
    numericFilterOperators[0]
  );

  const numericTextBoxOnChange = (event: NumericTextBoxChangeEvent) => {
    const { value: filterValue } = event.target;
    setFilterCellValue(filterValue);
    setIsFilterActive(true);

    filterCellPropsOnChange({
      value: filterValue,
      operator: filterValue ? selectedOperator.operator : "",
      syntheticEvent: event.syntheticEvent,
    });
  };

  const onButtonClearClick = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
    event.preventDefault();
    setFilterCellValue(null);
    setIsFilterActive(false);
    setSelectedOperator(numericFilterOperators[0]);

    filterCellPropsOnChange({
      value: "",
      operator: "",
      syntheticEvent: event,
    });
  };

  const dropdownlistOnChange = (event: DropDownListChangeEvent) => {
    const operator = event.value as NumericFilterOperatorType;
    setSelectedOperator(operator);
  };

  return (
    <div className="k-filtercell">
      <NumericTextBox onChange={numericTextBoxOnChange} format={format} value={filterCellValue} />

      <DropDownList
        data={numericFilterOperators}
        textField="text"
        dataItemKey="operator"
        onChange={dropdownlistOnChange}
        value={numericFilterOperators.find((item) => item.operator === selectedOperator.operator)}
        className="k-button k-filtercell-clear"
        popupSettings={{ width: "180px" }}
      />

      <Button title="Clear" onClick={onButtonClearClick}>
        <span
          className={`k-icon k-i-filter-clear k-button-icon ${
            !isFilterActive ? "k-disabled" : "k-clear-button-visible"
          }`}
        />
      </Button>
    </div>
  );
};

 

Christian
Top achievements
Rank 1
Iron
Iron
Iron
commented on 27 Nov 2023, 11:58 AM

Hello,

after much trial and error, I have found a solution. For all those who are interested.

Screen

 

import { NumericTextBox, NumericTextBoxChangeEvent } from"@progress/kendo-react-inputs"; import { GridFilterCellProps } from"@progress/kendo-react-grid"; import { Button } from"@progress/kendo-react-buttons"; importReact, { useState } from"react"; import { DropDownList } from"@progress/kendo-react-dropdowns/dist/npm/DropDownList/DropDownList"; import { DropDownListChangeEvent } from"@progress/kendo-react-dropdowns"; import { KendoReactNumericFilterFormat } from"./KendoReactNumericFilterFormat"; exporttypeCustomNumericFilterCellProps = { gridFilterCellProps: GridFilterCellProps; format: KendoReactNumericFilterFormat; }; typeNumericFilterOperatorType = { text: string; operator: string; }; constnumericFilterOperators: NumericFilterOperatorType[] = [ { text: "Is equal to", operator: "eq" }, { text: "Is not equal to", operator: "neq" }, { text: "Is greater than or equal", operator: "gte" }, { text: "Is greater than", operator: "gt" }, { text: "Is less than or equal", operator: "lte" }, { text: "Is less than", operator: "lt" }, { text: "Is null", operator: "isnull" }, { text: "Is not null", operator: "isnotnull" }, ]; exportconstCustomNumericFilterCell = ({ gridFilterCellProps, format, }: CustomNumericFilterCellProps) => { const { onChange: filterCellPropsOnChange } = gridFilterCellProps; const [filterCellValue, setFilterCellValue] = useState<number | null>(null); const [isFilterActive, setIsFilterActive] = useState<boolean>(false); const [selectedOperator, setSelectedOperator] = useState<NumericFilterOperatorType>( numericFilterOperators[0] ); constnumericTextBoxOnChange = (event: NumericTextBoxChangeEvent) => { const { value: filterValue } = event.target; setFilterCellValue(filterValue); setIsFilterActive(true); filterCellPropsOnChange({ value: filterValue, operator: filterValue ? selectedOperator.operator : "", syntheticEvent: event.syntheticEvent, }); }; constonButtonClearClick = (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => { event.preventDefault(); setFilterCellValue(null); setIsFilterActive(false); setSelectedOperator(numericFilterOperators[0]); filterCellPropsOnChange({ value: "", operator: "", syntheticEvent: event, }); }; constdropdownlistOnChange = (event: DropDownListChangeEvent) => { const operator = event.valueasNumericFilterOperatorType; setSelectedOperator(operator); setIsFilterActive(true); }; return ( <div className="k-filtercell"> <NumericTextBox style={{ marginRight: "4px" }} onChange={numericTextBoxOnChange} format={format} value={filterCellValue} /> <DropDownList data={numericFilterOperators} textField="text" dataItemKey="operator" onChange={dropdownlistOnChange} value={numericFilterOperators.find((item) => item.operator === selectedOperator.operator)} popupSettings={{ width: "180px" }} className="k-dropdownlist k-picker k-dropdown-operator k-picker-md k-rounded-md k-picker-solid" iconClassName="k-icon k-i-filter k-button-icon" style={{ marginRight: "4px" }} /> <Button title="Clear" className="k-button-md" onClick={onButtonClearClick} disabled={!isFilterActive} > <span className={`k-icon k-i-filter-clear k-button-icon ${ !isFilterActive ? "k-disabled" : "k-clear-button-visible" }`} /> </Button> </div> ); };


Konstantin Dikov
Telerik team
commented on 28 Nov 2023, 06:17 AM

Hi Christian,

I am glad to see that you have found a solution for the operators and the filtering.

As for a list with all class names, I have to say that we do not have such list available and in order to use the class names of KendoReact components for styling elements you can inspect the rendered elements in the browser for the component which styles you want to use and see the structure and the applied class names.

 

Christian
Top achievements
Rank 1
Iron
Iron
Iron
commented on 30 Nov 2023, 08:16 AM | edited

Hello Konstantin,

thank you for your response. I still have a question about the custom filter cell. If I want to use this with floating point numbers, I get an error with numbers with a leading 0. Do you have a suggestion on how I can deal with this? The NumericTextBox only accepts numbers.

Konstantin Dikov
Telerik team
commented on 04 Dec 2023, 06:30 AM

Hi Christian,

The NumericTextBox works only with numbers, so if you need to use leading zeroes you will have to use a simple input element (000.1 for example). However, if the issue is observed with numbers like 0.1, this could indicate that you are passing string values and not a float numbers to the underlying data of the Grid (the data property). 

Nevertheless, if the issue persists, please share a stackblitz example demonstrating the problem, so we can test and debug it locally.

No answers yet. Maybe you can help?

Tags
DropDownList Filter 
Asked by
Christian
Top achievements
Rank 1
Iron
Iron
Iron
Share this question
or