primereact
primereact copied to clipboard
Datatable context menu and selection blend
Describe the bug
Hi There,
My problem is that I’m using Datatable with the checkbox selection function and with contextmenu too, but when I select multiple lines with the checkbox the contextmenu selection state is populated with the row selection content.
My aim is to be able to select multiple rows with left click, but when on righ click the context menu shows an ‘open’ menu item an on click it opens up a modal with the single row details that is click with the right mouse button.
It work fine until I select multiple lines with left click and then right click on a line, because the state contain all the selected rows.
i use different state (react usestate) for the selection and onContectMenuSelection props
Reproducer
No response
PrimeReact version
10.0.4
React version
18.x
Language
ES6
Build / Runtime
Next.js
Browser(s)
Chrome
Steps to reproduce the behavior
No response
Expected behavior
No response
@flash but can't you just use onContextMenuSelectionChange={(e) => setSelectedProduct(e.value)} and set your selection to the already selected values? So that way the right click will leave all your left click selected items as is?
No, because that way it’s just add to the selection like with left click and sends no data. My latest attempt like:
selection={selectedProducts}
onSelectionChange={(e) => setSelectedProducts(e.value)}
contextMenuSelection={selectedContext}
onContextMenuSelectionChange={(e) => setSelectedContext(e.value)}
Can you create a StackBlitz reproducer so I can try it?
Please fork the CodeSandbox project or Stackblitz project and create a case demonstrating your bug report. This issue will be closed if no activities in 20 days.
right click on a row and view => everything is fine Left click on a row then right click on another row => no data
OK it looks like its working? I CTRL+LEFTCLICK 3 items then I right click and the ContextMenu is displayed and the 3 items remain selected?
Yes, but on the toast where the product name should be seen nothing is appear
it’s because the selectedContext state has the same items as the selectedProducts instead of change the selectedContext value it adds to the array
oh ok let me look.
Its fixed: https://codesandbox.io/s/primereact-demo-forked-67nzvk?file=/src/App.js
Your ViewProduct was viewing an Array but thinking it was 1 item so product.name is always blank.
Well, I would like to fully separate the left and right click.
For example the first 3 rows selected with left click and when I right click on the forth row the toast should only show the fourth product name and the left click selection must keep
Oh that is an odd UI/UX paradigm. The right click should work on the Selected rows. To me that would violate Principal Of Least Surprise when it comes to what a "user expects" to happen.
I see. The functionallity would be like you select the necessary rows and if you would like to check one if it has to be selected the you right click on it and click view (open a modal with the product details) and if needed then you close it and select with left click
Datatable version 9.6.2 worked as described by @flash417. Unfortunately, as of version 10 this has stopped working. Users are used to the context menu and selection blend, which is definitely more convenient. I would appreciate the implementation of this issue in version 10.0.10 or next.
@melloware - I believe this should be a Bug, not an Enhancement. The behavior of the onContextMenuSelectionChange callback is inconsistent, and a breaking change relative to v9.6.2.
Using the sandbox you provided (https://codesandbox.io/s/primereact-demo-forked-67nzvk?file=/src/App.js), I see the following issues:
- If no records are selected in the grid, right-click any record and click View. This results in an exception because
ViewProductexpectsproductsto be an array, but in this case it is an object. - Select one or more records in the grid. Right-click a different record (one that was not previously selected), and click View. In this case,
ViewProductdoes get theproductsas an array as expected. However, the toast displays the previously selected record(s), and not the record that was right-clicked.
In v9.6.2, right-clicking a record always passed the right-clicked record data with the onContextMenuSelectionChange event. As of v10.0.2, the right-clicked record data is not available on the event unless it was already selected in the grid prior to triggering the context menu.
Switched to bug.
The bug seems to come from onRowRightClick in TableBody.js. I have a couple of questions:
- Can that callback be exposed as prop of DataTable?
- What was supposed to be the difference between
onContextMenuandonContextMenuSelectionChange? - What is the point of having
contextMenuSelectionat the moment? - How can a dev properly change the
contextMenuSelection(and why should they) if they cannot access the row that has been right-clicked on?
For those looking for a work-around until this is fixed/changed:
You can keep the row that is hovered over with the mouse in a ref by using onRowMouseEnter (and also onRowMouseLeave if you want) and then using that row in onContextMenuSelectionChange instead of the actual argument passed to it.
Fixed with https://github.com/primefaces/primereact/pull/6403