如果其他 portlet 包含 <form> 标签,PrimeFaces 拖放操作将不起作用

PrimeFaces Drag & Drop not working if other portlets contain <form> tags

如果我有一个 Liferay 页面,其中包含带有 form 标记的 Liferay Web 内容显示,然后是带有 p:droppablep:draggable 的 PrimeFaces portlet,则拖放功能可以不工作。

我的 XHTML:

<?xml version="1.0"?>

<f:view xmlns="http://www.w3.org/1999/xhtml" xmlns:c="http://java.sun.com/jsp/jstl/core"
        xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui"
        xmlns:ui="http://java.sun.com/jsf/facelets">
    <h:head />
    <h:body>

        <h:form id="carForm">
            <p:fieldset id="availableCarsField" legend="AvailableCars">
                <p:dataGrid id="availableCars" var="car" value="#{dndCarsView.cars}" columns="3">
                    <p:panel id="pnl" header="#{car.id}" style="text-align:center">
                        <h:panelGrid columns="1" style="width:100%">
                            <h:outputText value="#{car.id}" />
                        </h:panelGrid>
                    </p:panel>

                    <p:draggable for="pnl" revert="true" handle=".ui-panel-titlebar" stack=".ui-panel" />
                </p:dataGrid>
            </p:fieldset>

            <p:fieldset id="selectedCars" legend="Selected Cars" style="margin-top:20px">
                <p:outputPanel id="dropArea">
                    <h:outputText value="!!!Drop here!!!" rendered="#{empty dndCarsView.droppedCars}" style="font-size:24px;" />
                    <p:dataTable id="selectedCarsTable" var="car" value="#{dndCarsView.droppedCars}"
                                 rendered="#{not empty dndCarsView.droppedCars}">
                        <p:column headerText="Id">
                            <h:outputText value="#{car.id}" />
                        </p:column>

                        <p:column headerText="Year">
                            <h:outputText value="#{car.year}" />
                        </p:column>

                        <p:column headerText="Brand">
                            <h:outputText value="#{car.brand}" />
                        </p:column>

                        <p:column headerText="Color">
                            <h:outputText value="#{car.color}" />
                        </p:column>

                        <p:column style="width:32px">
                            <p:commandButton update=":carForm:display" oncomplete="PF('carDialog').show()" icon="ui-icon-search">
                                <f:setPropertyActionListener value="#{car}" target="#{dndCarsView.selectedCar}" />
                            </p:commandButton>
                        </p:column>
                    </p:dataTable>
                </p:outputPanel>
            </p:fieldset>

            <p:droppable for="selectedCars" tolerance="touch" activeStyleClass="ui-state-highlight" datasource="availableCars"
                         onDrop="handleDrop">
                <p:ajax listener="#{dndCarsView.onCarDrop}" update="dropArea availableCars" />
            </p:droppable>

            <p:dialog header="Car Detail" widgetVar="carDialog" resizable="false" draggable="false" showEffect="fade"
                      hideEffect="fade" modal="true">

                <p:outputPanel id="display">
                    <h:panelGrid columns="2" cellpadding="5" rendered="#{not empty dndCarsView.selectedCar}">
                        <f:facet name="header">
                            <p:graphicImage name="/demo/images/car/#{dndCarsView.selectedCar.brand}.gif" />
                        </f:facet>

                        <h:outputText value="Id" />
                        <h:outputText value="#{dndCarsView.selectedCar.id}" style="font-weight:bold" />

                        <h:outputText value="Year:" />
                        <h:outputText value="#{dndCarsView.selectedCar.year}" style="font-weight:bold" />

                        <h:outputText value="Brand" />
                        <h:outputText value="#{dndCarsView.selectedCar.brand}" style="font-weight:bold" />

                        <h:outputText value="Color:" />
                        <h:outputText value="#{dndCarsView.selectedCar.color}" style="font-weight:bold" />
                    </h:panelGrid>
                </p:outputPanel>
            </p:dialog>
        </h:form>

    </h:body>
</f:view>

我的豆子:

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.DragDropEvent;

@ManagedBean(name = "dndCarsView")
@ViewScoped
public class DNDCarsView implements Serializable {

    private List<Car> cars;

    private List<Car> droppedCars;

    private Car selectedCar;

    @PostConstruct
    public void init() {
        cars = new ArrayList<Car>();
        cars.add(new Car(1, 2001, "toyota", "black"));
        cars.add(new Car(2, 2002, "honda", "yello"));
        cars.add(new Car(3, 2003, "ferrari", "white"));
        cars.add(new Car(4, 2004, "bmw", "green"));
        cars.add(new Car(5, 2005, "suzuki", "blue"));
        cars.add(new Car(6, 2006, "mazda", "brown"));
        cars.add(new Car(7, 2007, "audi", "halfwhie"));
        cars.add(new Car(8, 2008, "aqua", "neroon"));
        droppedCars = new ArrayList<Car>();
    }

    public void onCarDrop(DragDropEvent ddEvent) {
        Car car = ((Car) ddEvent.getData());

        droppedCars.add(car);
        cars.remove(car);
    }

    public List<Car> getCars() {
        return cars;
    }

    public List<Car> getDroppedCars() {
        return droppedCars;
    }

    public Car getSelectedCar() {
        return selectedCar;
    }

    public void setSelectedCar(Car selectedCar) {
        this.selectedCar = selectedCar;
    }

}

您 运行 进入 PrimeFaces Issue #3265: PrimeFaces Draggable/Droppable submits Ajax requests via the wrong form。一个简单的解决方法是显式声明您希望用于 Draggable/Droppable Ajax 请求的表单(使用 h:formbindingp:ajaxform属性):

<h:form id="carForm" binding="#{carForm}">
    <!-- Your code here.... -->
    <p:droppable for="selectedCars" tolerance="touch"
        activeStyleClass="ui-state-highlight" datasource="availableCars"
        onDrop="handleDrop">
        <p:ajax listener="#{dndCarsView.onCarDrop}"
            update="dropArea availableCars" form="#{carForm.clientId}" />
    </p:droppable>
</h:form>