disableVisualSelection not working as expected

Tags: #<Tag:0x00007efc606c6750>

I have found out some issues regarding disableVisualSelection for some rows only.

My goal was to disable selection of the first row for the user (which act as a header but that is not important I think)

var hot = new Handsontable(container, {
  data: data(),
  minSpareCols: 1,
  minSpareRows: 1,
  rowHeaders: true,
  colHeaders: true,
  contextMenu: true,
  cells:(row, column)=>{
  		if(row==0){
      	return {
        	disableVisualSelection: true,
        }
      }
      return {};
  }
});

http://jsfiddle.net/9j6rn4uh/

Issues:

  1. Right click on any > 0 row on -1 column works as intended BUT if you right click -1,-1 (the very corner) whole table will be logically selected but selection is not shown. Therefore right clicking on any other of rows will not select those rows but rather display context menu for whole table.
    I assume that whole table is selected because it is shown like this if I reenable visual selection. I have to left click somewhere to make it work again - it is very confusing for the users (and was even for me) especially if context menu content is based on row selection (my real case)

  2. I cannot left/right click select the first row as intended, BUT I can actually click any row > 1 and shift click row 0 to select it which should be forbidden :wink:

Hi @sebastian.choina

I have to say that, this is a great finding. Generally, the disableVisualSelection is considered as a global options (only on the table) level. But let me work on that a little. I will update this subject after the weekend.

Hi @sebastian.choina

I wanted to update you on the subject. We had a discussion over the cell meta properties and their use within different table structures (table > column / row > cell) and the following option disableVisualSelection was never intended to work in a lower structure. It was dedicated and tested to work only on the table level.

We also came to the conclusion that it is not clear what are the intended places for the options. That is why we are preparing a tutorial, to sum up all options and specify their destination of use. Thank you for being our motivation to create this tutorial.

When it comes to the subject of blocking operation for given coordinates I can share some ideas. I would just need to know if you plan to block mouse, keys or both types of events.

Hi @aleksandra_budnik

the general idea here is to have first row to act as a header row for the table. This is because spreadsheet LAF is still required therfore columns A,B,C… are to be ther. Maybe I should simply use different approach to have kind of 2 row column header, but it must also support comments (as I provide validation tips etc). This is why I try to use first row as header - as I need some of cell specific features.

What I need here is actually be able to block every action on the first row - selection, removal, modification etc. All user interaction options should be disabled for that row.

I understand. If you want to treat the first row and the headers you need to block

  • mouse events via beforeOnCellMouseDown
  • keyboard events via beforeKeyDown

Ok so basically I have to check for that special row being a part of selection and potentially remove it from selection range by hand.

Now while I’m thinking about it you have two approaches.

You can block the key events if they would end up selecting the cell in the first row via getSelected() method to spot what cell is selected before using the key and returning event.stopImmediatePropagation() to block the movement. And with the mouse events, it is the same, but the event already shares the information about the coordinates so it’s just

  beforeOnCellMouseDown: function(e, coords) {
    if(coords.row === 0){
    	e.stopImmediatePropagation()
    }
  }

The second approach is to (as you mentioned) use the afterSelectionEnd to check if the first row is in the range and if it is

  • remove the selection
  • reapply the selection without the first row

Personally, I would recommend the first approach because you are really blocking those operations and you avoid the rerendering of the table when selection changes.

I will try your proposal. At first glance it will probably not cover (-1,-1) click that selects complete table nor drag selection going from bottom up. I think that “reapply the selection without the first row” is more generic and should cover selections done via keyboard as well. Am I right here?

The mouseDown event is also able to tell if you click a header along with the (-1, -1) element that selects all of the cells. Demo https://jsfiddle.net/80tpgLnd/3/
But yes, you are right - the selection way would work for any selection made (by mouse, keyboard, or the one done programmatically) they all are registered by the afterSelectionEnd hook.