Issue with cell double-click - reactjs

On reactJS ag-grid, I need to be able to edit a cell on double clicking. I tried the following code. I do not see any error message popping up. But the cell is still read-only.
Am I missing something here please?
Thanks.
function myTest(props)
{
const[gridApi, setGridApi] = userState(null);
...
...
const onCellDoubleClicked = (params) =>
{
gridApi.startEditingCell({rowIndex: params.node.id, colKey: "testField"});
}
const onGridReady = (params) =>
{
setGridApi(params.api);
}
....
...
{headerName:'Test', field:'testField', editable:false};
<AgGridReact columnDefs={...} rowData={...} onCellDoubleClicked=
{onCellDoubleClicked} onGridReady={onGridReady}>
}

Tough to say without seeing your coldef - I'd venture that you need to set the column(s) whose cells you want to be editable to true. See the docs below
Cell Editing

Add editable: true property in your column defs

Related

Triggering a lexical.js mentions menu programatically when clicking on a mention

What I need
Let's start with The mentions plugin taken from the docs.
I would like to enhance if with the following functionality:
Whenever I click on an existing MentionNode, the menu gets rendered (like it does when menuRenderFunction gets called), with the full list of options, regardless of queryString matching
Selecting an option from menu replaces said mention with the newly selected one
Is there a way to implement this while leaving LexicalTypeaheadMenuPlugin in control of the menu?
Thank you for your time 🙏🏻
What I've tried
I figured that maybe I could achieve my desired behaviour simply by returning the right QueryMatch from triggerFn. Something like this:
const x: FC = () => {
const nodeAtSelection = useNodeAtSelection() // Returns LexicalNode at selection
return (
<LexicalTypeaheadMenuPlugin<VariableTypeaheadOption>
triggerFn={(text, editor) => {
if ($isMentionsNode(nodeAtSelection)) {
// No idea how to implement `getQueryMatchForMentionsNode`,
// or whether it's even possible
return getQueryMatchForMentionsNode(nodeAtSelection, text, editor)
}
return checkForVariableBeforeCaret(text, editor)
}}
/>
)
}
I played around with it for about half an hour, unfortunately I couldn't really find any documentation for triggerFn or QueryMatch, and haven't really made any progress just by messing around.
I also thought of a potential solution the I think would work, but feels very hacky and I would prefer not to use it. I'll post it as an answer.
So here is my "dirty" solution that should work, but feels very hacky:
I could basically take the function which I provide to menuRenderFn prop and call it manually.
Let's say I render the plugin like this:
const menuRenderer = (
anchorElementRef,
{ selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }
) => { /* ... */}
return (
<LexicalTypeaheadMenuPlugin menuRenderFn={menuRenderer} /* ... other props */ />
)
I could then create a parallel environment for rendering menuRenderer, something like this:
const useParallelMenu = (
menuRenderer: MenuRenderFn<any>,
allOptions: TypeaheadOption[],
queryString: string
) => {
// I could get anchor element:
// 1. either by using document.querySelector("." + anchorClassName)
// 2. or by extracting it from inside `menuRenderFn`:
// menuRenderFn={(...params) => {
// extractedRef.current = params[0].current;
// return menuRenderer(...params)
// }}
const anchorEl = x
const [selectedIndex, setHighlightedIndex] = useState(0)
const nodeAtSelection = useNodeAtSelection() // Returns LexicalNode at selection
const selectOptionAndCleanUp = (option: TypeaheadOption) => {
// Replace nodeAtSelection with new MentionsNode from `option`
}
return () =>
$isMentionsNode(nodeAtSelection) &&
menuRenderer(
anchorEl,
{
selectedIndex,
setHighlightedIndex,
selectOptionAndCleanUp,
options: allOptions
},
queryString
)
}
On paper, this seems like a viable approach to me... but I would really prefer not to have to do this and instead let LexicalTypeaheadMenuPlugin manage the state of my menu, as it is intended to do.

Ag-grid isRowSelectable conditional not activating

