primereact icon indicating copy to clipboard operation
primereact copied to clipboard

Datatable context menu and selection blend

Open flash4174 opened this issue 2 years ago • 17 comments

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

flash4174 avatar Oct 24 '23 09:10 flash4174

@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?

melloware avatar Oct 24 '23 11:10 melloware

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)}

flash4174 avatar Oct 24 '23 12:10 flash4174

Can you create a StackBlitz reproducer so I can try it?

melloware avatar Oct 24 '23 12:10 melloware

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.

github-actions[bot] avatar Oct 24 '23 12:10 github-actions[bot]

codesandbox

right click on a row and view => everything is fine Left click on a row then right click on another row => no data

flash4174 avatar Oct 24 '23 13:10 flash4174

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?

melloware avatar Oct 24 '23 13:10 melloware

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

flash4174 avatar Oct 24 '23 13:10 flash4174

oh ok let me look.

melloware avatar Oct 24 '23 13:10 melloware

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.

melloware avatar Oct 24 '23 14:10 melloware

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

flash4174 avatar Oct 24 '23 14:10 flash4174

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.

melloware avatar Oct 24 '23 14:10 melloware

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

flash4174 avatar Oct 24 '23 14:10 flash4174

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.

rafalwojdowski avatar Nov 07 '23 14:11 rafalwojdowski

@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:

  1. If no records are selected in the grid, right-click any record and click View. This results in an exception because ViewProduct expects products to be an array, but in this case it is an object.
  2. 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, ViewProduct does get the products as 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.

xryanwilson avatar Nov 07 '23 21:11 xryanwilson

Switched to bug.

melloware avatar Nov 07 '23 21:11 melloware

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 onContextMenu and onContextMenuSelectionChange?
  • What is the point of having contextMenuSelection at 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?

rayman-de avatar Nov 23 '23 13:11 rayman-de

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.

rayman-de avatar Nov 23 '23 14:11 rayman-de

Fixed with https://github.com/primefaces/primereact/pull/6403

melloware avatar Apr 17 '24 12:04 melloware