【问题标题】:selectonemenu is not updating from another selectonemenu using<p:ajax > primefacesselectonemenu 未使用 <p:ajax > primefaces 从另一个 selectonemenu 更新
【发布时间】:2013-03-12 18:49:25
【问题描述】:

我正在尝试通过从其他 selectonemenu 中选择一些值来更新 selectonemenu。我正在使用&lt;p:ajax update=":main:deviceosName" listener="#deviceRegistration.updateOSName}" /&gt; 但是侦听器没有调用 updateOSName 方法。 在这里,我尝试从带有 id-manufectureName 的 selectonemenu 中选择一些值后,用 id -deviceosName 更新 selectonemenu

带有 id-manufectureName 的 selectonemenu 再次更新。

这是我的 xhtml 页面-

<h:form id="main" enctype="multipart/form-data">
    <p:growl id="messages" showDetail="true" />

    <p:panel id="os_version_panel" header="Os Version">
        <h:panelGrid columns="3" title="Os Version" style="width:40%;height:20%;padding:10%;padding-left:30%">

            <h:outputLabel for="manufectureName" value="Manufecture Name:*" style="float:right;font-size:15px;width:200px" />
            <p:spacer width="20" height="50" />
            <p:selectOneMenu id="manufectureName" value="#{deviceRegistration.selectedManufacture}" effect="fade" converter="deviceManufactureConverter"
                style="width:200px">
                <f:selectItem itemLabel="Select One" itemValue="" />
                <f:selectItems value="#{deviceRegistration.manufactureNameList}" var="manufacturer" itemLabel="#{manufacturer.manufacturersName}"
                    itemValue="#{manufacturer}" />
                <p:ajax event="valueChange" update=":main:deviceosName" listener="#{deviceRegistration.updateOSName}" />
            </p:selectOneMenu>

            <h:outputLabel for="deviceosName" value="Device OS Name:*" style="float:right;font-size:15px;width:200px" />
            <p:spacer width="20" height="50" />
            <p:selectOneMenu id="deviceosName" value="#{deviceRegistration.selectedOsName}" effect="fade" converter="deviceOsNameConverter"
                style="width:200px">
                <f:selectItem itemLabel="Select One" itemValue="" />
                <f:selectItems value="#{deviceRegistration.osNamesList}" var="name" itemLabel="#{name.osName}" itemValue="#{name}" />
            </p:selectOneMenu>

            <h:outputLabel for="versionName" value="Device OS Version Name:*" style="float:right;font-size:15px;width:200px" />
            <p:spacer width="20" height="50" />
            <p:inputText id="versionName" value="#{deviceRegistration.selectedVersion.osVersionName}" required="true" label="versionName" size="30">
                <f:validateLength minimum="2" />
            </p:inputText>
            <h:outputLabel for="version" value="Device Os Version:*" style="float:right;font-size:15px;width:200px" />
            <p:spacer width="20" height="50" />
            <p:inputText id="version" value="#{deviceRegistration.selectedVersion.osVersion}" required="true" label="version" size="30">
                <f:validateLength minimum="2" />
            </p:inputText>
            <f:facet name="footer">
                <p:spacer width="20" height="80" />

                <p:commandButton id="addOsVersion" value="Add OS Version" actionListener="#{deviceRegistration.addOsVersion}"
                    action="addversion.xhtml?faces-redirect=true" ajax="false" style="float:right;" />
            </f:facet>
        </h:panelGrid>
    </p:panel>


</h:form>

【问题讨论】:

  • 在这种情况下 :main 是什么?你可以试试 deviceosName
  • main 是表单的 id。要识别表单中的元素,我们必须使用表单 id 和元素 id
  • 你试过 update="deviceosName"
  • 是的,我试过找不到 servlateException 组件

标签: jakarta-ee jsf-2 primefaces


【解决方案1】:

我正在尝试通过从其他 selectonemenu 中选择一些值来更新 selectonemenu。但是监听器并没有调用updateOSName 方法。

如果发生转换或验证错误,就会发生这种情况。然后将完全跳过 INVOKE_APPLICATION 阶段。您没有使用 &lt;p:growl autoUpdate="true"&gt; 并且可能也没有注意服务器日志中的警告,因此这些转换/验证错误已经引起了您的注意。

请务必注意转换/验证错误。你真的有一个机会是很大的

main:manufectureName: 验证错误:值无效

如果这是真的,那么请前往以下答案了解所有可能的原因和适当的解决方案:Validation Error: Value is not valid

另一个可能的原因是您没有正确注册 PrimeFaces FileUploadFilter。你有一个&lt;h:form enctype="multipart/form-data"&gt;,默认情况下JSF不支持它。但是,这不会导致这个问题,而是整个表单根本无法提交/可处理,根据目前提供的信息,情况似乎并非如此。 p>

【讨论】:

  • 感谢@BalusC 指出正确的问题。但在 FileUploaderFilter 的情况下,我在我的 web.xml 中将其注册为 &lt;filter&gt; &lt;filter-name&gt;PrimeFaces FileUpload Filter&lt;/filter-name&gt; &lt;filter-class&gt;org.primefaces.webapp.filter.FileUploadFilter&lt;/filter-class&gt; &lt;/filter&gt; &lt;filter-mapping&gt; &lt;filter-name&gt;PrimeFaces FileUpload Filter&lt;/filter-name&gt; &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt; &lt;/filter-mapping&gt;
