How to render a button before the detail grid in ag grid react

157 views Asked by At

I'd like to add a "New Payment" button above the Detail grid within the Master Rows. Please feel free to share any tips to enhance the efficiency and reduce potential errors in my component. Here's my current component:

function CreditorsViewer() {
  const gridRef = useRef<AgGridReact | null>(null);
  const defaultColDef = useMemo( () => ({
    sortable: true, 
    filter: true, 
    enableRowGroup: true
  }), [])
  const detailCellRendererParams = useMemo(() => {
    return {
      detailGridOptions: {
        columnDefs: [
          { field: 'amount' },
          { field: 'type' },
          { field: 'year' },
          { field: 'month'},
          { field: 'date' },
        ],
        defaultColDef: {
          flex: 1,
          sortable: true, 
          filter: true, 
          enableRowGroup: true
        },
        rowSelection: "multiple",
        rowGroupPanelShow:"always",
        alwaysShowHorizontalScroll: true,
        alwaysShowVerticalScroll: true,
        
      },
      getDetailRowData: (params: GetDetailRowDataParams) => {
        params.successCallback(params.data.payments)
      },
    };
  }, []);
  const columnsDefs =[
    { field: "client", cellRenderer: 'agGroupCellRenderer'},
    { field: "contact" },
    { field: "debt", valueFormatter: valueFormatterToDH },
    { field: "pending", valueFormatter: valueFormatterToDH},
    {field: "year"},
    {field: "date"},
    { field: "transactions" },
  ];
  
 
  const cellClickedListener = useCallback((e: { value: any }) => {
    console.log('cellClicked', e.value);
  }, []);
  return (
    <div className="h-full container ag-theme-material">
      <AgGridReact
        defaultColDef={defaultColDef}
        masterDetail={true}
        detailRowHeight={300}
        detailCellRendererParams={detailCellRendererParams}
        ref={gridRef}
        rowGroupPanelShow="always"
        enableRangeSelection={true}
        enableCharts={true}
        animateRows={true}
        rowSelection="multiple"
        domLayout="autoHeight"
        alwaysShowHorizontalScroll={true}
        alwaysShowVerticalScroll={true}
        rowData={rowData}
        columnDefs={columnsDefs}
        onCellClicked={cellClickedListener}
      />
    </div>
  );
}

I've made an attempt to create a custom detail cell renderer, but I didn't succeed due to my current skillset, and I found the documentation article related to this topic a bit challenging to grasp .

1

There are 1 answers

0
Ahmet Firat Keler On

Actually, it's not a big deal.

First add your custom detail cell renderer component

detailCellRenderer.jsx

import React, { useEffect } from 'react';
import { AgGridReact } from 'ag-grid-react';

const DetailCellRenderer = ({ data, node, api }) => {
  const rowId = node.id;

  useEffect(() => {
    return () => {
      console.log('removing detail grid info with id: ', rowId);

      // the detail grid is automatically destroyed as it is a React component
      api.removeDetailGridInfo(rowId);
    };
  }, []);

  const colDefs = [
    { field: 'callId' },
    { field: 'direction' },
    { field: 'number' },
    { field: 'duration', valueFormatter: "x.toLocaleString() + 's'" },
    { field: 'switchCode' },
  ];

  const defaultColDef = {
    flex: 1,
    minWidth: 120,
  };

  const onGridReady = (params) => {
    const gridInfo = {
      id: node.id,
      api: params.api,
      columnApi: params.columnApi,
    };

    console.log('adding detail grid info with id: ', rowId);

    api.addDetailGridInfo(rowId, gridInfo);
  };

  return (
    <div className="full-width-panel">
      <div className="full-width-button">
        <button>New Payment</button>
      </div>
      <AgGridReact
        id="detailGrid"
        className="full-width-grid ag-theme-alpine"
        columnDefs={colDefs}
        defaultColDef={defaultColDef}
        rowData={data.callRecords}
        onGridReady={onGridReady}
      />
    </div>
  );
};

export default DetailCellRenderer;

Here's our styles

.example-wrapper {
  display: flex;
  flex-direction: column;
  height: 100%;
}

#myGrid {
  flex: 1 1 0px;
  width: 100%;
}

.full-width-panel {
  position: relative;
  background: #edf6ff;
  height: 100%;
  width: 100%;
  padding: 5px;
}

.call-record-cell {
  text-align: right;
}

.full-width-detail {
  padding-top: 4px;
}

.full-width-button {
  display: flex;
  justify-content: start;
  padding: 25px 25px 0 25px;
}

.full-width-grid {
  padding: 25px;
  display: block;
  height: calc(100% - 50px) !important;
}

.full-width-grid-toolbar {
  top: 4px;
  left: 30px;
  margin-left: 150px;
  display: block;
  position: absolute;
}

.full-width-phone-icon {
  padding-right: 10px;
}

.full-width-search {
  border: 1px solid #eee;
  margin-left: 10px;
}

.ag-react-container {
  display: inline-block;
  width: 100%;
  height: 100%;
}

We import our component and use it like that

// other imports...
import DetailCellRenderer from './detailCellRenderer.jsx';

const GridExample = () => {
  // column definitions, refs, styles, etc..
  const detailCellRenderer = useMemo(() => {
    return DetailCellRenderer;
  }, []);
  //...

  return (
    <div style={containerStyle}>
      <div className="example-wrapper">
        <div style={gridStyle} className="ag-theme-alpine">
          <AgGridReact
            ref={gridRef}
            rowData={rowData}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            masterDetail={true}
            detailRowHeight={310}
            detailCellRenderer={detailCellRenderer}
            onGridReady={onGridReady}
            onFirstDataRendered={onFirstDataRendered}
          />
        </div>
      </div>
    </div>
  );
}};

This is a quick forked answer to help you. Please get rid of the parts you do not need.

Here's the working plunker: https://plnkr.co/edit/OXRHpR4tca8DvtgA?preview