We have an Ag-Grid table with row selection via the built in checkbox functionality. The check boxes are conditionally displaying via the isRowSelectable options:
isRowSelectable: function (rowNode) {
return rowNode.data ? rowNode.data.published === false : true;
}
The published column is being updated as part of a modal called from another column. A redrawRows is being called when the modal is closed:
modal.result.then(() => {
const row = params.api.getDisplayedRowAtIndex(params.rowIndex as number);
//this.gridApi?.redrawRows([row] as any);
this.gridApi?.redrawRows();
});
The display values in the row are being updated when the modal is closed, however, the checkbox is not appearing when the published value is set to false. If I hang a breakpoint in Dev Tools the isRowSelectable code does not appear to be hit.
Any suggestions would be much appreciated.
Cheers,
-John
Can you try this and see if it works?
let itemsToUpdate = [];
let data = rowNode.data;
// modify data fields
// Ex: data.field1 = "new value";
itemsToUpdate.push(data);
this.gridApi.applyTransaction({update: itemsToUpdate});
https://www.ag-grid.com/javascript-data-grid/data-update-transactions/
Use refreshCells
this.gridApi?.refreshCells({force:true});
https://www.ag-grid.com/react-data-grid/view-refresh/#redraw-rows

Move a row to the top/bottom or at any index ag-grid react

I have been trying to move a particular row to the top of the grid, but unable to find any solution. There is a default feature (Dragging row) available in the grid, which is not needed in this case. I have added a button using cell renderer and clicking to that button, the row should move to the top.
{
headerName: "", field: "move",
cellRenderer: (params) => {
let eGui = document.createElement('div');
let imageElement = document.createElement("img");
imageElement.src = moveTopIcon;
eGui.appendChild(imageElement);
eGui.addEventListener('click', e => {
//code to move the row
});
return eGui;
}
}
Here is the column definition where button is placed.
I'm not sure whether AG-Grid has some hook to do that;
But you can achieve using the following approach:
On Click of button : Get the item you have clicked using event handler & Modify the row Data such that it's in top (index =0) . Let me know if this helps.

How to check dynamically rendered checkboxes

I'm rendering some checkboxes dynamically, but currently I'm only able to check the first box, and all other boxes operate the first one. How do I get the boxes to work independently of each other?
This is typescript in React. I've tried changing the interface I'm referencing in the function, thinking I was referencing the wrong thing, but none of those worked.
This is the function:
handleCheckboxClick = (entitlement: IApiEntitlements, checked: boolean): void => {
if (checked === true) {
this.selectedEntitlementIDs.push(entitlement.id);
} else {
const index: number = this.selectedEntitlementIDs.indexOf(entitlement.id);
this.selectedEntitlementIDs.splice(index, 1);
}
//tslint:disable-next-line:prefer-const
let entitlementChecked: IEntitlementChecked = this.state.entitlementChecked;
entitlementChecked[entitlement.id] = checked;
let selectAll: boolean = false;
if (this.selectedEntitlementIDs.length === this.state.responses.apiResponses.apiClients.length) {
selectAll = true;
}
this.setState({
entitlementChecked: entitlementChecked,
selectAll: selectAll
});
console.log(this.selectedEntitlementIDs, 'hi');
console.log(entitlementChecked, 'hello');
}
And this is where it's being called:
return (
<Checkbox
checked={this.state.entitlementChecked[entitlement.id]}
data-ci-key={entitlement.id}
id='api-checkbox'
key={entitlement.id}
labelText={entitlement.label}
onChange={this.handleCheckboxClick}>
</Checkbox>
);
I expect each checkbox to be able to be checked, but currently on the first one works, and all others check or uncheck that first one.
You shouldn't keep an array as a property on the class that keeps track of selected items, this isn't tied to the React lifecycle and could potentially not update the view when you want to. Instead you should just use your map (entitlementChecked) you already have to determine if something is checked or not.
handleCheckboxClick(id) {
this.setState(prevState => ({
entitlementChecked: {
...prevState.entitlementChecked,
[id]: !prevState.entitlementChecked[id]
}
}));
}
When calling the handler method, you can just pass the id through that you need specifically.
onChange={this.handleCheckboxClick.bind(null, item.id)}
Here's a rudimentary example for more detail :)

Check which column has been clicked on rowClick event

I am looking for a way to see which column the rowClick event has happened.
Because based on which column this happend we want other things to happen.
We already got something like this:
this.chart.listen('rowClick', (event) => {
if (event['period'] && event['period'].itemType === GanttItemType.work) {
setTimeout(() => this.clickedDetail(event), 1);
} else if (event['item'] && event['item'].get('technicianId') && !event['period']) {
// HERE WE WANT TO KNOW IN WHICH COLUMN WE ARE
const technicianId = event['item'].get('technicianId');
setTimeout(() => this.openTechnician(technicianId), 1);
} else {
this.preventDef(event);
}
});
Thanks in advance I cannot seem to find if/where this is possible
Unfortunately, there's no out-of-the-box method to implement such functionality, so it requires some tricks.
The idea is quite simple – if dataGrid columns width is predefined we can compare the click X-coordinate and the column width. For details, check the sample by the link provided in the comment below.

Resources