【解决方案2】:

将菜单更改为:

<p:selectOneMenu id="manufectureName" value="#{deviceRegistration.selectedManufacture}" effect="fade" converter="deviceManufactureConverter"
    style="width:200px">
    <f:selectItem itemLabel="Select One" itemValue="" />
    <f:selectItems value="#{deviceRegistration.manufactureNameList}" var="manufacturer" itemLabel="#{manufacturer.manufacturersName}"
        itemValue="#{manufacturer}" />
    <p:ajax update="deviceosName" listener="#{deviceRegistration.updateOSName}" />
</p:selectOneMenu>

p:ajax 的默认事件是change。你的监听器方法被调用了吗?您也不需要:main:deviceosName,因为deviceosNamemanufectureName 相同。

【讨论】:

  • @Subham 尝试按照我向您展示的那样更改您的代码;看看这是否有效。
  • @Subham 您的侦听器方法可能没有调用,因为我认为p:ajax 中没有任何事件称为valueChange
  • 我也尝试过你的方法,但我的监听器方法永远不会被调用
  • @Subham 看到我的另一个答案。
【解决方案3】:

一个运行良好的示例应用程序。 托管 bean:

package app.so.dev.web.controller;

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 javax.faces.event.AjaxBehaviorEvent;

import app.so.dev.web.model.Manufacturer;
import app.so.dev.web.model.Product;

@ManagedBean(name = "so15369641")
@ViewScoped
public class SO15369641 implements Serializable {

    private static final long serialVersionUID = 3128349336575959334L;

    private static final String[] manufacturerNames;
    private static final String[] productNames;
    private List<Manufacturer> manufacturers;
    private List<Product> products;
    private List<Product> productsForManufacturer;
    private String selectedManufacturer;
    private String selectedProduct;

    static {
        manufacturerNames = new String[3];
        manufacturerNames[0] = "Intel";
        manufacturerNames[1] = "Asus";
        manufacturerNames[2] = "AMD";

        productNames = new String[5];
        productNames[0] = "Motherboard";
        productNames[1] = "Processor";
        productNames[2] = "Graphics card";
        productNames[3] = "NIC";
        productNames[4] = "RAM";
    }

    @PostConstruct
    public void init() {
        manufacturers = new ArrayList<Manufacturer>();

        for(String manufactureName : manufacturerNames) {
            manufacturers.add(new Manufacturer(manufactureName));
        }

        products = new ArrayList<Product>();

        for (String productName : productNames) {
            products.add(new Product(productName, getRandomManufacturerName()));
        }

        productsForManufacturer = new ArrayList<Product>();
    }

    public void updateProduct(AjaxBehaviorEvent event) {
        if(selectedManufacturer == null || selectedManufacturer.trim().length() == 0) {
            return;
        }       

        productsForManufacturer.clear();

        for(Product product : products) {
            if(product.getManufactureName().equals(selectedManufacturer)) {
                productsForManufacturer.add(product);
            }
        }           
    }

    private String getRandomManufacturerName() {
        return manufacturerNames[(int) (Math.random() * 3)];
    }

    public List<Manufacturer> getManufacturers() {
        return manufacturers;
    }

    public void setManufacturers(List<Manufacturer> manufacturers) {
        this.manufacturers = manufacturers;
    }

    public List<Product> getProductsForManufacturer() {
        return productsForManufacturer;
    }

    public void setProductsForManufacturer(List<Product> productsForManufacturer) {
        this.productsForManufacturer = productsForManufacturer;
    }

    public String getSelectedManufacturer() {
        return selectedManufacturer;
    }

    public void setSelectedManufacturer(String selectedManufacturer) {
        this.selectedManufacturer = selectedManufacturer;
    }

    public String getSelectedProduct() {
        return selectedProduct;
    }

    public void setSelectedProduct(String selectedProduct) {
        this.selectedProduct = selectedProduct;
    }       
}

还有xhtml:

<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core" xmlns:p="http://primefaces.org/ui" template="/WEB-INF/templates/globalTemplate.xhtml">

    <ui:define name="title">15369641</ui:define>
    <ui:define name="content">
        <p:growl id="growl" showDetail="true" />

        <h:form id="form">
            <p:selectOneMenu id="manufacturer" value="#{so15369641.selectedManufacturer}">
                <f:selectItem itemLabel="Select One" itemValue="" />
                <f:selectItems value="#{so15369641.manufacturers}" var="manufacturer" itemLabel="#{manufacturer.name}" itemValue="#{manufacturer.name}" />

                <p:ajax listener="#{so15369641.updateProduct}" update="product"/>
            </p:selectOneMenu>

            <p:selectOneMenu id="product" value="#{so15369641.selectedProduct}">
                <f:selectItem itemLabel="Select One" itemValue=""/>
                <f:selectItems value="#{so15369641.productsForManufacturer}" var="product" itemLabel="#{product.name}" itemValue="#{product.name}"/>
            </p:selectOneMenu>
        </h:form>
    </ui:define>

</ui:composition>

希望它会有所帮助。

环境:

  • JBoss AS7
  • JBoss org 提供的 JSF Mojarra 2.1.7
  • Primefaces 3.4.2

【讨论】:

    猜你喜欢
    • 2013-08-14
    • 2015-05-04
    • 2013-09-16
    • 2014-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多