p:dataTable 中的可拖动行
draggable rows in a p:dataTable by handle
我有一个数据表,我在其中添加了对行的拖放支持 (draggableRows="true")。问题是无论我在一行中单击什么地方,我都可以拖动它。
我想要的是仅通过手柄拖动行的可能性,例如,手柄可以是行左侧带有图标的列字段(查看屏幕截图),因此如果用户点击句柄外的一行,不支持拖动;但如果他点击手柄,他将有可能拖动整行。
我该如何实现?
source is always with you. In there you can see the makeRowsDraggable function on line 2727 in datatable.js
makeRowsDraggable: function() {
var $this = this;
this.tbody.sortable({
placeholder: 'ui-datatable-rowordering ui-state-active',
cursor: 'move',
handle: 'td,span:not(.ui-c)',
appendTo: document.body,
start: function(event, ui) {
ui.helper.css('z-index', ++PrimeFaces.zindex);
},
...
}
引用句柄 ('td, span:not(.ui-c)')。
通过覆盖此函数并使句柄指向明确引用您的句柄的选择器,您可以 'fix' 它。
您甚至可以通过不为句柄分配显式字符串,而是在例如您在放置 'string' 的数据表上定义的自定义传递属性。
我有没有提到 the source 总是和你在一起?有进一步问题时要记住的好事
另一种可能性是在初始化 UI sortable:
后覆盖 Primefaces 的处理程序设置
<script type="text/javascript">
$(document).ready(function() {
var sortableRows = $(".tableWithDraggableRows > tbody");
if (sortableRows) {
sortableRows.sortable("option", "handle", ".ui-icon-arrow-4");
}
});
</script>
我的方案和@Kuketje的方案一样。
这是源代码(兼容 Primefaces 6.1)
if (PrimeFaces.widget.DataTable){
PrimeFaces.widget.DataTable = PrimeFaces.widget.DataTable.extend({
makeRowsDraggable: function () {
var $this = this,
draggableHandle = '.dnd-handle'; //change to what ever selector as you like
this.tbody.sortable({
placeholder: 'ui-datatable-rowordering ui-state-active',
cursor: 'move',
handle: draggableHandle,
appendTo: document.body,
start: function (event, ui) {
ui.helper.css('z-index', ++PrimeFaces.zindex);
},
helper: function (event, ui) {
var cells = ui.children(),
helper = $('<div class="ui-datatable ui-widget"><table><tbody></tbody></table></div>'),
helperRow = ui.clone(),
helperCells = helperRow.children();
for (var i = 0; i < helperCells.length; i++) {
helperCells.eq(i).width(cells.eq(i).width());
}
helperRow.appendTo(helper.find('tbody'));
return helper;
},
update: function (event, ui) {
var fromIndex = ui.item.data('ri'),
toIndex = $this.paginator ? $this.paginator.getFirst() + ui.item.index() : ui.item.index();
$this.syncRowParity();
var options = {
source: $this.id,
process: $this.id,
params: [
{name: $this.id + '_rowreorder', value: true},
{name: $this.id + '_fromIndex', value: fromIndex},
{name: $this.id + '_toIndex', value: toIndex},
{name: this.id + '_skipChildren', value: true}
]
}
if ($this.hasBehavior('rowReorder')) {
$this.cfg.behaviors['rowReorder'].call($this, options);
}
else {
PrimeFaces.ajax.Request.handle(options);
}
},
change: function (event, ui) {
if ($this.cfg.scrollable) {
PrimeFaces.scrollInView($this.scrollBody, ui.placeholder);
}
}
});
}
});
}
Vít Suchánek 的解决方案并没有真正奏效。它仅在页面准备就绪时检测拖放句柄。在第一次拖放交互后,它不再起作用了。
因为 Primefaces 6.2 p:datatable 有一个 属性 rowDragSelector
专门用于此目的。请参阅以下示例:
<p:dataTable value="#{myBean.entities}" id="myTablePreferredId" rowDragSelector=".draggableHandle" draggableRows="true">
<p:ajax event="rowReorder" listener="#{myBean.onRowReorder}"/>
<p:column>
<h:outputText styleClass="fa fa-arrows-v draggableHandle" />
</p:column>
...
</p:dataTable>
有关详细信息,请参阅 primefaces documentation。
我有一个数据表,我在其中添加了对行的拖放支持 (draggableRows="true")。问题是无论我在一行中单击什么地方,我都可以拖动它。
我想要的是仅通过手柄拖动行的可能性,例如,手柄可以是行左侧带有图标的列字段(查看屏幕截图),因此如果用户点击句柄外的一行,不支持拖动;但如果他点击手柄,他将有可能拖动整行。
我该如何实现?
source is always with you. In there you can see the makeRowsDraggable function on line 2727 in datatable.js
makeRowsDraggable: function() {
var $this = this;
this.tbody.sortable({
placeholder: 'ui-datatable-rowordering ui-state-active',
cursor: 'move',
handle: 'td,span:not(.ui-c)',
appendTo: document.body,
start: function(event, ui) {
ui.helper.css('z-index', ++PrimeFaces.zindex);
},
...
}
引用句柄 ('td, span:not(.ui-c)')。
通过覆盖此函数并使句柄指向明确引用您的句柄的选择器,您可以 'fix' 它。
您甚至可以通过不为句柄分配显式字符串,而是在例如您在放置 'string' 的数据表上定义的自定义传递属性。
我有没有提到 the source 总是和你在一起?有进一步问题时要记住的好事
另一种可能性是在初始化 UI sortable:
后覆盖 Primefaces 的处理程序设置 <script type="text/javascript">
$(document).ready(function() {
var sortableRows = $(".tableWithDraggableRows > tbody");
if (sortableRows) {
sortableRows.sortable("option", "handle", ".ui-icon-arrow-4");
}
});
</script>
我的方案和@Kuketje的方案一样。 这是源代码(兼容 Primefaces 6.1)
if (PrimeFaces.widget.DataTable){
PrimeFaces.widget.DataTable = PrimeFaces.widget.DataTable.extend({
makeRowsDraggable: function () {
var $this = this,
draggableHandle = '.dnd-handle'; //change to what ever selector as you like
this.tbody.sortable({
placeholder: 'ui-datatable-rowordering ui-state-active',
cursor: 'move',
handle: draggableHandle,
appendTo: document.body,
start: function (event, ui) {
ui.helper.css('z-index', ++PrimeFaces.zindex);
},
helper: function (event, ui) {
var cells = ui.children(),
helper = $('<div class="ui-datatable ui-widget"><table><tbody></tbody></table></div>'),
helperRow = ui.clone(),
helperCells = helperRow.children();
for (var i = 0; i < helperCells.length; i++) {
helperCells.eq(i).width(cells.eq(i).width());
}
helperRow.appendTo(helper.find('tbody'));
return helper;
},
update: function (event, ui) {
var fromIndex = ui.item.data('ri'),
toIndex = $this.paginator ? $this.paginator.getFirst() + ui.item.index() : ui.item.index();
$this.syncRowParity();
var options = {
source: $this.id,
process: $this.id,
params: [
{name: $this.id + '_rowreorder', value: true},
{name: $this.id + '_fromIndex', value: fromIndex},
{name: $this.id + '_toIndex', value: toIndex},
{name: this.id + '_skipChildren', value: true}
]
}
if ($this.hasBehavior('rowReorder')) {
$this.cfg.behaviors['rowReorder'].call($this, options);
}
else {
PrimeFaces.ajax.Request.handle(options);
}
},
change: function (event, ui) {
if ($this.cfg.scrollable) {
PrimeFaces.scrollInView($this.scrollBody, ui.placeholder);
}
}
});
}
});
}
Vít Suchánek 的解决方案并没有真正奏效。它仅在页面准备就绪时检测拖放句柄。在第一次拖放交互后,它不再起作用了。
因为 Primefaces 6.2 p:datatable 有一个 属性 rowDragSelector
专门用于此目的。请参阅以下示例:
<p:dataTable value="#{myBean.entities}" id="myTablePreferredId" rowDragSelector=".draggableHandle" draggableRows="true">
<p:ajax event="rowReorder" listener="#{myBean.onRowReorder}"/>
<p:column>
<h:outputText styleClass="fa fa-arrows-v draggableHandle" />
</p:column>
...
</p:dataTable>
有关详细信息,请参阅 primefaces documentation。