有p:dataTable
与一列p:inputText
:
<h:form id="form">
<p:dataTable id="dataTable" value="#{rowReorder.dataList}"
var="row" draggableRows="true" rowKey="#{row.id}">
<p:ajax event="rowReorder" listener="#{rowReorder.reorder}" update="dataTable"/>
<p:column>
<f:facet name="header">
<p:commandButton value="Add" actionListener="#{rowReorder.addData}"
update="dataTable" process="dataTable"/>
</f:facet>
<p:outputLabel value="#{row.id}"/>
</p:column>
<p:column>
<p:inputText value="#{row.name}"/>
</p:column>
</p:dataTable>
</h:form>
支持bean:
import org.omnifaces.cdi.ViewScoped;
import org.primefaces.event.ReorderEvent;
import javax.inject.Named;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
@Named("rowReorder")
@ViewScoped
public class RowReorder implements Serializable {
private List<Data> dataList = new LinkedList<>();
public void addData() {
Data data = new Data();
data.setId(dataList.size() + 1);
data.setName("Data " + data.getId());
dataList.add(data);
}
public void reorder(ReorderEvent event) {
}
/**
* Getters, Setters
*/
public List<Data> getDataList() {
return dataList;
}
}
数据类:
public class Data implements Serializable {
private Integer id;
private String name;
/**
* Getters, Setters
*/
}
重排前的样品数据表:
--------------
|id | name |
--------------
| 1 | Data 1 |
| 2 | Data 2 |
| 3 | Data 3 |
| 4 | Data 4 |
--------------
和重新排序后(移动1-ST行至3-RD):
--------------
|id | name |
--------------
| 2 | Data 1 |
| 3 | Data 2 |
| 1 | Data 3 |
| 4 | Data 4 |
--------------
据我所知,这是发生在“阶段p:inputText
从设置UPDATE_MODEL
的数据的原因。我试图在process="@none"
部件确定p:ajax
防止输入字段的处理,但它不能正常工作。有什么想法如何使draggableRows
和p:inputText
朋友?
我找到了解决办法!它不处理输入(实际上没有提交它在所有)与属性process="@none" partialSubmit="true"
因此,完整的电话号码:Ajax组件看起来像<p:ajax event="rowReorder" listener="#{rowReorder.reorder}" update="dataTable" process="@none" partialSubmit="true"/>
让我们看看是什么在拖行发生了什么?我们有Ajax请求强制process="form:dataTable"
。上APPLY_REQUEST_VALUES相DataTableRenderer
试图调用DraggableRowsFeature
的解码,这反过来,旋转列表元素(列表指定为DataTable的值属性)。因此,对UPDATE_MODEL_VALUES阶段,我们有一个旋转的列表,并输入组件,其中机要提交它们的值name
Data
对象的领域。但请求参数仍然包含在输入IDS旧行指标:他们是form:dataTable:1:name = Data 2
,form:dataTable:2:name = Data 3
,form:dataTable:0:name = Data 1
(我加3排,并移动第一行到最后一个)。所以在这里我们得到什么,我们得到了。这样,如果我们需要的数据要在我们必须避免我们的名单UPDATE_MODEL_VALUES之前转动做,后来就INVOKE_APPLICATION阶段执行此旋转,并呈现对Ajax请求的dataTable正确的地点提交:
在DraggableRowsFeature.decode()
我们可以看到,Collections.rotate()
只有当调用值列表的实例。
if (value instanceof List) {
List list = (List) value;
if(toIndex >= fromIndex) {
Collections.rotate(list.subList(fromIndex, toIndex + 1), -1);
}
else {
Collections.rotate(list.subList(toIndex, fromIndex + 1), 1);
}
}
else {
LOGGER.info("Row reordering is only available for list backed datatables, use rowReorder ajax behavior with listener for manual handling of model update.");
}
也有DraggableRowsFeature.shouldDecode()
方法。
public boolean shouldDecode(FacesContext context, DataTable table) {
return context.getExternalContext().getRequestParameterMap().containsKey(table.getClientId(context) + "_rowreorder");
}
所以在这里我们有2种可能性,以防止数据源旋转:
List
为dataTable的值org.primefaces.component.datatable.feature.DraggableRowsFeature
返回在shouldDecode()
方法错误。我修改Bean文件是这样的:
@Named("rowReorder")
@ViewScoped
public class RowReorder implements Serializable {
private static final Logger log = LoggerFactory.getLogger(RowReorder.class);
private Set<Data> dataList = new LinkedHashSet<>();
public void addData() {
Data data = new Data();
data.setId(dataList.size() + 1);
data.setName("Data " + data.getId());
dataList.add(data);
log.warn("{} {}", Integer.toHexString(data.hashCode()), data.getId());
}
public void removeData(Data data) {
dataList.remove(data);
}
public void reorder(ReorderEvent event) {
List<Data> list = new LinkedList<>(dataList);
int fromIndex = event.getFromIndex();
int toIndex = event.getToIndex();
if(toIndex >= fromIndex) {
Collections.rotate(list.subList(fromIndex, toIndex + 1), -1);
}
else {
Collections.rotate(list.subList(toIndex, fromIndex + 1), 1);
}
dataList.clear();
dataList.addAll(list);
}
/**
* Getters, Setters
*/
public Set<Data> getDataList() {
return dataList;
}
}
而现在,它首先提交值来建模和INVOKE_APPLICATION相位旋转列表。