4 Replies Latest reply on Mar 10, 2008 1:26 PM by tulip

    RichFaces ShuttleList sample doesn't work in a Seam framewor

    todd.nash

      In an effort to validate the errors with the ShuttleList in my own pages, I decided to see if the sample works in a Seam framework.

      I have found that many of the Richfaces components don't work well when used in a Seam framework. Are you guys testing anything using Seam?

      I only modified the sample code enough to avoid any Seam errors. Specifically, I had to remove the UIEventsBouncer because org.ajax4jsf.component.UIDataAdaptor doesn't exist in the Richfaces jars and you can't include the ajax4jsf jars when using Seam.

      The following error occurs in both 3.1.3 and 3.1.4.

      When I click the submit button on the page containing a ListShuttle I get the following error:

      javax.el.PropertyNotFoundException: /documents/listShuttle.xhtml @52,55 value="#{item.name}": Property 'name' not found on type java.lang.String

      Here is the xhtml page I modified from the samples:

      <!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:a4j="http://richfaces.org/a4j"
       xmlns:rich="http://richfaces.org/rich"
       template="../layout/template.xhtml">
      
      <ui:define name="body">
      
      <style type="text/css">
       .zebraCell1 {
       background-color: yellow;
       }
      
       .zebraCell2 {
       background-color: fuchsia;
       }
      
       .zebraRow1 * {
       color: white;
       }
      
       .zebraRow2 * {
       color: navy;
       }
      
       .downControlClass {
       font-weight: bold;
       }
      </style>
      <a4j:outputPanel ajaxRendered="true">
       <h:messages/>
      </a4j:outputPanel>
      
      <h:form id="form">
       <rich:listShuttle id="listShuttle" var="item" sourceValue="#{listShuttleDemoBean.source}"
       targetValue="#{listShuttleDemoBean.target}"
       orderControlsVisible="#{listShuttleDemoBean.orderControlsVisible}"
       fastOrderControlsVisible="#{listShuttleDemoBean.fastOrderControlsVisible}"
       moveControlsVisible="#{listShuttleDemoBean.moveControlsVisible}"
       fastMoveControlsVisible="#{listShuttleDemoBean.fastMoveControlsVisible}"
       converter="#{converter}"
       onorderchanged="orderChanged(event)"
      
       sourceSelection="#{listShuttleDemoBean.sourceSelection}"
       targetSelection="#{listShuttleDemoBean.targetSelection}"
       switchByClick="#{listShuttleDemoBean.switchByClick}">
       <h:column><h:outputText value="#{item.name}"/></h:column>
       <h:column><h:outputText value="#{item.price}"/></h:column>
       </rich:listShuttle>
      
       <f:verbatim>
       <div id="cdiv" style="width: 600px; height: 200px; overflow: auto;"></div>
      
       <script>
       function orderChanged( event )
       {
       var cdiv = $('cdiv');
       Element.clearChildren(cdiv);
       cdiv.appendChild(document.createTextNode(Object.inspect($H(event))));
       }
       </script>
       </f:verbatim>
      
       <h:panelGrid columns="2">
       <h:outputText value="Order controls visible:"/>
       <h:selectBooleanCheckbox value="#{listShuttleDemoBean.orderControlsVisible}"/>
      
       <h:outputText value="Fast order controls visible:"/>
       <h:selectBooleanCheckbox value="#{listShuttleDemoBean.fastOrderControlsVisible}"/>
      
       <h:outputText value="Move controls visible:"/>
       <h:selectBooleanCheckbox value="#{listShuttleDemoBean.moveControlsVisible}"/>
      
       <h:outputText value="Fast move controls visible:"/>
       <h:selectBooleanCheckbox value="#{listShuttleDemoBean.fastMoveControlsVisible}"/>
      
       <h:outputText value="Switch by click:"/>
       <h:selectBooleanCheckbox value="#{listShuttleDemoBean.switchByClick}"/>
      
       </h:panelGrid>
      
       <a4j:status startText="...start..."/>
       <a4j:commandButton value="Ajax Submit" reRender="listShuttle"/>
      
       <h:commandButton value="Submit"/>
       <h:commandButton value="Submit Immediate" immediate="true"/>
       <h:commandButton value="Start over" action="#{listShuttleDemoBean.startOver}" immediate="true" rendered="false"/>
      
      
       <rich:listShuttle onlistchanged="alert(event.type)" id="listShuttle2" var="item"
       sourceValue="#{listShuttleDemoBean.zebraItems}"
       columnClasses="zebraCell1, zebraCell2" rowClasses="zebraRow1, zebraRow2"
       moveControlsVerticalAlign="top" orderControlsVerticalAlign="bottom"
       downControlClass="downControlClass">
       <rich:column width="10px">
       <f:facet name="header">
       <h:outputText value="Name"/>
       </f:facet>
       <h:outputText value="#{item}"/>
       </rich:column>
       <rich:column width="10px">
       <f:facet name="header">
       <h:outputText value="Name"/>
       </f:facet>
       <h:outputText value="#{item}"/>
       </rich:column>
       <rich:column width="10px">
       <f:facet name="header">
       <h:outputText value="Name"/>
       </f:facet>
       <h:outputText value="#{item}"/>
       </rich:column>
       <h:column>
       <f:facet name="header">
       <h:outputText value="Name"/>
       </f:facet>
       <h:outputText value="#{item}"/>
       </h:column>
       </rich:listShuttle>
      </h:form>
      </ui:define>
      </ui:composition>


      Here is the ListShuttleDemoBean:
      package com.executorsresource.plo.session;
      
      import org.jboss.seam.ScopeType;
      import org.jboss.seam.annotations.Name;
      import org.jboss.seam.annotations.Scope;
      import org.jboss.seam.annotations.Destroy;
      
      import javax.ejb.Stateful;
      import javax.ejb.Remove;
      import javax.faces.context.FacesContext;
      import java.util.Collection;
      import java.util.Random;
      
      /**
       * @author Nick Belaevski
       * mailto:nbelaevski@exadel.com
       * created 16.11.2007
       */
      @Stateful
      @Scope( ScopeType.SESSION )
      @Name( "listShuttleDemoBean" )
      public class ListShuttleDemoBean implements ListShuttleDemoLocal
      {
      
       private Collection sourceSelection;
       private Collection targetSelection;
      
       private String[] zebraItems = new String[]{"0", "1", "2", "3", "4"};
      
       private ListShuttleOptionItem[] source;
      
       private ListShuttleOptionItem[] target;
      
       private Integer[] numbers = new Integer[10];
      
       private boolean moveControlsVisible = true;
       private boolean fastMoveControlsVisible = true;
      
       private boolean orderControlsVisible = true;
       private boolean fastOrderControlsVisible = true;
      
       private boolean switchByClick = false;
      
       public boolean isSwitchByClick()
       {
       return switchByClick;
       }
      
       public void setSwitchByClick( boolean switchByClick )
       {
       this.switchByClick = switchByClick;
       }
      
       public ListShuttleDemoBean()
       {
       super();
      
       source = new ListShuttleOptionItem[3];
       for ( int i = 0; i < source.length; i++ )
       {
       source = new ListShuttleOptionItem( "Source Item " + i, new Random().nextInt( 40 ) );
       }
      
       target = new ListShuttleOptionItem[5];
       for ( int i = 0; i < target.length; i++ )
       {
       target = new ListShuttleOptionItem( "Target Item " + i, new Random().nextInt( 40 ) );
       }
      
       for ( int i = 0; i < numbers.length; i++ )
       {
       numbers = new Random().nextInt( 256 );
       }
       }
      
       public ListShuttleOptionItem[] getSource()
       {
       return source;
       }
      
       private static String arrayToString( Object[] objects )
       {
       StringBuffer result = new StringBuffer();
       if ( objects == null )
       {
       result.append( "null" );
       }
       else
       {
       int iMax = objects.length - 1;
       if ( iMax == -1 )
       {
       result.append( "[]" );
       }
       else
       {
       result.append( '[' );
       for ( int i = 0; i <= iMax; i++ )
       {
       result.append( objects );
       if ( i != iMax )
       {
       result.append( ", " );
       }
       }
       result.append( ']' );
       }
       }
      
       return result.toString();
       }
      
       public void setSource( ListShuttleOptionItem[] source )
       {
       System.out.print( "ListShuttleDemoBean.setSource() " );
       System.out.println( arrayToString( source ) );
      
       this.source = source;
       }
      
       public ListShuttleOptionItem[] getTarget()
       {
       System.out.println( "ListShuttleDemoBean.getTarget()" );
       if (target != null)
       {
       System.out.println( arrayToString( target ) );
       }
       return target;
       }
      
       public void setTarget( ListShuttleOptionItem[] target )
       {
       System.out.println( "ListShuttleDemoBean.setTarget() " + arrayToString( target ) );
       this.target = target;
       }
      
       public void startOver()
       {
       FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove( "listShuttleDemoBean" );
       }
      
       public boolean isMoveControlsVisible()
       {
       return moveControlsVisible;
       }
      
       public void setMoveControlsVisible( boolean moveControlsVisible )
       {
       this.moveControlsVisible = moveControlsVisible;
       }
      
       public boolean isFastMoveControlsVisible()
       {
       return fastMoveControlsVisible;
       }
      
       public void setFastMoveControlsVisible( boolean fastMoveControlsVisible )
       {
       this.fastMoveControlsVisible = fastMoveControlsVisible;
       }
      
       public boolean isOrderControlsVisible()
       {
       return orderControlsVisible;
       }
      
       public void setOrderControlsVisible( boolean orderControlsVisible )
       {
       this.orderControlsVisible = orderControlsVisible;
       }
      
       public boolean isFastOrderControlsVisible()
       {
       return fastOrderControlsVisible;
       }
      
       public void setFastOrderControlsVisible( boolean fastOrderControlsVisible )
       {
       this.fastOrderControlsVisible = fastOrderControlsVisible;
       }
      
       public Collection getSourceSelection()
       {
       return sourceSelection;
       }
      
       public void setSourceSelection( Collection sourceSelection )
       {
       System.out.println( "ListShuttleDemoBean.setSourceSelection() " + sourceSelection );
       this.sourceSelection = sourceSelection;
       }
      
       public Collection getTargetSelection()
       {
       return targetSelection;
       }
      
       public void setTargetSelection( Collection targetSelection )
       {
       System.out.println( "ListShuttleDemoBean.setTargetSelection() " + targetSelection );
       this.targetSelection = targetSelection;
       }
      
       public Integer[] getNumbers()
       {
       return numbers;
       }
      
       public void setNumbers( Integer[] numbers )
       {
       for ( int i = 0; i < numbers.length; i++ )
       {
       System.out.print( numbers.getClass().getSimpleName() + " " );
       }
       System.out.println();
      
       this.numbers = numbers;
       }
      
       public String[] getZebraItems()
       {
       return zebraItems;
       }
      
       public void setZebraItems( String[] zebraItems )
       {
       this.zebraItems = zebraItems;
       }
      
       @Remove
       @Destroy
       public void destroy()
       {
       }
      
       }
      


      Here is the converter:

      package com.executorsresource.plo.session;
      
      import javax.faces.component.UIComponent;
      import javax.faces.context.FacesContext;
      import javax.faces.convert.Converter;
      
      
      /**
       */
      public class ListShuttleOptionItemConverter implements Converter
      {
      
       /* (non-Javadoc)
       * @see javax.faces.convert.Converter#getAsObject(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.String)
       */
       public Object getAsObject( FacesContext context, UIComponent component, String value )
       {
      
       int index = value.indexOf( ':' );
      
       ListShuttleOptionItem item = new ListShuttleOptionItem( value.substring( 0, index ), Integer.valueOf( value.substring( index + 1 ) ) );
       return item;
       }
      
       /* (non-Javadoc)
       * @see javax.faces.convert.Converter#getAsString(javax.faces.context.FacesContext, javax.faces.component.UIComponent, java.lang.Object)
       */
       public String getAsString( FacesContext context, UIComponent component, Object value )
       {
      
       ListShuttleOptionItem optionItem = ( ListShuttleOptionItem ) value;
       return optionItem.getName() + ":" + optionItem.getPrice();
       }
      
      }
      
      


      Here is the option item:

      package com.executorsresource.plo.session;
      
      import java.io.Serializable;
      
      /**
       * @author Nick Belaevski
       * mailto:nbelaevski@exadel.com
       * created 16.11.2007
       */
      public class ListShuttleOptionItem implements Serializable
      {
      
       private static final long serialVersionUID = -8460586062149160189L;
       private String name;
       private int price;
      
       public ListShuttleOptionItem()
       {
       }
      
       public ListShuttleOptionItem( String name, int price )
       {
       super();
       this.name = name;
       this.price = price;
       }
      
       public String getName()
       {
       return name;
       }
      
       public void setName( String name )
       {
       this.name = name;
       }
      
       public int getPrice()
       {
       return price;
       }
      
       public String toString()
       {
       return this.getClass().getSimpleName() + " [" + name + "] by " + price;
       }
      
       public void action()
       {
       System.out.println( "ListShuttleOptionItem.action() " + this.toString() );
       }
      
       public int hashCode()
       {
       final int prime = 31;
       int result = 1;
       result = prime * result + ( ( name == null ) ? 0 : name.hashCode() );
       result = prime * result + price;
       return result;
       }
      
       public boolean equals( Object obj )
       {
       if ( this == obj )
       {
       return true;
       }
       if ( obj == null )
       {
       return false;
       }
       if ( getClass() != obj.getClass() )
       {
       return false;
       }
       ListShuttleOptionItem other = ( ListShuttleOptionItem ) obj;
       if ( name == null )
       {
       if ( other.name != null )
       {
       return false;
       }
       }
       else if ( !name.equals( other.name ) )
       {
       return false;
       }
       if ( price != other.price )
       {
       return false;
       }
       return true;
       }
      }
      


        • 1. Re: RichFaces ShuttleList sample doesn't work in a Seam fram
          loveena_k

          I am also trying to use listShuttle with Seam framework and get the same error when trying to submit the page with ListShuttle. I am using version 3.1.4

          SEVERE: Error Rendering View[/createHierarchy.xhtml]
          javax.faces.FacesException: javax.el.PropertyNotFoundException: /createHierarchy.xhtml @46,63 value="#{entity.entityDefI
          d}": Property 'entityDefId' not found on type java.lang.String


          Anyone any suggestions ?

          • 2. Re: RichFaces ShuttleList sample doesn't work in a Seam fram
            poisoner

            I get the same. With richfaces in portlet.

            • 3. Re: RichFaces ShuttleList sample doesn't work in a Seam fram
              gabir1

               

              "poisoner" wrote:
              I get the same. With richfaces in portlet.


              Hi guys,

              I've managed to work with seam and listShuttle

              here is some code :

              <rich:listShuttle id="available_groups" sourceValue="#{available_groups}"
               targetValue="#{selectedGroups}" var="gr"
               listHeight="300" listWidth="300"
               sourceCaptionLabel="Available Groups"
               targetCaptionLabel="Currently Selected Groups"
               converter="groupConverter" >
              
               <rich:column >
              
               <h:outputText value="#{gr.name}" />
              
               </rich:column>
              
               </rich:listShuttle>


              @Begin(join=true)
               @Factory("available_groups")
               public List<Group> getGroups(){
              
               List groups = groupService.getGroups();
               return groups;
              
               }


              and

              @Out(required=false)
               List<Group> selectedGroups = new ArrayList<Group>();


              You must have a converter and equals() on your entity.

              Maybe this helps.

              Cheers.

              • 4. Re: RichFaces ShuttleList sample doesn't work in a Seam fram
                tulip

                 

                You must have a converter and equals() on your entity


                Could you please post your converter code ? Thanks