vaadin / web-components

A set of high-quality standards based web components for enterprise web applications. Part of Vaadin 20+
https://vaadin.com/docs/latest/components
452 stars 83 forks source link

[grid] Select multiple rows with ctrl/cmd-click or shift-click #2041

Open caribouflex opened 7 years ago

caribouflex commented 7 years ago

It would be a nice feature to handle the ctrl/cmd+click on a row for the multiple selection, instead of using the checkbox. The auto-select attribute can make this useless, but the best use case would be when the auto-select attribute is not present, to always select the row on click cell (one only selected), but allow the multiple selection with the ctrl/cmd+click cell and the checkbox selection.

jouni commented 7 years ago

As shift-click is closely related to this, I added that in the title. So shift-click should select all rows between the previously activated row and the one newly clicked/activated row.

jouni commented 7 years ago

I suppose this should be a separate feature that can be enabled on it’s own, and not part of <vaadin-grid-selection-column>, so it can be used independently as well?

Should we add this information (cmd/ctrl or shift keys being pressed and the previous active item) to the active-item-changed event, and add a default implementation in <vaadin-grid-selection-column> based on that?

but the best use case would be when the auto-select attribute is not present, to always select the row on click cell (one only selected), but allow the multiple selection with the ctrl/cmd+click cell and the checkbox selection.

I’m preliminary in favor of this change, but I think we need to gather some more opinions and do some research before we do it.

caribouflex commented 7 years ago

I agree for the shift-click, but this is two different use, with the same purpose of multi-selection at the end.

It could be a good idea to be a separate feature and have a default implementation in the <vaadin-grid-selection-column>.

A custom property as the keyBindings could be cool, where we can define 'ctrl+click' or 'shift+click' to fire an event. This maybe can a new behavior that mix the two behaviors vaadin-grid-cell-click-behavior.html and vaadin-grid-keyboard-navigation-behavior.html that listen for the separate keyboard and click event.

jouni commented 7 years ago

As @caribouflex hinted, this can actually work for keyboard users as well, so that Shift + Space would add the rows between the previous active item and the new active item to the selection. Having the modifier-key info in the active-item-changed event would cover this use case as well, right?

ea-ncu commented 6 years ago

Hi,

I am new to polymer and web development. I have written a few dirty methods that can implement ctrl click and shift click selection on vaadin grid.

Firstly, your vaadin-grid needs the following properties: active-item, and on-click. `

` activeItem needs an observer: `activeItem : { observer : '_activeItemChanged' },` And here are the following methods ```javascript _activeItemChanged : function(item) { this.itemClicked = true; if (item !== null) { this.selectedItem = item; } }, checkItems : function(event) { event.preventDefault(); if (this.itemClicked === true) { if (event.shiftKey === true && this.selectedItem !== null && this.initItem !== null) { this._getMultiSelected(this.initItem, this.selectedItem); } else if (event.ctrlKey === true) { this.initItem = this.selectedItem; this._addCtrlSelected(this.selectedItem); } else { this.initItem = this.selectedItem; if (this.$.grid.selectedItems.includes(this.selectedItem)) { this.$.grid.selectedItems = []; } else { this.$.grid.selectedItems = [ this.selectedItem ]; } } this._sendEventWithItems(); } this.itemClicked = false; }, _getMultiSelected : function(firstItem, secondItem) { var list = this.$.grid.items; var firstIndex = list.indexOf(firstItem); var secondIndex = list.indexOf(secondItem); var min = Math.min(firstIndex, secondIndex); var max = Math.max(firstIndex, secondIndex); var selectedlist = []; for (let i = min; i <= max; i++) { selectedlist.push(list[i]); } this.$.grid.selectedItems = selectedlist; }, _addCtrlSelected : function(firstItem) { var list = this.$.grid.items; var firstIndex = list.indexOf(firstItem); var spliceIndex = this.$.grid.selectedItems.indexOf(firstItem); var selectedlist = this.$.grid.selectedItems; if (selectedlist.includes(list[firstIndex])) { selectedlist.splice(spliceIndex, 1); } else { selectedlist.push(list[firstIndex]); } this.$.grid.selectedItems = selectedlist.filter(onlyUnique); }, ``` I am sure that there is a more polymer-friendly implementation, and I would welcome the feedback :)
tomivirkki commented 6 years ago

Here's an example on how this could be implemented with help of activeItem https://glitch.com/edit/#!/vigorous-stream

hari2m commented 4 years ago

Are there any plans on implementing this?

jcgueriaud1 commented 3 years ago

There is an add-on for the Java API here. https://vaadin.com/directory/component/selection-grid