<p:autocomplete> POJO problem : label used as value

UI Components for JSF
Post Reply
bix
Posts: 2
Joined: 15 Mar 2011, 17:19

15 Mar 2011, 18:30

Hi,

I found what I think is an anormal behaviour of the <p:autocomplete> component.

Server : Websphere AS 7.0.0.13
JSF : mojarra 2.0.3 (JSF 2.0)
Primefaces : 2.2-RC2

I use an autocomplete component with POJO support, my POJOs have a label and an id.

Code: Select all

<p:autoComplete
    id="site"
    value="#{myBean.selectedSite}"
    required="true"
    converter="#{myBean.siteConverter}"
    completeMethod="#{myBean.completeSite}"
    var="site"
    itemLabel="#{site.label}"
    itemValue="#{site}"
    forceSelection="true"
    minQueryLength="0"
    widgetVar="siteAutoComplete"
    onclick="siteAutoComplete.search(siteAutoComplete.value)"/>
I use a converter to handle the id <-> Site object transformation :

Code: Select all

public class SiteConverter implements Converter, Serializable {

    private static final long serialVersionUID = 1L;

    private Collection<Site> cache;

    public SiteConverter(final Collection<Site> cache) {
        this.cache = cache;
    }
    
    @Override
    public Object getAsObject(final FacesContext context, final UIComponent component,
            final String value) {

        if (value == null || value.trim().isEmpty()) {
            return null;
        }

        Long siteId;
        try {
            siteId = Long.parseLong(value);
        } catch (NumberFormatException e) {
            String message = "Site convertion error with id=\"" + value + "\"";
            FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message,
                    null);
            throw new ConverterException(facesMessage, e);
        }

        Site site = null;
        if (cache != null) {
            for (Site s : cache) {
                if (s != null && s.getId() != null && s.getId().equals(siteId)) {
                    site = s;
                    break;
                }
            }
        }

        if (site == null) {
            String message = "Site convertion error with id=\"" + value + "\"";
            FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, message, null);
            throw new ConverterException(facesMessage);
        }

        return site;
    }

    @Override
    public String getAsString(final FacesContext context, final UIComponent component,
            final Object value) {

        if (value == null) {
            return "";
        }

        if (!(value instanceof Site)) {
            throw new IllegalArgumentException("Cannot convert non-Site object.");
        }

        Site site = (Site) value;
        if (site.getId() == null) {
            throw new IllegalArgumentException("Cannot convert Site object with null id.");
        }

        return Long.toString(site.getId());
    }
}
The component works, but the internal behaviour is very strange.
On client side, two <input> tags are generated : site_input, this is what I type, and site_hinput, this is (should be) the id of the selected item.

When I select a site in the autocomplete list :
- site_input is set to the site label, and site_hinput is set to the site id--> OK
- an ajax POST is done to update the selected site on server-side --> OK
- the site_hinput field is processed by the SiteConverter, and a site corresponding to the id is found --> OK

Ajax POSTs (catched with firebug) :

Code: Select all

mainForm:site_hinput	2
mainForm:site_input	FLA - Site de Flamanville
mainForm:site_query	FLA - Site de Flamanville
But now when I type a value in the autocomplete field, let's say "FLA" :
- site_input contains "FLA", and site_hinput contains the same value --> why ?? No site has been selected, FLA does not correspond to a site_id. Why doesn't site_hinput contains a null value ??
- an ajax POST is done to update the selected site on server-side --> why ?? Again, no site has been selected. The "FLA" value is sent, which does not correspond to a site id. Let's say we consider I unselected the previous site, and selected an empty site instead by typing the "FLA" value : it is a null value that should be send to server, in order to put a null value as selected site.
- the site_hinput field is processed by the SiteConverter, and an error happen --> KO, my converter handles site ids, not site labels. Sending "FLA" throws a Converter Exception.

Ajax POSTs (catched with firebug) :

Code: Select all

mainForm:site_hinput	F
mainForm:site_input	F
mainForm:site_query	F

Code: Select all

mainForm:site_hinput	FL
mainForm:site_input	FL
mainForm:site_query	FL

Code: Select all

mainForm:site_hinput	FLA
mainForm:site_input	FLA
mainForm:site_query	FLA
Here is the converter exception stacktrace :

Code: Select all

2011-03-15 16:08:41,927 ERROR [ebContainer : 4 ] Exhaustive - Exception launched in  Object fr.XXXXX.SiteConverter.getAsObject(FacesContext, UIComponent, String) with arguments [com.sun.faces.context.FacesContextImpl@63d963d9, org.primefaces.component.autocomplete.AutoComplete@39b839b8, F]
javax.faces.convert.ConverterException: Site convertion error with id=FLA.
	at fr.XXXXX.SiteConverter.getAsObject(SiteConverter.java:133)
	at org.primefaces.component.autocomplete.AutoCompleteRenderer.getConvertedValue(AutoCompleteRenderer.java:215)
	at javax.faces.component.UIInput.getConvertedValue(UIInput.java:1023)
	at javax.faces.component.UIInput.validate(UIInput.java:953)
	at javax.faces.component.UIInput.executeValidate(UIInput.java:1204)
	at javax.faces.component.UIInput.processValidators(UIInput.java:693)
	at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:469)
	at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:175)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1476)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
	at javax.faces.component.UIForm.visitTree(UIForm.java:331)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
	at javax.faces.component.UIComponent.visitTree(UIComponent.java:1487)
	at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:361)
	at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:241)
	at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:179)
	at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1157)
	at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:72)
	at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:97)
	at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:114)
	at javax.faces.webapp.FacesServlet.service(FacesServlet.java:308)
Again, the basic behaviour of the component works : it loads a list, I can select an item in it, and the server-side item value is updated.
But if I want to handle this field on client-side with JavaScript, the strange behaviour of the site_hinput field is annoying. The convertion errors on server-side are annoying too.
Server : Websphere AS 7.0.0.13
JSF : mojarra 2.0.3 (JSF 2.0)
Primefaces : 2.2-RC2

DeKrikke
Posts: 1
Joined: 12 Mar 2011, 20:45

29 Apr 2011, 20:44

i noticed the same behaviour and couldn't really find an explanation for it.
i am also working with POJOs where i display a string representation but where the converter returns the id in the getAsString method.
and indeed, when i select a value, everything works as expected. but when i start typing the letters, the getAsObject always tries to convert the input string but it doesn't make sense because i didn't select any value yet at that time. and so the getAsObject of course throws a conversion error because it expects the id to be passed.
at the moment i am just catching the numerformatexception and ignoring it, which is not the right thing to do.

was wondering if you found an explanation for this in the meantime ?

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: Google [Bot] and 23 guests