【问题标题】:SHift-click jqgrid multiselect missing last rowSHIFT-单击 jqgrid 多选缺少最后一行
【发布时间】:2012-06-25 19:59:13
【问题描述】:

我采用了this post 的代码并制作了this fiddle。尝试单击第一行,然后按住 shift 单击最后一行。如果你注意到这段代码做得很好,除了最后一行,你点击的那一行,没有被选中。我一直在为此挠头。谁能帮我修改代码,让多选也选择最后一行?

谢谢!

【问题讨论】:

    标签: javascript jquery jqgrid multi-select shift


    【解决方案1】:

    尝试用这个替换这个:if ((shouldSelectRow = id == startID || shouldSelectRow)) {

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

    【讨论】:

      【解决方案2】:

      我同意 Michael Gendin 的观点,即您不应选择 id 等于 rowid 的行。这是你的主要错误。不过,我会重写演示的大部分代码以使用行的 DOM 元素的rowIndex,而不是枚举网格的所有行。此外,在您当前的代码中,在 IE 中选择文本并不方便,因此我建议您将其删除。你在here找到的修改后的demo我使用了beforeSelectRow回调的如下代码:

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

      【讨论】:

      • Oleg 的解决方案适用于我的 Safari 和 IE8 设置。如果其他人出于与我相同的原因正在查看此内容,如果您想要附加选择,则需要进行以下调整(移位选择一个块,然后另一个不清除选择):1)删除对 $ 的两个调用this.jqGrid('resetSelection') 不清除现有选择。 2) 调用 $this.jqGrid('getGridParam','selarrrow');要获取所选索引的数组,并在测试中切换选择,还要检查 rows[i].id 是否不在您的现有选择数组中。
      • @Kelly:如果您只是在答案中添加代码会很好。我可以想象这个问题对其他人来说可能很有趣。在我看来,$this.jqGrid('resetSelection') 的调用似乎需要模拟用户知道的相同行为。如果您要选择一些项目,例如在 Windows 中,然后在按下 Shift 或没有 Shift 且没有 Ctrl 的情况下再单击一项,您将看到选择将被重置。无论如何共享代码都是好的,我可以想象选择的不同实现。
      【解决方案3】:

      正如 Oleg 的回答中所讨论的,这是一个调整后的 beforeSelectRow,它执行附加的选择。

      在我的例子中,我们的用户选择了一堆要导出的行,所以额外的选择通常并不意味着他们想要开始一个新的选择。

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

      【讨论】:

        【解决方案4】:

        添加$('#grid').disableSelection(); 以消除烦人的文本选择

        【讨论】:

          【解决方案5】:

          Oleg 的解决方案不适用于所有选择模式(上/下)。感谢他的部分解决方案。

          我用这段代码纠正了这个问题:

          您需要 2 个变量来存储当前的起始行 ID 和结束行 ID。 还有一个用于存储选择的一侧。

          var _currentStartSelectRow, _currentEndSelectRow, _isSideDown = null;
          

          beforeSelectRow 回调的代码调用:

          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;
                      }, 
          

          【讨论】:

            猜你喜欢
            • 2016-04-25
            • 2020-01-21
            • 2019-08-11
            • 1970-01-01
            • 2013-07-31
            • 2019-04-02
            • 2017-06-16
            • 1970-01-01
            • 2013-08-19
            相关资源
            最近更新 更多