SHift-click jqgrid multiselect missing last row

心已入冬 提交于 2019-12-05 16:12:15

try replacing this: if ((shouldSelectRow = id == startID || shouldSelectRow)) { with this:

if ((shouldSelectRow = id == startID || shouldSelectRow) && (id != rowid)){
Oleg

I agree with Michael Gendin that you should not select the row with the id equal to rowid. It's your main error. Nevertheless I would rewrite the most code of the demo to use rowIndex of DOM elements of the rows instead of enumerating of all rows of the grid. Additionally the selection of the text in IE is uncomfortable in your current code, so I would suggest removing it. The modified demo which you find here I used the following code of beforeSelectRow callback:

beforeSelectRow: function (rowid, e) {
    var $this = $(this), rows = this.rows,
        // get id of the previous selected row
        startId = $this.jqGrid('getGridParam', 'selrow'),
        startRow, endRow, iStart, iEnd, i, rowidIndex;

    if (!e.ctrlKey && !e.shiftKey) {
        $this.jqGrid('resetSelection');
    } else if (startId && e.shiftKey) {
        $this.jqGrid('resetSelection');

        // get DOM elements of the previous selected and the currect selected rows
        startRow = rows.namedItem(startId);
        endRow = rows.namedItem(rowid);
        if (startRow && endRow) {
            // get min and max from the indexes of the previous selected
            // and the currect selected rows 
            iStart = Math.min(startRow.rowIndex, endRow.rowIndex);
            rowidIndex = endRow.rowIndex;
            iEnd = Math.max(startRow.rowIndex, rowidIndex);
            for (i = iStart; i <= iEnd; i++) {
                // the row with rowid will be selected by jqGrid, so:
                if (i != rowidIndex) {
                    $this.jqGrid('setSelection', rows[i].id, false);
                }
            }
        }

        // clear text selection
        if(document.selection && document.selection.empty) {
            document.selection.empty();
        } else if(window.getSelection) {
            window.getSelection().removeAllRanges();
        }
    }
    return true;
}

Add $('#grid').disableSelection(); to remove the annoying text selection

As discussed in Oleg's answer, here is an adjusted beforeSelectRow that does appended selections.

In my case, our users are selecting a bunch of rows for export, so additional selections does not usually mean they want to start a new selection.

 beforeSelectRow: function(rowid, e) {
      var $this = $(this), rows = this.rows,

      // get id of the previous selected row
      startId = $this.jqGrid('getGridParam', 'selrow'),
      startRow, endRow, iStart, iEnd, i, rowidIndex;

      if (!e.ctrlKey && !e.shiftKey) {
          //intentionally left here to show differences with
          //Oleg's solution. Just have normal behavior instead.
          //$this.jqGrid('resetSelection');
      } else if (startId && e.shiftKey) {
          //Do not clear existing selections
          //$this.jqGrid('resetSelection');

          // get DOM elements of the previous selected and
          // the currect selected rows
          startRow = rows.namedItem(startId);
          endRow = rows.namedItem(rowid);

          if (startRow && endRow) {
              // get min and max from the indexes of the previous selected
              // and the currect selected rows
              iStart = Math.min(startRow.rowIndex, endRow.rowIndex);
              rowidIndex = endRow.rowIndex;
              iEnd = Math.max(startRow.rowIndex, rowidIndex);

              // get the rowids of selected rows
              var selected = $this.jqGrid('getGridParam','selarrrow');

              for (i = iStart; i <= iEnd; i++) {
                  // if this row isn't selected, then toggle it.
                  // jqgrid will select the clicked on row, so just ingore it.
                  // note that we still go <= iEnd because we don't know which is start or end.
                  if(selected.indexOf(rows[i].id) < 0 && i != rowidIndex) {
                    // true is to trigger onSelectRow event, which you may not need
                    $this.jqGrid('setSelection', rows[i].id, true);
                  }
              }
          }

          // clear text selection (needed in IE)
          if(document.selection && document.selection.empty) {
              document.selection.empty();
          } else if(window.getSelection) {
              window.getSelection().removeAllRanges();
          }
      }
      return true;
  }

The solution of Oleg is not working in all selection mode (up/down). Thanks to him for the partial solution.

I correct this with this code:

You need 2 variables for stored the current start row Id and end row Id. And an other one to store the side of the selection.

var _currentStartSelectRow, _currentEndSelectRow, _isSideDown = null;

Code call by the beforeSelectRow callback:

beforeSelectRow: function (rowid, e) {
                var $this = $(this), rows = this.rows,
                // get id of the previous selected row
                previousId = $this.jqGrid('getGridParam', 'selrow'),
                previousRow, currentRow;

                if (!e.ctrlKey && !e.shiftKey) {
                    _isSideDown = null;                       
                        $this.jqGrid('resetSelection');                       

                } else if (previousId && e.shiftKey) {
                    $this.jqGrid('resetSelection');


                    // get DOM elements of the previous selected and the currect selected rows
                    previousRow = rows.namedItem(previousId);
                    currentRow = rows.namedItem(rowid);
                    if (previousRow && currentRow) {
                        //Increment
                        if (previousRow.rowIndex < currentRow.rowIndex) {
                            if (_isSideDown == false || _isSideDown == null) {
                                _currentStartSelectRow = previousRow.rowIndex;
                                _currentEndSelectRow = currentRow.rowIndex;
                            }
                            else {
                                _currentEndSelectRow = currentRow.rowIndex;
                            }
                            _isSideDown = true;
                        }
                        //Decrement
                        else {
                            if (_isSideDown == null) {
                                _currentStartSelectRow = currentRow.rowIndex;
                                _currentEndSelectRow = previousRow.rowIndex;
                                _isSideDown = false;
                            }
                            else if (_isSideDown == true) {
                                if (currentRow.rowIndex < _currentStartSelectRow) {
                                    _currentStartSelectRow = currentRow.rowIndex;
                                    _isSideDown = false;
                                }
                                else {
                                    _currentEndSelectRow = currentRow.rowIndex;
                                }
                            }
                            else {
                                _currentStartSelectRow = currentRow.rowIndex;
                            }

                        }

                        for (i = _currentStartSelectRow; i <= _currentEndSelectRow; i++) {
                            // the row with rowid will be selected by jqGrid, so we don't need to select him:
                            if (i != currentRow.rowIndex) {
                                $this.jqGrid('setSelection', rows[i].id, false);
                            }
                        }
                    }

                }
                return true;
            }, 
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!