Announcement Announcement Module
Collapse
No announcement yet.
RichFaces/Ajax4JSF integration now available Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • jeremyg484
    started a topic RichFaces/Ajax4JSF integration now available

    RichFaces/Ajax4JSF integration now available

    We have completed testing the use of RichFaces in combination with Spring Faces and some special integration support has been added and is available in the latest nightly snapshot of RC1.

    A couple of minor things had to be tweaked in order to allow RichFaces to work on its own with the Web Flow JSF integration. Additionally, we've added a special RichFacesAjaxHandler class that can be configured as a property on your FlowController that will allow the RichFaces components to be used alongside the Spring Faces components in the same page. This is especially useful as certain features such as the popup support are natively handled by the Spring Javascript library used by the Spring Faces components.

    Configuring the RichFacesAjaxHandler is simple:
    Code:
    <bean id="flowController" class="org.springframework.webflow.mvc.FlowController">
    	<constructor-arg ref="flowExecutor" />
    	<property name="ajaxHandler">
    		<bean class="org.springframework.faces.mvc.richfaces.RichFacesAjaxHandler"/>
    	</property>
    </bean>
    One nice part of the integration is that you can continue to use the <render> tag in your flow definition to control which components are re-rendered in response to an Ajax request. Doing so just requires binding the reRender attribute of your RichFaces Ajax component to a special flow variable called flowRenderFragments. For example the "More Results" command link in the reviewHotels view of the Spring Travel sample app becomes:

    Code:
    <a4j:commandLink id="nextPageLink" value="More Results" action="next" reRender="#{flowRenderFragments}" rendered="#{not empty hotels and hotels.rowCount == searchCriteria.pageSize}"/>
    So for those of you out there using RichFaces with Web Flow (especially those of you who were encountering problems), I encourage you to grab the latest nightly build of RC1 from the snapshots repo and give it a try and let us know if you encounter any further problems.

    - Jeremy

  • zeppelin71
    replied
    what about with portlets?

    I sort of have Richfaces working with Webflow and Oracle Weblogic Portal 10gR3.

    One issue is that the portal flowcontroller for webflow does not have an "ajaxHandler" property. The non-portlet flowcontroller does, and the above instructions include having to set this property.

    Does anyone have insight into this?

    thanks,
    Markus

    Leave a comment:


  • jotereh
    replied
    I have tested this example in the page "More Results" and an other simple example. But The ajax response/fragment is not rendered.
    Boot Camp

    Leave a comment:


  • lucky99
    replied
    HI,

    After testing more Rich Faces components I would like to share some information regarding the update problem.





    Appointment Making , Appointment Setting Services

    Leave a comment:


  • cgs
    replied
    Ah, I have this in my config:

    Code:
    	<bean id="faceletsViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    		<property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
    		<property name="prefix" value="/WEB-INF/views/" />
    		<property name="suffix" value=".xhtml" />
    	</bean>

    Leave a comment:


  • julian
    replied
    That didn't seem to work for me. In my case I am using Facelets and .XHTML extensions. If I leave the view-factory-creator out, I get the following stack trace:

    Code:
    Caused by: java.lang.IllegalArgumentException: Unsupported view type /WEB-INF/flows/search/beginSearch.xhtml only types supported by this FlowViewResolver implementation are [.jsp] and [.jspx]
        at org.springframework.webflow.mvc.builder.FlowResourceFlowViewResolver.getViewInternal(FlowResourceFlowViewResolver.java:94)
        at org.springframework.webflow.mvc.builder.FlowResourceFlowViewResolver.resolveView(FlowResourceFlowViewResolver.java:72)
        at org.springframework.webflow.mvc.view.AbstractMvcViewFactory.getView(AbstractMvcViewFactory.java:80)
        at org.springframework.webflow.engine.ViewState.resume(ViewState.java:193)
        at org.springframework.webflow.engine.Flow.resume(Flow.java:545)
        at org.springframework.webflow.engine.impl.FlowExecutionImpl.resume(FlowExecutionImpl.java:259)
        ... 86 more
    Due to this, it seems I do need to keep that configuration in place.

    Leave a comment:


  • cgs
    replied
    The flow-builder-services in the faces namespace (http://www.springframework.org/schema/faces http://www.springframework.org/schem...-faces-2.0.xsd) uses that view factory creator by default.

    Leave a comment:


  • julian
    replied
    cgs,

    Why are you suggesting that I remove the JSFViewFactoryCreator reference? I have posted these configurations as a working example of what I've put together to enable RichFaces and Spring Webflow.

    Thanks,
    Julian

    Leave a comment:


  • cgs
    replied
    Code:
        <flow:flow-builder-services id="facesFlowBuilderServices" development="true" view-factory-creator="viewFactoryCreator"/>
        
    <!-- Since we are using JSF, we need to configure the view factory in place of a ViewResolver bean (aka no view resolver bean is being configured for XHTML requests to Facelet based pages -->
        <bean id="viewFactoryCreator" class="org.springframework.faces.webflow.JsfViewFactoryCreator"/>
    That should be able to be replaced with:

    Code:
    <faces:flow-builder-services id="facesFlowBuilderServices" development="true" />

    Leave a comment:


  • julian
    replied
    Now I'll show some sample XHTML that calls webflows:

    Code:
        <ui:define name="content">
            <f:view>
                <div id="search" >
                <span class="errors">
                    <h:messages globalOnly="true" /> 
                </span>
                <h2>Search</h2>
                <h:form id="mainForm">
                    <fieldset>
                    <div class="field">
                    <div class="label"><h:outputLabel for="searchString">Search String:</h:outputLabel>
                    </div>
                    <div class="input">
                        <sf:clientTextValidator
                            promptMessage="Search for elements by their identifier."  allowBlank="false" msgDisplay="block" msgClass="errors">
                            <h:inputText id="criteriaId" value="#{criteria.ID}"/>
                        </sf:clientTextValidator></div>
                        
                    </div>
                    <div class="buttonGroup">
                       <!-- process the DOM/ID elements contained in the mainForm and use the Spring supplied variable flowRenderFragments to handle the results and interact with RichFaces-->
                        <a4j:commandButton id="find"
                            value="Find" action="search" processIds="mainForm" reRender="#{flowRenderFragments}"
                            oncomplete="showDiv({duration:0.75});">
                        </a4j:commandButton>
                        <!-- This effect is called when the AJAX request is completed and highlights the results for a brief moment-->
                        <rich:effect  name="showDiv" for="table" type="Highlight" />
                    </div>
                    </fieldset>
                </h:form></div>
            </f:view>
            <br/>
            <f:view>
                <div id="section" class="section" >
                    <h2>Current Results:</h2>
                    <h:form id="form">
                        <span class="errors">
                            <h:messages globalOnly="true" /> 
                        </span>
                        <!-- This is where the results are displayed as defined in the webflow's transition render fragment definition-->
                        <a4j:outputPanel id="searchResultsFragment">
                        
                        <h:outputText value="Nothing Found" rendered="#{empty results }" />
        
                        <rich:dataTable id="table" value="#{results}" var="result" 
                            rendered="#{!empty results}">
                                         
                            <f:facet name="header">
                                <h:outputText value="Current Results" />
                            </f:facet>
                            <rich:column>
                                <f:facet name="header">ID</f:facet>
                                #{result.ID}
                            </rich:column>
                            <rich:column>
                                <f:facet name="header">Name</f:facet>
                                #{result.name}
                            </rich:column>
                            <rich:column>
                                <f:facet name="header">Note</f:facet>
                                #{result.note}
                            </rich:column>
                        </rich:dataTable>
                        </a4j:outputPanel>
                        
                        </h:form>
                        
                </div>
            </f:view>
    ...and then the flow that handles this initial view state fragment...

    Code:
    <var name="criteria" class="com.company.domain.Criteria"/>
           
        <!-- according to config, the view file is in the same directory as this flow-->
        <view-state id="listAll" view="beginSearch.xhtml">
            
            
            <transition on="search">
                <!-- Call the service which queries the underlying datastore and have it return 1 result with a 0 offset of results-->
                <evaluate expression="resultManager.executeSelect(criteria,1,0)" result="flowScope.medications"/>
                <render fragments="searchResultsFragment"/>
            </transition>
            
            ....
        </view-state>
    I hope my sample configs here enable others to find their way through this maze! I understand much of this is available in bits and pieces throughout the interwebs, but I thought another example can't hurt.

    Leave a comment:


  • julian
    replied
    Fortunately I was able to get RichFaces and AJAX to work with my own solution. I had to make many changes to finally get it working so I can't recall exactly what was needed. I did run into issue describe by the link in the last post whereby I had to add a DIV in between different elements. Also, I had to ensure that my bean was a session scoped bean so that I could continue working on it between requests (not shown in the snippets below). I had to also make sure the RichFaces AJAX Handler was configure for the the flow handler bean. I wish I could remember all the moving parts. Here are relevant portions of my configs:

    Spring Application Context Config for Webflow:

    Code:
        <!--  Webflow Mappings -->
        <!-- Enables FlowHandler URL mapping -->
        <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerAdapter">
            <property name="flowExecutor" ref="flowExecutor" />
            <property name="ajaxHandler">
               <!-- Add the RichFacesAjaxHandler so Spring Faces elements can live side by side with RichFaces and RichFaces can "see" Spring Faces elements -->
                <bean class="org.springframework.faces.richfaces.RichFacesAjaxHandler"/>
            </property>
        </bean>
            
        <!-- Maps request paths to flows in the flowRegistry;
         e.g. a path of /hotels/booking looks for a flow with id "hotels/booking" -->        
        <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
            <property name="flowRegistry" ref="flowRegistry"/>
    <!-- try to load flows first before falling back to other handler mappings in place (e.g. traditional MVC handlers -->
            <property name="order" value="0"/>
        </bean>
    
        <!-- Executes flows: the central entry point into the Spring Web Flow system -->
        <flow:flow-executor id="flowExecutor">
            <flow:flow-execution-listeners>
                <flow:listener ref="hibernateFlowExecutionListener"/>
                <flow:listener ref="securityFlowExecutionListener"/>
            </flow:flow-execution-listeners>
        </flow:flow-executor>
    
        <!-- The registry of executable flow definitions -->
        <flow:flow-registry id="flowRegistry" flow-builder-services="facesFlowBuilderServices" base-path="/WEB-INF/flows/">
            <flow:flow-location-pattern value="/**/*-flow.xml"/>
        </flow:flow-registry>
    
        <flow:flow-builder-services id="facesFlowBuilderServices" development="true" view-factory-creator="viewFactoryCreator"/>
        
    <!-- Since we are using JSF, we need to configure the view factory in place of a ViewResolver bean (aka no view resolver bean is being configured for XHTML requests to Facelet based pages -->
        <bean id="viewFactoryCreator" class="org.springframework.faces.webflow.JsfViewFactoryCreator"/>
    
    <!-- Create a bean to expose the hibernate session as a persistence context in any given flow/  this can be replace with a JPAFlowExecutionListener if using JPA -->
        <bean id="hibernateFlowExecutionListener" class="org.springframework.webflow.persistence.HibernateFlowExecutionListener">
            <constructor-arg ref="sessionFactory"/>
            <constructor-arg ref="transactionManager"/>
        </bean>
    
           <!-- Installs a listener to apply Spring Security authorities -->
           <bean id="securityFlowExecutionListener"
             class="org.springframework.webflow.security.SecurityFlowExecutionListener"/>
             
        <!--  End Webflow Mappings -->
    Faces Config:
    Code:
    <?xml version="1.0"?>
    <!DOCTYPE faces-config PUBLIC
      "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
      "http://java.sun.com/dtd/web-facesconfig_1_0.dtd">
    
    <faces-config>
        <application>
            <!-- Enables Facelets -->
            <view-handler>com.sun.facelets.FaceletViewHandler</view-handler>  
        </application>
    </faces-config>
    Web.xml Snippets:
    Code:
        <!-- Making the RichFaces skin spread to standard HTML controls -->
        <context-param>
            <param-name>org.richfaces.CONTROL_SKINNING</param-name>
            <param-value>enable</param-value>
        </context-param>
        <context-param>        
            <param-name>org.ajax4jsf.SKIN</param-name>
            <param-value>darkX</param-value>
        </context-param>  
    
    
        <context-param>
            <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
            <param-value>.xhtml</param-value>
        </context-param>
    
        <!-- Enables special Facelets debug output during development -->
        <context-param>
            <param-name>facelets.DEVELOPMENT</param-name>
            <param-value>true</param-value>
        </context-param>
    
        <!-- Causes Facelets to refresh templates during development -->
          <context-param>
              <param-name>facelets.REFRESH_PERIOD</param-name>
              <param-value>1</param-value>
          </context-param>
          
        <!---->
        <filter>
            <display-name>RichFaces Filter</display-name>
            <filter-name>richfaces</filter-name>
            <filter-class>org.ajax4jsf.Filter</filter-class>
        </filter>
    
        <filter-mapping>
            <filter-name>richfaces</filter-name>
           <!-- springapp is the name of the Dispatch Servlet-->
            <servlet-name>springapp</servlet-name>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>INCLUDE</dispatcher>
        </filter-mapping>
    .....continue web.xml...

    Code:
       <!-- Mappings for the resource servlet so CSS and Javascript (e.g. Dojo) files can be loaded when needed by RichFaces or Spring Faces -->
        <servlet>
            <servlet-name>Resource Servlet</servlet-name>
            <servlet-class>org.springframework.js.resource.ResourceServlet
            </servlet-class>
            <load-on-startup>0</load-on-startup>
        </servlet>
    
        <servlet-mapping>
            <servlet-name>Resource Servlet</servlet-name>
            <url-pattern>/resources/*</url-pattern>
        </servlet-mapping>
    ...more web.xml...
    Code:
        <!-- Just here so the JSF implementation can initialize, *not* used at runtime -->
        <servlet>
            <servlet-name>Faces Servlet</servlet-name>
            <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
            <load-on-startup>3</load-on-startup>
        </servlet>
    
        <!-- Just here so the JSF implementation can initialize -->
        <servlet-mapping>
            <servlet-name>Faces Servlet</servlet-name>
            <url-pattern>*.faces</url-pattern>
        </servlet-mapping>
    ...web.xml cont'd...
    Code:
        <!-- Add mapping for flows so we can route all requests to /flows/** by convention;  this isolates requests to the flow handler from other elements-->
        <servlet-mapping>
            <servlet-name>springapp</servlet-name>
            <url-pattern>/flows/*</url-pattern>
        </servlet-mapping>
    Ok, so those are what I believe to be the relevant sections of the configuration that I needed to get everything working. Most of this doesn't look much different than what you'll see in the various docs and samples. Next, I'll post a sample flow and JSF snippet.
    Last edited by julian; Jan 1st, 2010, 12:41 PM.

    Leave a comment:


  • cgs
    replied
    Originally posted by julian View Post
    Hi all,

    I have attempted several ways to integrate JSF with Spring Webflow, but all seem to fail. Rich Faces is my preferred approach, so I downloaded the samples at:
    If you are still having difficulty and you are using ~RichFaces 3.3.2 SR1 and SWF 2.0.8, try my workaround here.

    Leave a comment:


  • julian
    replied
    Still doesn't work

    Hi all,

    I have attempted several ways to integrate JSF with Spring Webflow, but all seem to fail. Rich Faces is my preferred approach, so I downloaded the samples at:

    http://jira.springframework.org/browse/SWF-462

    Unfortunately, the AJAX features of the hotel search results table doesn't appear to work at all. When I click one of the table headers a POST occurs, but the response is a full blown HTML file, which has no effect on the rich table. Has anyone gotten these samples to work out of the box? If not, I'd love to know if anyone has ever gotten any of the JSF/RichFaces/Webflow integration to work.

    Thanks,
    Julian
    Last edited by julian; Dec 19th, 2009, 01:05 AM. Reason: Updated JIRA issue link

    Leave a comment:


  • kjeldpaw
    replied
    Originally posted by kjeldpaw View Post
    Hi,
    I have a problem using <a4j:support> in a form with multiple input components. The support action is only triggered when I add a <4j:region> tag to the component.

    I can see a request in the tomcat log when the region tag is not used.

    Example:

    Code:
    <a4j:region renderRegionOnly="false">	 
    	<h:selectOneListbox id="selectPeriodInterval" value="#{reportCriteria.periodInterval}" size="1">
    		<a4j:support id="supportPeriodInterval" event="onchange" action="updateInterval" reRender="#{flowRenderFragments}"/>
    		<f:selectItem  itemLabel="#{msg.emails_report_form_period_default}" itemValue="0"/>
    		<f:selectItem  itemLabel="#{msg.emails_report_form_period_1}" itemValue="1"/>
    		<f:selectItem  itemLabel="#{msg.emails_report_form_period_2}" itemValue="2"/>
    		<f:selectItem  itemLabel="#{msg.emails_report_form_period_3}" itemValue="3"/>
    	</h:selectOneListbox>
    </a4j:region>
    Please help me.

    Best regards,
    Paw
    Solved the problem. An exception was thrown in one of the setter methods in the bean. I solved the problem after I read the richfaces faq. Added the <h:messages> and got a strange error.

    But I still having problems using the <rich:beanValidator>. It does'nt seem to work.

    Best regards,
    Paw

    Leave a comment:


  • kjeldpaw
    replied
    Action not called using a4j:support

    Hi,
    I have a problem using <a4j:support> in a form with multiple input components. The support action is only triggered when I add a <4j:region> tag to the component.

    I can see a request in the tomcat log when the region tag is not used.

    Example:

    Code:
    <a4j:region renderRegionOnly="false">	 
    	<h:selectOneListbox id="selectPeriodInterval" value="#{reportCriteria.periodInterval}" size="1">
    		<a4j:support id="supportPeriodInterval" event="onchange" action="updateInterval" reRender="#{flowRenderFragments}"/>
    		<f:selectItem  itemLabel="#{msg.emails_report_form_period_default}" itemValue="0"/>
    		<f:selectItem  itemLabel="#{msg.emails_report_form_period_1}" itemValue="1"/>
    		<f:selectItem  itemLabel="#{msg.emails_report_form_period_2}" itemValue="2"/>
    		<f:selectItem  itemLabel="#{msg.emails_report_form_period_3}" itemValue="3"/>
    	</h:selectOneListbox>
    </a4j:region>
    Please help me.

    Best regards,
    Paw

    Leave a comment:

Working...
X