【发布时间】:2012-06-25 19:59:13
【问题描述】:
我采用了this post 的代码并制作了this fiddle。尝试单击第一行,然后按住 shift 单击最后一行。如果你注意到这段代码做得很好,除了最后一行,你点击的那一行,没有被选中。我一直在为此挠头。谁能帮我修改代码,让多选也选择最后一行?
谢谢!
【问题讨论】:
标签: javascript jquery jqgrid multi-select shift
我采用了this post 的代码并制作了this fiddle。尝试单击第一行,然后按住 shift 单击最后一行。如果你注意到这段代码做得很好,除了最后一行,你点击的那一行,没有被选中。我一直在为此挠头。谁能帮我修改代码,让多选也选择最后一行?
谢谢!
【问题讨论】:
标签: javascript jquery jqgrid multi-select shift
尝试用这个替换这个:if ((shouldSelectRow = id == startID || shouldSelectRow)) {:
if ((shouldSelectRow = id == startID || shouldSelectRow) && (id != rowid)){
【讨论】:
我同意 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;
}
【讨论】:
$this.jqGrid('resetSelection') 的调用似乎需要模拟用户知道的相同行为。如果您要选择一些项目,例如在 Windows 中,然后在按下 Shift 或没有 Shift 且没有 Ctrl 的情况下再单击一项,您将看到选择将被重置。无论如何共享代码都是好的,我可以想象选择的不同实现。
正如 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;
}
【讨论】:
添加$('#grid').disableSelection(); 以消除烦人的文本选择
【讨论】:
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;
},
【讨论】: