我已经花了很多时间试图实现与Showcase > Dependent Dropdowns所示的功能相同,但是我要使用autoComplete而不是下拉菜单(p:selectOneMenu
)。
我变得有点复杂,因为我发现它并不那么简单-而不是“在页面中”,我试图在对话框中实现相同目的+我希望在未选择国家/地区时禁用城市自动完成功能。 / p>
因此最初的简单方法如下:
页面
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui"
xmlns:sec="http://www.springframework.org/security/tags" xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
</h:head>
<h:body>
<h:form>
<p:commandButton value="Open dialog" id="show" actionListener="#{dependentAutocompletesDialogView.showDialog}" icon="ui-icon-info" update="dialog" />
</h:form>
<p:dialog id="dialog" widgetVar="dialog" modal="true" dynamic="true" >
<h:form prependId="false" id="form">
<p:panel header="Select a Location" style="margin-bottom:10px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:autoComplete id="country" value="#{dependentAutocompletesDialogView.country}" completeMethod="#{dependentAutocompletesDialogView.countriesComplete}"
dropdown="true" required="true">
<p:ajax event="itemSelect" update="city" />
</p:autoComplete>
<p:outputLabel for="city" value="City: " />
<p:autoComplete id="city" value="#{dependentAutocompletesDialogView.city}"
completeMethod="#{dependentAutocompletesDialogView.citiesComplete(dependentAutocompletesDialogView.country)}"
dropdown="true" widgetVar="city" required="true" disabled="#{dependentAutocompletesDialogView.country == null}">
</p:autoComplete>
</h:panelGrid>
</p:panel>
<p:commandButton value="Submit" id="submit" actionListener="#{dependentAutocompletesDialogView.dialogSubmit}" icon="ui-icon-check" process="dialog" update="form"/>
</h:form>
</p:dialog>
</h:body>
</html>
Bean
package com.codenotfound.primefaces.model;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.AjaxBehaviorEvent;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.PrimeFaces;
import org.primefaces.context.RequestContext;
@Named
@ViewScoped
public class DependentAutocompletesDialogView {
private Map<String,List<String>> data = new HashMap<String, List<String>>();
private String country;
private String city;
private List<String> countries;
private List<String> cities;
public List<String> countriesComplete(String filter) {
return countries;
}
public List<String> citiesComplete(String filter) {
return data.get(country);
}
@PostConstruct
public void init() {
countries = new LinkedList<>();
countries.add("USA");
countries.add("Germany");
countries.add("Brazil");
List<String> list;
list = new LinkedList<>();
list.add("New York");
list.add("San Francisco");
list.add("Denver");
data.put("USA", list);
list = new LinkedList<>();
list.add("Berlin");
list.add("Munich");
list.add("Frankfurt");
data.put("Germany", list);
list = new LinkedList<>();
list.add("Sao Paolo");
list.add("Rio de Janerio");
list.add("Salvador");
data.put("Brazil", list);
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public List<String> getCountries() {
return countries;
}
public List<String> getCities() {
return cities;
}
public void displayLocation() {
FacesMessage msg;
if(city != null && country != null)
msg = new FacesMessage("Selected", city + " of " + country);
else
msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid", "City is not selected.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onChange(AjaxBehaviorEvent event) {
System.out.println();
}
public void showDialog() {
country = null;
city = null;
RequestContext.getCurrentInstance().getScriptsToExecute().add("PF('dialog').show();");
PrimeFaces.current().ajax().update("form");
}
public void dialogSubmit() {
RequestContext.getCurrentInstance().getScriptsToExecute().add("PF('dialog').hide();");
displayLocation();
}
}
这似乎是一见钟情:
但是
showDialog()
中的国家和城市设置为null 我尝试通过添加以下内容来解决使用JavaScript的删除问题:
<p:ajax process="@this"
oncomplete="if ( PF('country').input.val() == '' ) { PF('city').input.val(''); PF('city').hinput.val(''); PF('city').disable(); }"
update="city" />
但是它只是删除city autoComplete,但是在提交时并未被验证为丢失=不会传播到bean ...
答案 0 :(得分:0)
根据我的测试,在PF版本6.2中,仅当用户从autoComplete中删除过滤器/选定的值时,才会在autoComplete上生成onchange事件。
我用它来解决它:
页面
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui"
xmlns:sec="http://www.springframework.org/security/tags" xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
</h:head>
<h:body>
<p:growl id="msgs" showDetail="true" />
<h:form>
<p:commandButton value="Open dialog" id="show" actionListener="#{dependentAutocompletesDialogChangeView.showDialog}" icon="ui-icon-info" update="dialog" />
</h:form>
<p:dialog id="dialog" widgetVar="dialog" modal="true" dynamic="true" >
<p:ajax event="close" listener="#{dependentAutocompletesDialogChangeView.handleClose}" update="@this" resetValues="true" />
<h:form id="form">
<p:remoteCommand name="clearCountry" actionListener="#{dependentAutocompletesDialogChangeView.clearCountryAndCity}" immediate="true" update="city" />
<p:panel header="Select a Location" style="margin-bottom:10px;">
<h:panelGrid columns="2" cellpadding="5">
<p:outputLabel for="country" value="Country: " />
<p:autoComplete id="country" widgetVar="country" value="#{dependentAutocompletesDialogChangeView.country}"
completeMethod="#{dependentAutocompletesDialogChangeView.countriesComplete}" process="@this"
dropdown="true" required="true" emptyMessage="No countries matching filter" onchange="clearCountry()">
<p:ajax event="itemSelect" update="city" />
</p:autoComplete>
<p:outputLabel for="city" value="City: " />
<p:autoComplete id="city" value="#{dependentAutocompletesDialogChangeView.city}"
completeMethod="#{dependentAutocompletesDialogChangeView.citiesComplete(dependentAutocompletesDialogChangeView.country)}"
dropdown="true" widgetVar="city" required="true" disabled="#{dependentAutocompletesDialogChangeView.country == null}">
</p:autoComplete>
</h:panelGrid>
</p:panel>
<p:commandButton value="Submit" id="submit" actionListener="#{dependentAutocompletesDialogChangeView.dialogSubmit}" icon="ui-icon-check" process="dialog" update="form, msgs" />
</h:form>
</p:dialog>
</h:body>
</html>
Bean
package com.codenotfound.primefaces.model;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.primefaces.PrimeFaces;
import org.primefaces.context.RequestContext;
import org.primefaces.event.CloseEvent;
@Named
@ViewScoped
public class DependentAutocompletesDialogChangeView {
private Map<String,List<String>> data = new HashMap<String, List<String>>();
private String country;
private String city;
private List<String> countries;
private List<String> cities;
public List<String> countriesComplete(String filter) {
return countries.stream().filter(item -> match(item, filter)).collect(Collectors.<String>toList());
}
private boolean match(String item, String filter) {
return item.contains(filter);
}
public List<String> citiesComplete(String filter) {
return data.get(country);
}
@PostConstruct
public void init() {
countries = new LinkedList<>();
countries.add("USA");
countries.add("Germany");
countries.add("Brazil");
List<String> list;
list = new LinkedList<>();
list.add("New York");
list.add("San Francisco");
list.add("Denver");
data.put("USA", list);
list = new LinkedList<>();
list.add("Berlin");
list.add("Munich");
list.add("Frankfurt");
data.put("Germany", list);
list = new LinkedList<>();
list.add("Sao Paolo");
list.add("Rio de Janerio");
list.add("Salvador");
data.put("Brazil", list);
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public List<String> getCountries() {
return countries;
}
public List<String> getCities() {
return cities;
}
public void displayLocation() {
FacesMessage msg;
if(city != null && country != null)
msg = new FacesMessage("Selected", city + " of " + country);
else
msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "Invalid", "City is not selected.");
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void showDialog() {
country = null;
city = null;
RequestContext.getCurrentInstance().getScriptsToExecute().add("PF('dialog').show();");
PrimeFaces.current().ajax().update("form");
}
public void dialogSubmit() {
RequestContext.getCurrentInstance().getScriptsToExecute().add("PF('dialog').hide();");
displayLocation();
}
public void clearCountryAndCity() {
country = null;
city = null;
PrimeFaces.current().executeScript("PF('country').input.val('')");
PrimeFaces.current().executeScript("PF('city').input.val('')");
PrimeFaces.current().ajax().update("country", "city");
}
public void handleClose(CloseEvent event) {
clearCountryAndCity();
}
}