Primefaces重新排序包含输入的行

ant*_*u17 2 primefaces jsf-2

p:dataTablep: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>
Run Code Online (Sandbox Code Playgroud)

支持豆:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

数据类:

public class Data implements Serializable {

    private Integer id;
    private String name;

    /**
     * Getters, Setters
     */

}
Run Code Online (Sandbox Code Playgroud)

重新排序之前的数据表示例:

--------------
|id |  name  |
--------------
| 1 | Data 1 |
| 2 | Data 2 |
| 3 | Data 3 |
| 4 | Data 4 |
--------------
Run Code Online (Sandbox Code Playgroud)

重新排序后(将第1行移至第3行):

--------------
|id |  name  |
--------------
| 2 | Data 1 |
| 3 | Data 2 |
| 1 | Data 3 |
| 4 | Data 4 |
--------------
Run Code Online (Sandbox Code Playgroud)

据我所知,它正在发生"从设置数据的原因p:inputText,在S" UPDATE_MODEL阶段.我试图通过process="@none"p:ajax组件中指定来阻止输入字段的处理,但它不起作用.知道如何制作draggableRowsp:inputText朋友吗?

ant*_*u17 10

第一解决方案

我找到了解决方案!它不处理带有属性的输入(实际上根本不提交它)process="@none" partialSubmit="true"

所以完整的p:ajax组件看起来像 <p:ajax event="rowReorder" listener="#{rowReorder.reorder}" update="dataTable" process="@none" partialSubmit="true"/>


第二种解决方案(如果需要提交数据)

理论:

让我们看看拖动行发生了什么?我们有ajax请求强制process="form:dataTable".在APPLY_REQUEST_VALUES阶段DataTableRenderer尝试调用解码DraggableRowsFeature,反过来,旋转列表元素(指定为dataTable的value属性的列表).所以在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()只有当值是List的实例时才调用.

    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.");
    }     
Run Code Online (Sandbox Code Playgroud)

还有DraggableRowsFeature.shouldDecode()方法.

public boolean shouldDecode(FacesContext context, DataTable table) {
    return context.getExternalContext().getRequestParameterMap().containsKey(table.getClientId(context) + "_rowreorder");
}
Run Code Online (Sandbox Code Playgroud)

所以这里我们有两种可能阻止数据源旋转:

  1. 不要List用作dataTable值
  2. org.primefaces.component.datatable.feature.DraggableRowsFeatureshouldDecode()方法中创建自己的返回false .

实践:

我像这样修改了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;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在它首先在INVOKE_APPLICATION阶段向模型和旋转列表提交值.

  • @lastresort它是不可能的,因为它没有面部组件可以伸展.我没有找到任何方法来注册自定义DraggableRowsFeature而不破坏primefaces源... (2认同)