在我的应用程序中,我有三个下拉菜单(p:selectOneMenu
),分别是A,B,C。其中两个是依赖的,例如B和C。通过更改BI的值可以将值动态加载到C。还有一个文本框。当这三个下拉菜单触发on-change事件时,文本框的值由ajax生成。
这是xhtml:
<p:selectOneMenu id="customerMenu" value="#{adminController.activityDTO.customerId}" required="true" label="Customer Name" style="width: 200px">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{adminController.customers}" var="customer" itemLabel="#{customer.customerName}" itemValue="#{customer.customerId}" />
<p:ajax listener="#{adminController.generateActivityName}" update="activityId" />
</p:selectOneMenu>
<p:selectOneMenu id="activityTypeMenu" value="#{adminController.activityDTO.activityParentType}" required="true" label="Activity Type"
style="width: 200px">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{adminController.activityTypes}" var="activityType" itemLabel="#{activityType.parent}" itemValue="#{activityType.parent}" />
<p:ajax listener="#{adminController.updateDependentActivity}" update="activitySubType" />
</p:selectOneMenu>
<p:selectOneMenu id="activitySubTypeMenu" value="#{adminController.activityDTO.activitySubType}" required="true" label="Activity Sub Type"
style="width: 200px">
<f:selectItem itemLabel="Select One" itemValue="" />
<f:selectItems value="#{adminController.activitySubTypes}" var="activityType" itemLabel="#{activityType.name}" itemValue="#{activityType.id}" />
<p:ajax listener="#{adminController.generateActivityId}" update="activityId" />
</p:selectOneMenu>
<p:inputText id="activityId" autocomplete="off" readonly="true" value="#{adminController.activityDTO.activityId}"
label="#{adbBundle['admin.addActivityPanel.addActivityTable.activityId']}" required="true" />
activityTypeMenu
和activitySubTypeMenu
取决于我正在填充activityTypeMenu
的activitySubTypeMenu
的选定值。现在我面临的问题是:
假设我在
activityTypeMenu
中选择了“外部”和“内部”,默认为“选择一个”。如果从activityTypeMenu
中选择“外部”,则activitySubTypeMenu
将具有“项目”和“服务”。但是,如果我选择默认的“选择一个”,则activitySubTypeMenu
仍保留以前动态填充的值。这是因为required="true"
属性拒绝触发我从中加载动态值的后端方法。我尝试将
itemValue
的<f:selectItem itemLabel="Select One" itemValue="" />
设置为#{null}
,然后在选择“选择一个”选项时触发后端方法,因此我可以将空列表设置为activitySubTypes
,这样activitySubTypeMenu
空着。但是在那种情况下,required="true"
变得毫无意义。我的意思是,我也有“保存”按钮,并且单击该按钮时未从activityTypeMenu
和activitySubTypeMenu
中选择任何选项(即选择“选择一个”),而不会抛出ValidatorException
,并且组件没有因错误CSS设置样式Primefaces类。另外,如果我没有将
itemValue
的<f:selectItem itemLabel="Select One" itemValue="" />
设置为#{null}
,则将所选值更改为默认选项(“选择一个”)不会清除activityId
p:inputText
。如果使用#{null}
,则可以触发后端方法,从该方法可以将文本框的值设置为空。我如何解决此问题并获得理想的结果。我想要的是:
如果选项设置为“选择一个”,则从属菜单将为空,而文本框将为空。
我想使用
required="true"
属性。 最佳答案
您可以在required
属性中使用EL。仅当按下特定的提交按钮或提交了特定的组件值(并因此通过其在请求参数映射true
中的客户端ID)时,才可以让所需的表达式求值#{param}
。
下面的启动示例应满足您的需求。
<p:selectOneMenu binding="#{menu1}" ... required="#{not empty param[submit.clientId]}">
...
</p:selectOneMenu>
<p:selectOneMenu ... required="#{not empty param[menu1.clientId]}">
...
</p:selectOneMenu>
<p:commandButton binding="#{submit}" ... />
这样,仅当按下表单的主提交按钮时才需要第一菜单(因此,当事件监听器被触发时才需要),仅当第一菜单具有值时才需要第二菜单。