(java7, jsf/mojarra v2.1.11, primefaces v3.4.2)
Problem
I have a form with an p:autocomplete
input field that the user is required to populate, along with other fields (shown, below).
Right now, after the page is returned with validation and/or required errors, the value that the user has set no longer displays. This is in contrast to all the other fields which still show their values that have been entered/set by the user.
Question:
Why doesnt this field display the user entered value? Can I force it to display the value?
(Again, initially, the selected value is visible in the p:autocomplete
input box. But, after the page is submitted and returned with validation erriors, the selected value is no longer displayed)
The tag looks like this:
<p:autoComplete
id="code"
requiredMessage="code value required"
converter="acConverter"
style="overflow: hidden"
maxResults="200"
scrollHeight="150"
dropdown="false"
value="#{testBean.parmMap['code']}"
completeMethod="#{testBean.codeListComplete}"
var="entry"
itemLabel="#{entry.split(':')[1]}"
itemValue="#{entry.split(':')[0]}"
minQueryLength="1"
forceSelection="true">
</p:autoComplete>
Right now, if a user submits the form and the form is posted back with various form validation errors, then, even if the user has correctly selected from the p:autocomplete
, the associated input field does not show what they have selected (although it is apparently saved in the request/memory).
FYI - Below is more info if you need it (otherwise, you can just ignore it)...
index.xhtml...
<?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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:head>
<title>test autocomplete...</title>
<meta charset="utf-8" />
</h:head>
<h:body>
<h:form id="queryForm">
<f:event type="postValidate" listener="#{testBean.validate}" />
<p:panel id="queryPanel" header="test autocomplete..." style="width:100%;">
<p:autoComplete
id="code"
requiredMessage="code value required"
converter="acConverter"
style="overflow: hidden"
maxResults="200"
scrollHeight="150"
dropdown="false"
value="#{testBean.parmMap['code']}"
completeMethod="#{testBean.codeListComplete}"
var="entry"
itemLabel="#{entry.split(':')[1]}"
itemValue="#{entry.split(':')[0]}"
minQueryLength="1"
forceSelection="true">
</p:autoComplete>
<br/>
<br/>
<p:commandButton
id="submit"
value="Submit"
type="submit"
update="@form"
process="@form"
action="#{testBean.submitQuery}"
style="width:150px;"
styleClass="button"/>
<p:commandButton
value="Reset"
update="@form"
onclick="location.reload();return true;"
process="@this"
actionListener="#{testBean.reset}"
immediate="true"
ajax="false"/>
</p:panel>
</h:form>
<h:outputStylesheet library="styles" name="query.css" />
<h:outputScript library="primefaces" name="/jquery/jquery.js" />
<h:outputScript library="primefaces" name="/jquery/plugins/ui/jquery-ui.custom.js" />
<h:outputScript library="primefaces" name="/jquery/plugins/inputmask/maskedinput.js" />
</h:body>
</f:view>
</html>
TestBean.java...
package aaa.bbb.ccc.war;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIForm;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ComponentSystemEvent;
import org.apache.commons.lang.StringUtils;
import org.primefaces.context.RequestContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("testBean")
@Scope("request")
public class TestBean implements Serializable
{
public TestBean()
{
parmMap = this.getParmMap();
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("parmMap", parmMap);
}
public void reset(ActionEvent event)
{
RequestContext.getCurrentInstance().reset("queryForm:queryPanel");
LinkedHashMap<String, Object> m = new LinkedHashMap<String, Object>();
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("parmMap");
setParmMap(m);
}
public String submitQuery()
{
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove("hitlistData");
System.out.println("TestBean_________________________submitQuery()____________________parmMap contains:" + this.getParmMap().toString());
if (this.getParmMap().isEmpty())
{
return "";
}
return "/page2.xhtml?faces-redirect=true";
}
private static LinkedHashMap<String, Object> parmMap;
public LinkedHashMap<String, Object> getParmMap()
{
LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("parmMap");
if (null == map)
{
map = new LinkedHashMap<String, Object>();
}
return map;
}
public void setParmMap(LinkedHashMap<String, Object> map)
{
parmMap = map;
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("parmMap", parmMap);
}
public void validate(ComponentSystemEvent e) throws ParseException
{
LinkedHashMap parmMap = this.getParmMap();
UIForm queryForm = (UIForm) e.getComponent();
FacesContext fc = FacesContext.getCurrentInstance();
UIInput code_c = (UIInput) queryForm.findComponent("code");
String code = (String) code_c.getValue();
try
{
if (StringUtils.isBlank(code))
{
code_c.setSubmittedValue("");
code_c.setValid(false);
fc.addMessage(code_c.getClientId(), new FacesMessage(FacesMessage.SEVERITY_ERROR, code_c.getRequiredMessage(), code_c.getRequiredMessage()));
}
if (fc.getMessageList().size() > 0)
{
fc.renderResponse();
}
}
catch (Exception e1)
{
e1.printStackTrace();
}
}
private static List<String> codeList;
public static List<String> getCodeList()
{
codeList = (List<String>) FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get("codeList");
if (null == codeList)
{
codeList = new ArrayList<String>();
codeList.add("keyaaaa:valaaaa");
codeList.add("keybbbb:valbbbb");
codeList.add("keycccc:valcccc");
codeList.add("keydddd:valdddd");
codeList.add("keyeeee:valeeee");
codeList.add("keyffff:valffff");
codeList.add("keygggg:valgggg");
codeList.add("keyhhhh:valhhhh");
FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put("codeList", codeList);
}
return codeList;
}
public void setCodeList(List<String> list)
{
codeList = list;
}
public static List<String> codeListComplete(String s) //autocomplete "completeMethod"...
{
List<String> list = getCodeList();
List<String> suggestions = new ArrayList<String>();
for (String ss : list)
{
if (ss.toLowerCase().contains(s.toLowerCase()))
{
suggestions.add(ss);
}
}
return suggestions;
}
}
ACConverter.java (I created this in an unsuccessful attempt to remove the string value "null")...
package aaa.bbb.ccc.war;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.ConverterException;
import javax.faces.convert.FacesConverter;
import org.apache.commons.lang.StringUtils;
@FacesConverter("acConverter")
public class ACConverter implements Converter
{
@Override
public Object getAsObject(FacesContext context, UIComponent component, String value)
{
try
{
if (StringUtils.isBlank(value) || String.valueOf(value).equalsIgnoreCase("null"))
{
return "";
}
}
catch (Exception e)
{
UIInput input = (UIInput) component;
FacesMessage msg = new FacesMessage(input.getConverterMessage(),input.getConverterMessage());
msg.setSeverity(FacesMessage.SEVERITY_ERROR);
throw new ConverterException(msg);
}
return value;
}
@Override
public String getAsString(FacesContext context, UIComponent component, Object value)
{
return (null==value?"":String.valueOf(value));
}
}