14 Replies Latest reply on Nov 19, 2007 5:15 AM by marius.oancea

    Parameters not sent when using s:selectItems

    marius.oancea

      The following code works perfectly:

      <h:selectOneMenu id="committee" value="#{mrpList.criteria.committee}" >
      <f:selectItem itemLabel="TEST1" itemValue="1" />
      <f:selectItem itemLabel="TEST2" itemValue="2" />

      </h:selectOneMenu>



      committee is an "int" and is set correctly when the form is submited.

      If I user the following code:

      <h:selectOneMenu id="committee" value="#{mrpList.criteria.committee}" >
      <s:selectItems value="#{committeeList.resultList}"
      var="committee"
      label="#{committee.title}" />
      <s:convertEntity />
      </h:selectOneMenu>

      "0" is submitted all the time.

      Please note that resultlist retrieve from DB the right entiries.

      Any clue?
      Thanx

        • 1. Re: Parameters not sent when using s:selectItems
          pmuir

          If committee is an int, why are you using the entity converter? It's a two way thing - both onto the page and back

          • 2. Re: Parameters not sent when using s:selectItems
            marius.oancea

            Thanx pete for the hint but what I want to do is:

            populate the combo from committeeList.resultList (committeeList is a seam query)

            Have the selected commitee.id stored in #{mrpList.criteria.committee} back and forth so that i can use it in another framework query.

            • 3. Re: Parameters not sent when using s:selectItems
              marius.oancea

              In plain words what i have is:

              MRPList.xhtml (snap)
              ====================

              <s:decorate template="layout/display.xhtml">
               <ui:define name="label">Committee</ui:define>
               <h:selectOneMenu id="cmtid" value="#{markupRepresentationList.criteria.committee}">
               <s:selectItems value="#{committeeList.resultList}"
               var="committee"
               label="#{committee.title}" />
               </h:selectOneMenu>
              
               </s:decorate>
              



              MRPList.page.xml
              ================

              <?xml version="1.0" encoding="UTF-8"?>
              <page xmlns="http://jboss.com/products/seam/pages"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd">
              
               <param name="firstResult" value="#{markupRepresentationList.firstResult}"/>
               <param name="order" value="#{markupRepresentationList.order}"/>
               <param name="from"/>
               <param name="fulltext" value="#{markupRepresentationList.criteria.fulltext}"/>
               <param name="cmtid" value="#{markupRepresentationList.criteria.committee}"/>
              </page>
              
              




              @Name("markupRepresentationList")
              public class MarkupRepresentationList extends EntityQuery {
              
               private static final String[] RESTRICTIONS = {
               "term.name like concat(#{markupRepresentationList.criteria.fulltext},'%')",
               "concept.sourceReference.ownerComittee.id=#{markupRepresentationList.criteria.committee}",
               };
              
               private MarkupSearchCriteria criteria = new MarkupSearchCriteria();
              
               @Override
               public String getEjbql() {
               return "select term from Markup term, IN (term.concepts) concept";
               }
              
               @Override
               public Integer getMaxResults() {
               return 5;
               }
              
              
               public MarkupSearchCriteria getCriteria() {
               return criteria;
               }
              
               @Override
               public List<String> getRestrictions() {
               return Arrays.asList(RESTRICTIONS);
               }
              
              }
              
              
              
              
              public class MarkupSearchCriteria {
               private String fulltext;
               private Integer committee;
              
               public String getFulltext() {
               return fulltext;
               }
              
               public void setFulltext(String fulltext) {
               this.fulltext = fulltext;
               }
              
               public Integer getCommittee() {
               return committee;
               }
              
               public void setCommittee(Integer committee) {
               this.committee = committee;
               }
              
              }
              


              I also tried to create a convertor for Committee:

              @Name("committeeConvertor")
              @org.jboss.seam.annotations.faces.Converter(forClass=Committee.class)
              public class CommitteeConvertor implements Converter, Serializable{
              
               @In
               private EntityManager entityManager;
              
               @Transactional
               public Object getAsObject(FacesContext context, UIComponent component, String value)
               {
               if (value != null)
               {
               try
               {
               Integer id = Integer.parseInt(value);
               if (id != null)
               {
               return entityManager.find(Committee.class, id);
               }
               }
               catch (NumberFormatException e) {
               }
               }
               return null;
               }
              
               public String getAsString(FacesContext context, UIComponent component, Object value)
               {
               if (value instanceof Committee)
               {
               Committee c = (Committee) value;
               return "" + c.getId();
               }
               else
               {
               return null;
               }
               }
              
              }
              


              What i want id to have cmtid synchronised with #{markupRepresentationList.criteria.committee}, so that query can use it.



              I've tried to explicitelly use the convertor but nothing works.

              Any clue ? Is there any limits by using the combination: event component, "param" in pages and s:selectItems? Any howto?

              I was able to make the application working when parameter is specified :
              MRPList.seam?cmtid=1

              But combo was not updated.

              Please help :((

              [/img]

              • 4. Re: Parameters not sent when using s:selectItems
                marius.oancea

                Problem solved.

                The solution was to modify the markupRepresentationList.criteria.committee to be a Commitee object not Integer.

                I think I tried this solution in the past but did not worked. I'm not sure why: either was a IE cache either the try was before I implemented the convertor.

                • 5. Re: Parameters not sent when using s:selectItems
                  marius.oancea

                  Now, I'm trying to allow multiselection. So I switched to h:selectManyListbox

                  In MarkupSearchCriteria:
                  private Committee committee;
                  becomes private Committee committee[];

                  It seems now this fails:



                  Failure is:

                  23:27:18,453 ERROR [SeamPhaseListener] uncaught exception
                  javax.el.ELException: java.lang.IllegalArgumentException: argument type mismatch
                   at javax.el.BeanELResolver.setValue(BeanELResolver.java:116)
                   at javax.el.CompositeELResolver.setValue(CompositeELResolver.java:68)
                   at com.sun.faces.el.FacesCompositeELResolver.setValue(FacesCompositeELResolver.java:93)
                   at org.jboss.el.parser.AstPropertySuffix.setValue(AstPropertySuffix.java:73)
                   at org.jboss.el.parser.AstValue.setValue(AstValue.java:84)
                   at org.jboss.el.ValueExpressionImpl.setValue(ValueExpressionImpl.java:249)
                   at org.jboss.seam.core.Expressions$1.setValue(Expressions.java:117)
                   at org.jboss.seam.navigation.Pages.applyConvertedValidatedValuesToModel(Pages.java:779)
                   at org.jboss.seam.navigation.Pages.postRestore(Pages.java:402)
                   at org.jboss.seam.jsf.SeamPhaseListener.postRestorePage(SeamPhaseListener.java:528)
                   at org.jboss.seam.jsf.SeamPhaseListener.afterRestoreView(SeamPhaseListener.java:374)
                   at org.jboss.seam.jsf.SeamPhaseListener.afterServletPhase(SeamPhaseListener.java:211)
                   at org.jboss.seam.jsf.SeamPhaseListener.afterPhase(SeamPhaseListener.java:184)
                   at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:280)
                   at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:117)
                   at javax.faces.webapp.FacesServlet.service(FacesServlet.java:244)
                   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
                   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
                   at org.jboss.seam.debug.hot.HotDeployFilter.doFilter(HotDeployFilter.java:68)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:85)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:44)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:141)
                   at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:281)
                   at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:60)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:58)
                   at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
                   at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
                   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                   at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
                   at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
                   at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
                   at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:230)
                   at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
                   at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:179)
                   at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
                   at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:84)
                   at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
                   at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
                   at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:157)
                   at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
                   at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:241)
                   at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
                   at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:580)
                   at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
                   at java.lang.Thread.run(Thread.java:595)
                  Caused by: java.lang.IllegalArgumentException: argument type mismatch
                   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
                   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
                   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                   at java.lang.reflect.Method.invoke(Method.java:585)
                   at javax.el.BeanELResolver.setValue(BeanELResolver.java:108)
                   ... 52 more
                  



                  Failure is in class "Pages" in method applyConvertedValidatedValuesToModel

                  Line that trigger the exception is valueExpression.setValue(object);


                  object is a string containing something like "[Lmymodel.Committee;@1afbdd4"

                  It seems that array cannot be user with "param" ?

                  Any solution to this? I found no example anywhere.

                  • 6. Re: Parameters not sent when using s:selectItems
                    marius.oancea

                    Another strange thing is that when i define the bind variable as List or Set the setter is never called:

                    public void setCommittee(List committee) {
                    this.committee = committee;
                    }


                    If i define as array, the setter is called but the exeption above is always thrown.

                    Any idea how to solve? Any known workaround?

                    • 7. Re: Parameters not sent when using s:selectItems
                      pmuir

                      I don't see where Pages comes into this.

                      Post the whole set of xhtml and backing beans from the beginning, I'm confused from your snippets above.

                      • 8. Re: Parameters not sent when using s:selectItems
                        marius.oancea

                        I will isolate my problem in a very small example. In few words, what is not working is to have a:



                        aListOfCommite is the variable behind selectManyListbox

                        I want to use that to rely on event scoped components (as in xxxxxList.xhtml generated with seam-gen).

                        • 9. Re: Parameters not sent when using s:selectItems
                          pmuir

                          This is clearly demonstrated in the ui example

                          • 10. Re: Parameters not sent when using s:selectItems
                            marius.oancea

                            Yes, except ui example does not use a thing like that:

                            <?xml version="1.0" encoding="UTF-8"?>
                            <page xmlns="http://jboss.com/products/seam/pages"
                             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                             xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd">
                            
                             <param name="firstResult" value="#{markupRepresentationList.firstResult}"/>
                             <param name="order" value="#{markupRepresentationList.order}"/>
                             <param name="from"/>
                             <param name="fulltext" value="#{markupRepresentationList.criteria.fulltext}"/>
                             <param name="cmtid" value="#{markupRepresentationList.criteria.committee}"/>
                            </page>
                            



                            In UI example in selectItems.xhtml, conversation is propagated and parsonHome.update is called.

                            In UI example i only find:
                            <page view-id="/selectItems.xhtml">
                            <begin-conversation join="true"/>



                            So only personId is bind with personHome.id. What I want it to bind a request parameter with my selectMany (cmtid with "#{markupRepresentationList.criteria.committee}")

                            But because of an unknown reason, in Pages.java line 779 (valueExpression.setValue(object)) object is not a list, set or array but a simple string containing "[Lmymodel.Committee;@1afbdd4"

                            • 11. Re: Parameters not sent when using s:selectItems
                              marius.oancea

                              In other words I do not want to use conversation propagation as in UI example but to transfor my selection into request parameters that makes the page bookmarkable.

                              All controls works fine (including selectOne but selectMany brings me that error)

                              • 12. Re: Parameters not sent when using s:selectItems
                                pmuir

                                Ok, I finally understand what you are trying to do! This is why its important to clearly structure your posts ;)

                                I don't see why you get that error when trying to apply request values to the model - that parameter should be empty when you submit the form, and populated in the render phase.

                                However, you probably need to write a converter to convert from the incoming String request value to a list.

                                • 13. Re: Parameters not sent when using s:selectItems
                                  marius.oancea

                                  simple code not working (the List is not set on submit):

                                  
                                  
                                  import java.util.ArrayList;
                                  import java.util.List;
                                  
                                  import org.jboss.seam.annotations.Name;
                                  
                                  @Name("testAction")
                                  public class TestAction {
                                   public List<Element> multiSelect;
                                  
                                   public List<Element> getMultiSelect() {
                                   return multiSelect;
                                   }
                                  
                                   public void setMultiSelect(List<Element> multiSelect) {
                                   this.multiSelect = multiSelect;
                                   }
                                  
                                   static public List<Element> allElements = new ArrayList<Element>();
                                   static {
                                   allElements.add(new Element(1, "One"));
                                   allElements.add(new Element(2, "Two"));
                                   allElements.add(new Element(3, "Three"));
                                   }
                                   public List<Element> getAllElements() {
                                   return allElements;
                                   }
                                  
                                   public void setAllElements(List<Element> allElements) {
                                   TestAction.allElements = allElements;
                                   }
                                  
                                  
                                  }
                                  
                                  
                                  
                                  import java.io.Serializable;
                                  import java.util.List;
                                  
                                  import javax.faces.component.UIComponent;
                                  import javax.faces.context.FacesContext;
                                  import javax.faces.convert.Converter;
                                  import javax.persistence.EntityManager;
                                  
                                  import org.jboss.seam.annotations.In;
                                  import org.jboss.seam.annotations.Name;
                                  import org.jboss.seam.annotations.Transactional;
                                  
                                  
                                  @Name("elementConvertor")
                                  @org.jboss.seam.annotations.faces.Converter(forClass=Element.class)
                                  public class ElementConvertor implements Converter, Serializable{
                                  
                                   @In
                                   private EntityManager entityManager;
                                  
                                   @Transactional
                                   public Object getAsObject(FacesContext context, UIComponent component, String value)
                                   {
                                   if (value != null)
                                   {
                                   try
                                   {
                                   Integer id = Integer.parseInt(value);
                                   if (id != null)
                                   {
                                   List<Element> allElements = TestAction.allElements;
                                   for (int i = 0; i < allElements.size(); i++) {
                                   if (allElements.get(i).getId().equals(id)) return allElements.get(i);
                                   }
                                   }
                                   }
                                   catch (NumberFormatException e) {
                                   }
                                   }
                                   return null;
                                   }
                                  
                                   public String getAsString(FacesContext context, UIComponent component, Object value)
                                   {
                                   if (value instanceof Element)
                                   {
                                   Element c = (Element) value;
                                   return "" + c.getId();
                                   }
                                   else
                                   {
                                   return null;
                                   }
                                   }
                                  
                                  }
                                  
                                  
                                  
                                  
                                  
                                  
                                  
                                  
                                  
                                  
                                  
                                  
                                  import java.util.ArrayList;
                                  import java.util.List;
                                  
                                  import org.jboss.seam.annotations.Name;
                                  
                                  @Name("testAction")
                                  public class TestAction {
                                   public List<Element> multiSelect;
                                  
                                   public List<Element> getMultiSelect() {
                                   return multiSelect;
                                   }
                                  
                                   public void setMultiSelect(List<Element> multiSelect) {
                                   this.multiSelect = multiSelect;
                                   }
                                  
                                   static public List<Element> allElements = new ArrayList<Element>();
                                   static {
                                   allElements.add(new Element(1, "One"));
                                   allElements.add(new Element(2, "Two"));
                                   allElements.add(new Element(3, "Three"));
                                   }
                                   public List<Element> getAllElements() {
                                   return allElements;
                                   }
                                  
                                   public void setAllElements(List<Element> allElements) {
                                   TestAction.allElements = allElements;
                                   }
                                  
                                  
                                  }
                                  
                                  
                                  
                                  === xList.page.xml====
                                  <?xml version="1.0" encoding="UTF-8"?>
                                  <page xmlns="http://jboss.com/products/seam/pages"
                                   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                   xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd">
                                  
                                   <param name="multiSelect" value="#{testAction.multiSelect}"/>
                                  </page>
                                  
                                  
                                  
                                  ===xList.xhtml=====
                                  <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                                   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                                  
                                  <ui:composition xmlns="http://www.w3.org/1999/xhtml"
                                   xmlns:s="http://jboss.com/products/seam/taglib"
                                   xmlns:ui="http://java.sun.com/jsf/facelets"
                                   xmlns:f="http://java.sun.com/jsf/core"
                                   xmlns:h="http://java.sun.com/jsf/html"
                                   xmlns:rich="http://richfaces.org/rich"
                                   template="layout/template.xhtml">
                                  
                                  <ui:define name="body">
                                  
                                   <h:messages globalOnly="true" styleClass="message" id="globalMessages"/>
                                  
                                   <h:form id="mySearch" styleClass="edit" >
                                  
                                   <rich:simpleTogglePanel label="Test submit multiple selection" switchType="ajax">
                                  
                                   <s:decorate template="layout/display.xhtml">
                                   <ui:define name="label">Please select some objects</ui:define>
                                   <h:selectManyListbox id="multiSelect" value="#{testAction.multiSelect}" >
                                   <s:selectItems value="#{testAction.allElements}"
                                   var="element"
                                   label="#{element.name}"/>
                                   </h:selectManyListbox>
                                  
                                   </s:decorate>
                                  
                                  
                                  
                                  
                                   </rich:simpleTogglePanel>
                                  
                                   <div class="actionButtons">
                                   <h:commandButton id="search" value="Search" action="/test/test.xhtml" />
                                   </div>
                                  
                                   </h:form>
                                  
                                   #{testAction.multiSelect}
                                  
                                  
                                  </ui:define>
                                  
                                  </ui:composition>
                                  
                                  




                                  testAction.setMultiSelect() is never called.


                                  • 14. Re: Parameters not sent when using s:selectItems
                                    marius.oancea

                                    Problem is 99% solved by doing the following:

                                    explicitelly added element convertor as Pete sugessted:

                                    <h:selectManyListbox id="theList" value="#{testAction.multiSelect}" >
                                     <s:selectItems value="#{testAction.allElements}" var="element" label="#{element.name}" />
                                     <f:converter converterId="elementConvertor" />
                                     </h:selectManyListbox>




                                    In param tag I called a convertor for the list parameter:
                                    <?xml version="1.0" encoding="UTF-8"?>
                                    <page xmlns="http://jboss.com/products/seam/pages"
                                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                                     xsi:schemaLocation="http://jboss.com/products/seam/pages http://jboss.com/products/seam/pages-2.0.xsd">
                                     <param name="theList" converterId="elementListConvertor" value="#{testAction.multiSelect}" />
                                    </page>


                                    The convertor is implemented as below:
                                    @org.jboss.seam.annotations.faces.Converter
                                    @Name("elementListConvertor")
                                    public class ElementListParameterConvertor implements Converter, Serializable {
                                     @In
                                     private EntityManager entityManager;
                                    
                                     @Transactional
                                     public Object getAsObject(FacesContext context, UIComponent component, String value) {
                                     if (value != null) {
                                     String[] allIds = value.split(" ");
                                     List<Element> theList = new ArrayList<Element>();
                                     for (int i = 0; i < allIds.length; i++) {
                                     String id = allIds;
                                     if (id == null || id.trim().length() == 0) continue;
                                     theList.add(findElement(id));
                                     }
                                     return theList;
                                     }
                                     return null;
                                     }
                                    
                                     private Element findElement(String id) {
                                     List<Element> allElements = TestAction.allElements;
                                     for (int i = 0; i < allElements.size(); i++) {
                                     if (allElements.get(i).getId().equals(new Integer(id))) return allElements.get(i);
                                     }
                                     return null;
                                     }
                                    
                                     public String getAsString(FacesContext context, UIComponent component, Object value) {
                                     if (value instanceof List) {
                                     List<Element> theList = (List<Element>) value;
                                     String s = "";
                                    
                                     for (Iterator iterator = theList.iterator(); iterator.hasNext();) {
                                     if (s.length() != 0) s += " ";
                                     Element element = (Element) iterator.next();
                                     s += element.id;
                                    
                                     }
                                     return s;
                                     }
                                     return null;
                                     }
                                    
                                     }
                                    



                                    Having that done, all works (without need for any conversation propagation and so on).

                                    Also if you call in the browser "localhost:8080/test/xList.seam?theList=1%202" the entries in "select" are selected as expected.

                                    The single point that does not work is the url when you submit the page:
                                    - point the browser to "localhost:8080/test/xList.seam?theList=1%202"
                                    - system shows first two entries in list selected (AS EXPECTED)
                                    - select the third entry and press submit
                                    - system update the browser location to "localhost:8080/test/xList.seam" (WRONG, the correct is localhost:8080/test/xList.seam?theList=1%202%203)

                                    For input Fields and selectOne, the system behaves as expected - parameter is automatically added to the URL. The problem is specific to selectManyListbox component.

                                    Additionally, if you have a :

                                    <s:link view="/xList.xhtml"
                                     value="Test List"
                                     propagation="none"/>


                                    the select multi parameter is not automatically added (while an input filed and selectOne is).


                                    Thanx again to Pete Muir for give me the valuable hints.