-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add single click boolean checkbox (#484)
* Update libs, add boolean checkbox
- Loading branch information
1 parent
d701db5
commit 3b527ff
Showing
24 changed files
with
2,705 additions
and
4,984 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { CellClickedEvent } from "ag-grid-community"; | ||
|
||
/** | ||
* AgGrid checkbox select does not pass clicks within cell but not on the checkbox to checkbox. | ||
* This passes the event to the checkbox when you click anywhere in the cell. | ||
*/ | ||
export const clickInputWhenContainingCellClicked = ({ data, event, colDef }: CellClickedEvent) => { | ||
if (!data || !event) return; | ||
|
||
const element = event.target as Element; | ||
// Already handled | ||
if (["BUTTON", "INPUT"].includes(element?.tagName) && element.closest(".ag-cell-inline-editing")) return; | ||
|
||
const row = element.closest("[row-id]"); | ||
if (!row) return; | ||
|
||
const colId = colDef.colId; | ||
if (!colId) return; | ||
|
||
const clickInput = (cnt: number) => { | ||
const cell = row.querySelector(`[col-id='${colId}']`); | ||
if (!cell) return; | ||
|
||
const input = cell.querySelector("input, button"); | ||
if (!input) { | ||
return; | ||
} | ||
// When clicking on a cell that is not editing, the cell changes to editing and the input/button ref becomes invalid | ||
// So wait until the cell is in edit mode before sending the click | ||
if (!input.ownerDocument.contains(input)) { | ||
if (cnt !== 0) { | ||
setTimeout(() => clickInput(cnt - 1)); | ||
} | ||
return; | ||
} | ||
input?.dispatchEvent(event); | ||
}; | ||
|
||
setTimeout(() => clickInput(20), 10); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import { CellFocusedEvent } from "ag-grid-community"; | ||
import { CellEditorCommon, ColDefT, GridCell } from "../GridCell"; | ||
import { useEffect, useRef } from "react"; | ||
import { fnOrVar } from "../../utils/util"; | ||
import clsx from "clsx"; | ||
import { GenericCellColDef } from "../gridRender"; | ||
import { GridBaseRow } from "../Grid"; | ||
import { CustomCellEditorProps } from "ag-grid-react"; | ||
import { clickInputWhenContainingCellClicked } from "../clickInputWhenContainingCellClicked"; | ||
|
||
const BooleanCellRenderer = (props: CustomCellEditorProps) => { | ||
const { onValueChange, value, api, node, column, colDef, data } = props; | ||
const inputRef = useRef<HTMLInputElement>(null); | ||
|
||
useEffect(() => { | ||
const checkFocus = (event: CellFocusedEvent) => { | ||
if (event.rowIndex === node.rowIndex && event.column === column) { | ||
inputRef.current?.focus(); | ||
} | ||
}; | ||
api.addEventListener("cellFocused", checkFocus); | ||
return () => { | ||
api.removeEventListener("cellFocused", checkFocus); | ||
}; | ||
}, [api, column, node.rowIndex]); | ||
|
||
return ( | ||
<div className={clsx("ag-wrapper ag-input-wrapper ag-checkbox-input-wrapper", { "ag-checked": props.value })}> | ||
<input | ||
type="checkbox" | ||
className="ag-input-field-input ag-checkbox-input" | ||
disabled={!fnOrVar(colDef?.editable, props)} | ||
ref={inputRef} | ||
checked={value} | ||
onChange={() => {}} | ||
onClick={(e) => { | ||
e.stopPropagation(); | ||
// cell has to be in edit mode | ||
// if in non-edit mode clickInputWhenContainingCellClicked will click to put it in edit mode | ||
if (!onValueChange) return; | ||
const params = props?.colDef?.cellEditorParams as GridEditBooleanEditorProps<any> | undefined; | ||
if (!params) return; | ||
const selectedRows = [data]; | ||
const checked = !value; | ||
onValueChange(checked); | ||
params.onClick({ selectedRows, selectedRowIds: selectedRows.map((r) => r.id), checked }).then(); | ||
}} | ||
/> | ||
</div> | ||
); | ||
}; | ||
|
||
export interface GridEditBooleanEditorProps<TData> extends CellEditorCommon { | ||
onClick: (props: { | ||
selectedRows: TData[]; | ||
selectedRowIds: (string | number)[]; | ||
checked: boolean; | ||
}) => Promise<boolean>; | ||
} | ||
|
||
export const GridEditBoolean = <TData extends GridBaseRow>( | ||
colDef: GenericCellColDef<TData, boolean>, | ||
editorProps: GridEditBooleanEditorProps<TData>, | ||
): ColDefT<TData> => { | ||
return GridCell({ | ||
minWidth: 64, | ||
maxWidth: 64, | ||
cellRenderer: BooleanCellRenderer as any, | ||
cellEditor: BooleanCellRenderer, | ||
cellEditorParams: editorProps, | ||
onCellClicked: clickInputWhenContainingCellClicked, | ||
singleClickEdit: true, | ||
resizable: false, | ||
editable: true, | ||
cellClass: "GridCellAlignCenter", | ||
headerClass: "GridHeaderAlignCenter", | ||
...colDef, | ||
}); | ||
}; |
Oops, something went wrong.