Search code examples
javascriptreactjstypescriptgridag-grid

Changing cell format in ag-grid/react


I am displaying numbers in my cells and for the colDefs, I only want to show them to 2dp. So within my colDefs I have this -

valueFormatter: (params: ValueFormatterParams) => params.value?.price?.toFixed(2)

I would like to add the ability for the user to double click on the cell and for it to show the full number (but when they click away it goes back to the 2dp format).

I have attached onCellDoubleClicked to my grid however I am having trouble sorting this.

    <Grid
      onGridReady={onGridReady}
      {...gridOptions}
      quickFilterText={searchValue}
      onCellDoubleClicked={manageCellDoubleClick}
    />

I know there is setDataValue available in the click event as I tried to use this however I don't want to change the data (because I still want the full number to be always there on copy/paste/export etc.). I just want the full number to be revealed and then for it to go back to the 2dp format when you click away.

Is there a way to do this?


Solution

  • We can use onCellDoubleClicked event to trigger a toggle on variable isFull on the row data.

    const cellDoubleClicked = (params) => {
      console.log(1)
      const data = params.data;
      data['showFull'] = !data['showFull'];
      params.node.setData(data);
    }
    

    On the formatter, using a ternary condition we can toggle the full/rounded value as shown below!

    const customFormatter = (params) => params.data.showFull ? params.value : params && params.value && params.value.toFixed(2);
    

    Then finally, we can add a onCellClicked listener to reset the isFull property to false, to bring it back to the old state, it only works when you click another cell in the grid!

      const onCellClicked = useCallback((event) => {
        console.log(event);
        setRowData(rowData.map(x => {
          x.showFull = false;
          return x;
        }));
      }, []);
    

    full code

    'use strict';
    
    import 'ag-grid-community/styles/ag-grid.css';
    import 'ag-grid-community/styles/ag-theme-quartz.css';
    import { AgGridReact } from 'ag-grid-react';
    import React, { StrictMode, useMemo, useState, useCallback } from 'react';
    import { createRoot } from 'react-dom/client';
    import './styles.css';
    
    
    const customFormatter = (params) => params.data.showFull ? params.value : params && params.value && params.value.toFixed(2);
    
    const cellDoubleClicked = (params) => {
      console.log(1)
      const data = params.data;
      data['showFull'] = !data['showFull'];
      params.node.setData(data);
    }
    
    
    const createRowData = () => {
      var rowData = [];
      for (var i = 0; i < 100; i++) {
        rowData.push({
          price: Math.random() * 100,
        });
      }
      return rowData;
    };
    
    const GridExample = () => {
      const containerStyle = useMemo(() => ({ width: '100%', height: '100%' }), []);
      const gridStyle = useMemo(() => ({ height: '100%', width: '100%' }), []);
      const [rowData, setRowData] = useState(createRowData());
      const [columnDefs, setColumnDefs] = useState([
        { headerName: 'Price', field: 'price', valueFormatter: customFormatter, onCellDoubleClicked: cellDoubleClicked },
      ]);
      const defaultColDef = useMemo(() => {
        return {
          flex: 1,
          cellClass: 'number-cell',
        };
      }, []);
    
    
      const onCellClicked = useCallback((event) => {
        console.log(event);
        setRowData(rowData.map(x => {
          x.showFull = false;
          return x;
        }));
      }, []);
    
      return (
        <div style={containerStyle}>
          <div
            style={gridStyle}
            className={
              "ag-theme-quartz"
            }
          >
            <AgGridReact
              rowData={rowData}
              columnDefs={columnDefs}
              defaultColDef={defaultColDef}
              onCellClicked={onCellClicked}
            />
          </div>
        </div>
      );
    };
    
    const root = createRoot(document.getElementById('root'));
    root.render(
      <StrictMode>
        <GridExample />
      </StrictMode>
    );
    

    plunkr