Most important links for RichFaces can be found here.
There are two places where you can find binary/source distribution:
This wiki article helps you to find an answer.
Download and install Maven if you have not it yet installed. Follow the instruction at http://maven.apache.org/download.html.
Open <Maven-Root>/conf/settings.xml file to edit
Add into the <profile> section:
<id>RichFaces</id>
<repositories>
<repository>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
<id>repository.jboss.com</id>
<name>Jboss Repository for Maven</name>
<url>
http://repository.jboss.com/maven2/
</url>
<layout>default</layout>
</repository>
<repository>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
<id>maven2-snapshots.jboss.com</id>
<name>Jboss Repository for Maven Snapshots</name>
<url>http://snapshots.jboss.com/</url>
<layout>default</layout>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>maven2-snapshots.jboss.com</id>
<name>Jboss Repository for Maven Snapshots</name>
<url>http://snapshots.jboss.com/</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</pluginRepository>
<pluginRepository>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
<updatePolicy>never</updatePolicy>
</snapshots>
<id>repository.jboss.com</id>
<name>Jboss Repository for Maven</name>
<url>
http://repository.jboss.com/maven2/
</url>
<layout>default</layout>
</pluginRepository>
</pluginRepositories>
Add into the <activeProfiles> section:
<activeProfile>RichFaces</activeProfile>
RichFaces repository structure overview can be found here.
How to build and how to use richfaces-samples applications in Eclipse is described here.
Online demo Web applications that show the most important functionality of RichFaces components are available here.
War file of a nightly build can be found here.
Source Code (SVN) can be found here.
Here is an article that explains the Skinnability basics.
For information you can also see discussion about this problem on the RichFaces Users Forum
Also, the effect of predefined skins on the application whole look-and-feel could be seen here.
RichFaces 3.1.0 has been released with the latest Prototype 1.5.1.1. The conflict happens because on your page an older version of prototypes that can be added from Tomahawk 1.1.6 is used. See the solution for the problem here.
The article about <rich:dataTable> flexibility can be found here.
Source code (SVN) could be found here.
Online demo for a Web application is available here.
It's necessary to put <a4j:include> inside the <rich:modalPanel> and perform navigation inside it, as it's shown in the example below:
Example:
...
<f:verbatim>
<a href="javascript:Richfaces.showModalPanel('_panel',{left:'auto', top:'auto'})">Show Modal Panel</a>
</f:verbatim>
<rich:modalPanel id="_panel">
<a4j:outputPanel id="view" >
<a4j:include viewId="/pages/included1.xhtml"></a4j:include>
</a4j:outputPanel>
</rich:modalPanel>
...
faces-config.xml:
...
<navigation-rule>
<from-view-id>/pages/included1.xhtml</from-view-id>
<navigation-case>
<from-outcome>included2</from-outcome>
<to-view-id>/pages/included2.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
...
included1.xhtml:
...
<h:form>
<h:outputText value="Go to the step 2"/>
<a4j:commandButton value="next" action="included2" reRender="view"/>
</h:form>
...
included2.xhtml
...
<h:form>
<h:outputText value="Close window"/>
<h:commandButton type="button" value="Close" onclick="javascript:Richfaces.hideModalPanel('_panel')"/>
</h:form>
...
The discussion about <a4j:include> and navigation rules can be found on the Ajax Users Forum.
Examples of validation in <rich:modalPanel> could be found in the Wiki article and on the RichFaces Users Forum.
To solve this problem you should use the latest versions of RichFaces.
Most important links for RichFaces can be found here.
Main demo of RichFaces is a facelets based application. Full Facelets support is one of the main features. Hence, the answer is yes.
<rich:dropDownMenu> is a standard JSF component. Thus, creation of the menu dynamically from the Java Script code is the same as for any other jsf component.
For more information follow the link.
The answer is yes.
Component provides two controllers groups for switching:
The controls of fast switching are created adding the facets component with the corresponding name:
Example:
...
<rich:datascroller for="table" maxPages="10">
<f:facet name="first">
<h:outputText value="First"/>
</f:facet>
<f:facet name="last">
<h:outputText value="Last"/>
</f:facet>
</rich:datascroller>
...
There are also facets used to create the disabled states: "first_disabled", "last_disabled", "next_disabled", "previous_disabled", "fastforward_disabled", "fastrewind_disabled".
If you want to navigate outside, when application uses an external URL, you should use the following approach:
Example:
...
<rich:dropDownMenu>
...
<rich:menuItem submitMode="none"
onclick="document.location.href='http://labs.jboss.com/jbossrichfaces/'">
<h:outputLink value="http://labs.jboss.com/jbossrichfaces/">
<h:outputText value="RichFaces Home Page"></h:outputText>
</h:outputLink>
</rich:menuItem>
...
</rich:dropDownMenu>
...
Also online demo <rich:dropDownMenu> component is available here.
The <rich:dropDownMenu> is designed keeping in mind that it should not be used for a contextMenu purpose. We have a <rich:contextMenu> component in the TODO list. However, it is not schedule for the nearest versions.
You can pass your parameters during modalPanel opening or closing. This passing could be performed in the following way:
Example:
Richfaces.showModalPanel('panelId', {left: auto}, {param1: value1});
Thus, except the standard modalPanel parameters you can pass any of your own parameters.
Simple code is placed below:
Example:
...
<rich:tree ...>
...
<rich:treeNode submitMode="none"
onclick="document.location.href='http://labs.jboss.com/jbossrichfaces/'">
<h:outputLink value="http://labs.jboss.com/jbossrichfaces/">
<h:outputText value="RichFaces Home Page"></h:outputText>
</h:outputLink>
</rich:treeNode>
...
</rich:tree ...>
...
It's not possible to place tabs upright in the tabPanel. For this purporse use togglePanel. Toggle controls can be placed anywhere in the layout.
Simple code is placed below:
Example:
...
<rich:modalPanel>
<f:facet name="header">
<h:outputText value="Test" />
</f:facet>
<f:facet name="controls">
<h:commandLink value="Close" style="cursor:pointer" onclick="Richfaces.hideModalPanel('mp')" />
</f:facet>
<h:form>
<t:commandButton value="Test" action="#{TESTCONTROLLER.test}" />
</h:form>
</rich:modalPanel>
...
Two rules are important for modalPanel:
modalPanel must have its own form if it has form elements (input or/and command components) inside (as it was shown in the example above)
modalPanel must not be included into the form (on any level up) if it has the form inside.
Simple code is placed below:
Example:
...
<rich:tabPanel selectedTab="t2">
<rich:tab label="tab 1" name="t1">
<h:outputText value="tab 1" />
</rich:tab>
<rich:tab label="tab 1" name="t2">
<h:outputText value="tab 2" />
</rich:tab>
<rich:tab label="tab 1" name="t3">
<h:outputText value="tab 3" />
</rich:tab>
</rich:tabPanel>
...
For necessary information you can see discussion about this problem on the RichFaces Users Forum.
For necessary information you can see RichFaces Users Forum.
To catch the value of the inputNumberSlider from the JavaScrip, use the following approach:
Example:
...
<rich:inputNumberSlider width="500" step="20"
onchange="someFunctionCall(this.input.value)"
minValue="0"
maxValue="500"
value="0"
showInput="false"
showToolTip="false"
showBoundaryValues="false"/>
...
<script>
function someFunctionCall(value) {
alert(value);
}
</script>
...
The answer could be found here.
For necessary information you can see discussion about this problem on the RichFaces Users Forum
It' necessary to redefine rich* classes for example like this:
Example:
.rich-datascr-button {
border: 0px;
}
.rich-dtascroller-table {
border: 0px;
}
.rich-datascr-button {
background-color: transparent;
}
The answer could be found here.
The answer could be found on the RichFaces Users Forum.
How to use <rich:dataTable> and <rich:dataScroller> in a context of Extended Data Model see here.
The answer could be found on the RichFaces Users Forum:
The answer could be found here.
The simple code is placed below:
Example:
...
<a4j:form id="form">
<h:panelGroup id="test" columns="2" style="width: 300px">
<h:selectBooleanCheckbox value="#{bean.check}">
<a4j:support event="onchange" reRender="test" />
<f:selectItem itemValue="true" itemLabel="Show" />
<f:selectItem itemValue="false" itemLabel="Hide" />
</h:selectBooleanCheckbox>
<rich:calendar popup="true"
rendered="#{!bean.check}" value="#{bean.date}" id="c"/>
<a onclick="$('form:c').component.doExpand()" href="#">Show</a>
</h:panelGroup>
</a4j:form>
...
To load the whole Scriptaculous library shipped with RichFaces use <a4j:loadScript> tag.
Example:
...
<a4j:loadScript src="resource://scriptaculous.js" />
...
Thus, this command allows loading an integrated version of the library that includes all existing scriptaculous files except unittest.js.
If you don't want to load the whole library, but only the particular file, for example, effect.js, use the following line:
Example:
...
<a4j:loadScript src="resource://scriptaculous/effect.js" />
...
Remember, it does not make sense to load the particular file if you already load the whole version.
For more information see RichFaces Users Forum.
A problem with tab height occurs in IE 7. The tab height is correct in Firefox and IE 6. This is IE's 7 bug. As a temporary solution you can try to change doctype declaration from:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
to:
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<rich:effect> component has several callback methods such as beforeStart, afterFinish. You can use them to save the status.
See also core effects in scriptaculous.
An example is placed below:
...
<rich:suggestionbox width="200" height="200" for="test" suggestionAction="#{bean.autocomplete}" var="cap">
<h:column>
<f:facet name="header">
<h:outputText value="Sometext"></h:outputText>
</f:facet>
<h:outputText value="#{cap.text}"></h:outputText>
</h:column>
<a4j:support event="onselect" action="#{bean.action}">
<f:setPropertyActionListener value="#{cap.label}" target="#{bean.property1}" />
</a4j:support>
</rich:suggestionbox>
...
In the example "onselect" event is used for sending selected value to the server. It's also possible to pass additional fields of selected object (which don't belong to "fetchvalue" attribute.)
Add the following code to your css file:
...
.rich-table, .rich-table-header,.rich-table-headercell, .rich-table-cell,
.rich-subtable-cell, .rich-table-footercell, .rich-subtable-footercell {
border-width:0px;
}
...
This is a working example:
...
org.apache.myfaces.component.html.ext.HtmlInputText searchBox = new org.apache.myfaces.component.html.ext.HtmlInputText();
searchBox.setId( "inputQuery" );
bar.getChildren().add( searchBox );
org.richfaces.component.html.HtmlSuggestionBox suggestions = new org.richfaces.component.html.HtmlSuggestionBox();
suggestions.setId( "sugg" );
suggestions.setFor( "inputQuery" );
suggestions.setTokens( ",[" );
suggestions.setRules( "none" );
javax.faces.el.MethodBinding mb = app.createMethodBinding( "#{suggestionBox.autocomplete}", new Class[] { Object.class } );
suggestions.setSuggestionAction( mb );
suggestions.setVar( "result" );
suggestions.setRows( 0 );
suggestions.setFirst( 0 );
suggestions.setMinChars( "#{suggestionBox.minchars}" );
suggestions.setShadowOpacity( "4" );
suggestions.setBorder( "1" );
suggestions.setWidth( "200" );
suggestions.setHeight( "150" );
suggestions.setShadowDepth( "4" );
suggestions.setCellpadding( "2" );
org.apache.myfaces.custom.column.HtmlSimpleColumn column = new org.apache.myfaces.custom.column.HtmlSimpleColumn();
column.setId( "col1" );
org.apache.myfaces.component.html.ext.HtmlOutputText text = new org.apache.myfaces.component.html.ext.HtmlOutputText();
text.setId( "text1" );
javax.faces.el.ValueBinding vb = app.createValueBinding( "#{result.text}" );
text.setValueBinding( "value", vb );
column.getChildren().add( text );
suggestions.getChildren().add( column );
bar.getChildren().add( suggestions );
...
See also RichFaces User Forum.
Necessary information could be found on the RichFaces User Forum.
The list of zones to be reRendered can be specified as EL expression. But there is a question that must be specified more exactly.
The list of Ids is formed during beforePhase of RENDER_RESPONSE. Therefore, in this case one can point reRender to the Set type Bean's property and fill the Set during a tracking request.
It's the way to form a list of updatable areas dynamically.
To check on the client some terms of request sending, the "onSubmit " attribute is added to all components, which may cause the request.
Example:
<h:inputText id="i" value="#{beanText.kennung}">
<a4j:support event="onfocus" onsubmit="doSomething();" reRender="panelToReRender"/>
</h:inputText>
So in this case "doSomething()" function is executed before the Ajax request.
Besides, if this function returns "false", Ajax request isn't fired.
Behavior of our "onsubmit" slightly differs from the standard one. Do not return "true" if you want to fire the request - because <xxx><a4j:support event="onclick" onsubmit="return true;"> is transformed into <xxx onclick="return true; A4J.Submit(.... );" > and the request isn't fired also in this case (but the standard event processing fired). You must only return "false" if your conditions weren't completed or perform some actions (if needed) without any returns in case you need to fire it.
To avoid differences with other JavaScript attributes, a function placement in a JavaScript call is changed, instead of simple inserting of attribute content (..oncomplete :anotherFunction(this)..), it places (oncomplete: function(){anotherFunction(this);}..) in anonymous function, to allow put "chain" of statements in attribute.
Since, "this" keyword will point to a parameters map instead of a control element as it was before. You may use document.findElementById() to get references to this object after a request is processed as when a page is updated in Ajax you will have reference to a control, removed from a DOM tree.
Or, if you are sure that your element is not updated, you can add "onsubmit" in <a4j:support> (or onclick in <a4j:commandLink/Button> ) to place reference to known variable ( <a4j:commandLink onclick="var myControl=this;" oncomplete="anotherFunction(myControl)"/> ).
The onComplete syntax now is:
<someAjaxActionComponent ...oncomplete="myFunc(req,event,data)".../>
where the event is a variable where the JS event copy that fires the request is placed into. One may use it to get the element instead of this. and data is a variable that contains deserialized value from the data attribute.
RichFaces currently does not use invokeOnComponent because of the 2 reasons:
Thus, for example, only entire dataTable can be updated in response (but all Ajax core action components inside table work properly).
To avoid exception, don't forget that the component stores beans in serialized view, but your bean should implement java.io.Serializable.
This situation could happen because of conversion/validation errors on form submission. In order to verify this, it's necessary to place this updating via an Ajax error message inside a form:
Example:
<a4j:outputPanel ajaxRendered="true">
<h:messages/>
</a4j:outpurPanel>
The <a4j:support> component has a "requestDelay" attribute where you can define the delay.
More information about this problem could be found on the Ajax4Jsf Users Forum.
More information about this problem could be found on the Ajax4Jsf Users Forum.
The "IgnoreDupResponses" attribute appeared from 1.0.4 RC1 version and is used on the client for response ignoring after an Ajax request if a newer request has been already sent.
The additional information could be found here.
"RequestDelay" attribute also defines the client behavior. It sets the time delay, after which another request could be sent, all other requests are taken away from a queue except the last one.
More information about this problem could be found on the Ajax4Jsf Users Forum.
The "EventQueue" attribute defines the query name where the requests are saved before their sending to the server. The queue is created for redundant requests deleting during frequent events, which call several requests forming one after another. The queue cuts redundant requests and send only the last one. The queue is created in any case and named on default, the attribute usage only re-defines this name.
<4j:page> is a component used for solving of incompatibility problems in early Ajax4jsf and MyFaces versions. The component encodes the full html page structure.
More information about this problem could be found on the Ajax4Jsf Users Forum.
Yes, you can. More information about this problem could be found on the JBoss RichFaces Online Demos.
<a4j:region> can't work inside iteration components like <h:dataTable> and <a4j:repeat>.
The details could be found here.
More information about this problem could be found on the Ajax4Jsf Users Forum.
More information about this problem could be found on the Ajax4Jsf Users Forum.
There is possibility to use special skin with name "plain". It doesn't have any parameters. It's necessary for embedding RichFaces components into existing projecst which have its own styles.
For information you can see discussion about this problem on the Ajax4Jsf Users Forum.
During "show/hide" functionality implementation the main error happens because of the "reRender" attribute of some Ajax core Action Component is set on a component that depends on rendered properties, i.e. a component that is to be hidden/rendered is tried to be updated. The problem is that if rendered="false" in this moment, the component isn't in the DOM tree and can't be updated because of the general limitations described in the Ajax Processing chapter.
The correct variant of functionality implantation:
With the rendered attribute wrap the component that is to be hidden or rendered on Ajax in a wrapper component (e.g. a4j:outputPanel)
Set reRender of an Ajax core Action component on this wrapper component instead of the component itself.
Example:
...
<a4j:outputPanel id="panel">
<h:panelGroup rendered="#{bean.rendered}">
<!--Some nested content to be hidden/shown depending on bean.rendered -->
</h:panelGroup>
</a4j:outputPanel>
...
<a4j:commandButton action=".." value=".." reRender="panel"/>
...
In this case the wrapper component always presents in the DOM tree and its inner content could be updated dynamically on AJAX.
For information you can see discussion about this problem on the Ajax4Jsf Users Forum.
More information about this problem could be found on the Ajax4Jsf Users Forum.
For information you can see discussion about this problem on the Ajax4Jsf Users Forum.
RichFaces registers its resources (scripts, images) after an application is accessed and then accesses it via a generated URL. During an application development when a developer constantly updates it on the server, it could happen that RichFaces re-registers its resources after every server restart and a browser tries to access them via cashed URL.
The problem is solved with browser cash update (e.g. CTRL+F5).
"ajaxKeys" attribute defines strings that are updated after an Ajax request. It provides possibility to update several child components separately without updating the whole page.
...
<a4j:poll intervall="1000" action="#{repeater.action}" reRender="text">
<table>
<tbody>
<a4j:repeat value="#{bean.props}" var="detail" ajaxKeys="#{repeater.ajaxedRowsSet}">
<tr>
<td>
<h:outputText value="detail.someProperty" id="text"/>
</td>
</tr>
</a4j:repeat>
</tbody>
</table>
</a4j:poll>
...
In order to get row selection in scrollableDataTable using one and multi-selection rows mode you should use the "selection" attribute.
In the following example when user submits the form current collection of objects selected by user is placed in the object's property. Then on complete action the <rich:modalPanel> with selected data will be shown.
Example:
...
<h:form>
<rich:spacer height="30" />
<rich:scrollableDataTable rowKeyVar="rkv" frozenColCount="1" height="200px"
width="300px" id="carList" rows="40" columnClasses="col"
value="#{dataTableScrollerBean.allCars}" var="category" sortMode="single"
selection="#{dataTableScrollerBean.selection}">
<rich:column id="make">
<f:facet name="header">
<h:outputText styleClass="headerText" value="Make" />
</f:facet>
<h:outputText value="#{category.make}" />
</rich:column>
<rich:column id="model">
<f:facet name="header">
<h:outputText styleClass="headerText" value="Model" />
</f:facet>
<h:outputText value="#{category.model}" />
</rich:column>
<rich:column id="price">
<f:facet name="header">
<h:outputText styleClass="headerText" value="Price" />
</f:facet>
<h:outputText value="#{category.price}" />
</rich:column>
</rich:scrollableDataTable>
<rich:spacer height="20px"/>
<a4j:commandButton value="Show Current Selection" reRender="table"
action="#{dataTableScrollerBean.takeSelection}"
oncomplete="javascript:Richfaces.showModalPanel('panel');"/>
</h:form>
<rich:modalPanel id="panel" autosized="true">
<f:facet name="header">
<h:outputText value="Selected Rows"/>
</f:facet>
<f:facet name="controls">
<span style="cursor:pointer" onclick="javascript:Richfaces.hideModalPanel('panel')">X</span>
</f:facet>
<rich:dataTable value="#{dataTableScrollerBean.selectedCars}" var="sel" id="table">
<rich:column>
<f:facet name="header">
<h:outputText value="Make" />
</f:facet>
<h:outputText value="#{sel.make}" />
</rich:column>
<rich:column id="model">
<f:facet name="header">
<h:outputText value="Model" />
</f:facet>
<h:outputText value="#{sel.model}" />
</rich:column>
<rich:column id="price">
<f:facet name="header">
<h:outputText value="Price" />
</f:facet>
<h:outputText value="#{sel.price}" />
</rich:column>
</rich:dataTable>
</rich:modalPanel>
...
In order to build this application, you can create a managed bean like this one. Function takeSelection() fills the array selectedCars with the data, got from the selection. Function getSelectedCars() returns the array selectedCars, which is used for filling <rich:dataTable> with selected row/rows data.
Example:
...
public class DataTableScrollerBean {
private SimpleSelection selection = new SimpleSelection();
private ArrayList<DemoInventoryItem> selectedCars = new ArrayList<DemoInventoryItem>();
...
public SimpleSelection getSelection() {
return selection;
}
public void setSelection(SimpleSelection selection) {
System.out.println("Setting Started");
this.selection = selection;
System.out.println("Setting Complete");
}
public String takeSelection() {
getSelectedCars().clear();
Iterator<SimpleRowKey> iterator = getSelection().getKeys();
while (iterator.hasNext()){
SimpleRowKey key = iterator.next();
getSelectedCars().add(getAllCars().get(key.intValue()));
}
return null;
}
public ArrayList<DemoInventoryItem> getSelectedCars() {
return selectedCars;
}
public void setSelectedCars(ArrayList<DemoInventoryItem> selectedCars) {
this.selectedCars = selectedCars;
}
}
...
Some additional information about usage of one and multi-selection rows mode can be found here.
How to get row selection in scrollableDataTable using one and multi-selection rows mode you could see the section above.
In order to perform Drag-and-Drop of selected columns on a dataTable you could use <rich:dragSupport> and <rich:dropSupport> components as it is shown in the example below.
Example:
...
<rich:scrollableDataTable rowKeyVar="rkv" frozenColCount="1" height="400px" width="700px" id="carList" rows="40" columnClasses="col"
value="#{dataTableScrollerBean.allCars}" var="category" sortMode="single" selection="#{dataTableScrollerBean.selection}">
<rich:column id="make">
<f:facet name="header">
<h:outputText styleClass="headerText" value="Make" />
</f:facet>
<a4j:outputPanel>
<rich:dragSupport dragType="selectionDrag" dragIndicator=":indicator"/>
<h:outputText value="#{category.make}" />
</a4j:outputPanel>
</rich:column>
<rich:column id="model">
<f:facet name="header">
<h:outputText styleClass="headerText" value="Model" />
</f:facet>
<h:outputText value="#{category.model}" />
</rich:column>
<rich:column id="price">
<f:facet name="header">
<h:outputText styleClass="headerText" value="Price" />
</f:facet>
<h:outputText value="#{category.price}" />
</rich:column>
<rich:column id="mileage">
<f:facet name="header">
<h:outputText styleClass="headerText" value="Mileage" />
</f:facet>
<h:outputText value="#{category.mileage}" />
</rich:column>
<rich:column width="200px" id="vin">
<f:facet name="header">
<h:outputText styleClass="headerText" value="VIN" />
</f:facet>
<h:outputText value="#{category.vin}" />
</rich:column>
<rich:column id="stock">
<f:facet name="header">
<h:outputText styleClass="headerText" value="Stock" />
</f:facet>
<h:outputText value="#{category.stock}" />
</rich:column>
</rich:scrollableDataTable>
<rich:spacer height="20px"/>
<rich:panel style="width:300px; height:300px">
<f:facet name="header">
<h:outputText value="Drop Here"/>
</f:facet>
<rich:dropSupport acceptedTypes="selectionDrag" dropListener="#{dataTableScrollerBean.dropListener}" reRender="table"/>
<rich:dataTable value="#{dataTableScrollerBean.droppedCars}" var="sel" id="table">
<rich:column>
<f:facet name="header">
<h:outputText value="Make" />
</f:facet>
<h:outputText value="#{sel.make}" />
</rich:column>
<rich:column id="model">
<f:facet name="header">
<h:outputText value="Model" />
</f:facet>
<h:outputText value="#{sel.model}" />
</rich:column>
<rich:column id="price">
<f:facet name="header">
<h:outputText value="Price" />
</f:facet>
<h:outputText value="#{sel.price}" />
</rich:column>
<rich:column id="mileage">
<f:facet name="header">
<h:outputText value="Mileage" />
</f:facet>
<h:outputText value="#{sel.mileage}" />
</rich:column>
<rich:column id="stock">
<f:facet name="header">
<h:outputText value="Stock" />
</f:facet>
<h:outputText value="#{sel.stock}" />
</rich:column>
</rich:dataTable>
</rich:panel>
...
This is the page from RichFaces LiveDemo site and also uses beans from RichFaces LiveDemo site. Only one method is added where the dropped selection is stored:
...
public void dropListener(DropEvent event) {
System.out.println("Drop Listener Fired");
getDroppedCars().clear();
Iterator<SimpleRowKey> item = getSelection().getKeys();
while (item.hasNext()){
SimpleRowKey key = item.next();
getDroppedCars().add(getAllCars().get(key.intValue()));
}
}
...
In order to save the state (exapnd/collapse) of the <rich:simpleTogglePanel> component you could use "opened" attribute responsible for keeping a panel state and <a4j:support> binded to onexpand and oncollapse events.
In the following example when you click on the toggle icon simpleTogglePanel appears and current state displays on modal panel. This state is remembered between page views.
Example:
...
<rich:simpleTogglePanel id="toggleP" label="simpleTogglePanel" switchType="client" width="600px" opened="#{demo.state}">
<a4j:support event="onexpand" actionListener="#{demo.stateTrue}" reRender="repeater" oncomplete="Richfaces.showModalPanel('myFrom:panel')" />
<a4j:support event="oncollapse" actionListener="#{demo.stateFalse}" reRender="repeater" oncomplete="Richfaces.showModalPanel('myFrom:panel')" />
<h:panelGrid columns="2" border="0">
<h:graphicImage url="pics/Canon.jpg" alt="" width="100px" height="100px" />
<h:panelGroup>
<h:outputText style="font: 18px;font-weight: bold;" value="Canon EOS Digital Rebel XT" />
<f:verbatim>
<br />
8.2 Megapixels - SLR / Large Digital Camera - 1.8 in LCD Screen -
Storage: Compact Flash, Compact Flash Type II - Built In Flash
</f:verbatim>
</h:panelGroup>
</h:panelGrid>
</rich:simpleTogglePanel>
<rich:modalPanel id="panel" width="300" height="100">
<f:facet name="header">
<h:outputText value="States of simpleTogglePanel" />
</f:facet>
<f:facet name="controls">
<span style="cursor: pointer" onclick="Richfaces.hideModalPanel('myFrom:panel')">X</span>
</f:facet>
<h:outputText value="Expanded simpleTogglePanel: " style="font-weight:bold;" />
<h:outputText value="#{demo.state}" id="repeater" />
</rich:modalPanel>
...
In order to build this application, you can create a managed bean like this one.
Example:
...
public class demo {
private boolean state = false;
public boolean isState() {
return state;
}
public void setState(boolean state) {
this.state = state;
}
public void stateTrue(ActionEvent event) {
this.state = true;
}
public void stateFalse(ActionEvent event) {
this.state = false;
}
}
...
In order to highlight rows in a dataTable when the mouse is over you should use "onRowMouseOver" and "onRowMouseOut" attributes.
Example:
...
<h:form>
<rich:dataTable onRowMouseOver="this.style.font = 'bold 20pt Arial'"
onRowMouseOut="this.style.font='#{a4jSkin.tableFont}'"
cellpadding="0" cellspacing="0"
width="700" border="0" var="record" value="#{report.expReport.records}"
onRowClick="#{dataTableBean.onRowClick}">
<f:facet name="header">
<rich:columnGroup>
<rich:column rowspan="2">
<rich:spacer />
</rich:column>
<rich:column colspan="3">
<h:outputText value="Expenses" />
</rich:column>
<rich:column rowspan="2">
<h:outputText value="subtotals" />
</rich:column>
<rich:column breakBefore="true">
<h:outputText value="Meals" />
</rich:column>
<rich:column>
<h:outputText value="Hotels" />
</rich:column>
<rich:column>
<h:outputText value="Transport" />
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column colspan="5">
<h:outputText value="#{record.city}" />
</rich:column>
<rich:subTable onRowMouseOver="this.style.font = 'bold 20pt Arial'"
onRowMouseOut="this.style.font='#{a4jSkin.tableFont}'"
var="expense" value="#{record.items}">
<rich:column>
<h:outputText value="#{expense.day}"></h:outputText>
<f:facet name="footer">
<rich:spacer />
</f:facet>
</rich:column>
<rich:column>
<h:outputText value="#{expense.meals}"><f:convertNumber pattern="$####.00" /></h:outputText>
<f:facet name="footer">
<h:outputText value="#{record.totalMeals}"><f:convertNumber pattern="$####.00" /></h:outputText>
</f:facet>
</rich:column>
<rich:column>
<h:outputText value="#{expense.hotels}"><f:convertNumber pattern="$####.00" /></h:outputText>
<f:facet name="footer">
<h:outputText value="#{record.totalHotels}"><f:convertNumber pattern="$####.00" /></h:outputText>
</f:facet>
</rich:column>
<rich:column>
<h:outputText value="#{expense.transport}"><f:convertNumber pattern="$####.00" /></h:outputText>
<f:facet name="footer">
<h:outputText value="#{record.totalTransport}"><f:convertNumber pattern="$####.00" /></h:outputText>
</f:facet>
</rich:column>
<rich:column>
<rich:spacer></rich:spacer>
<f:facet name="footer">
<h:outputText value="#{record.total}"><f:convertNumber pattern="$####.00" /></h:outputText>
</f:facet>
</rich:column>
</rich:subTable>
<f:facet name="footer">
<rich:columnGroup>
<rich:column>Totals</rich:column>
<rich:column>
<h:outputText value="#{report.expReport.totalMeals}"><f:convertNumber pattern="$####.00" /></h:outputText>
</rich:column>
<rich:column>
<h:outputText value="#{report.expReport.totalHotels}"><f:convertNumber pattern="$####.00" /></h:outputText>
</rich:column>
<rich:column>
<h:outputText value="#{report.expReport.totalTransport}"><f:convertNumber pattern="$####.00" /></h:outputText>
</rich:column>
<rich:column>
<h:outputText value="#{report.expReport.grandTotal}"><f:convertNumber pattern="$####.00" /></h:outputText>
</rich:column>
</rich:columnGroup>
</f:facet>
</rich:dataTable>
</h:form>
...
In order to select one row of a dataTable by clicking on it you could use JavaScript function described below.
Example:
...
<script type="text/javascript">
var oldRow;
function changeColor(row)
{
if (oldRow!=undefined)
{
oldRow.style.backgroundColor='#ffffff';
}
row.style.backgroundColor='#ffff00';
oldRow=row;
}
</script>
...
Then you could use a4j:support with "event" and "onsubmit" attributes.
Example:
...
<h:form>
<rich:dataTable cellpadding="0" cellspacing="0"
width="700" border="0" var="record" value="#{report.expReport.records}">
<a4j:support event="onRowClick" onsubmit="changeColor(this)" ajaxSingle="true">
<f:param name="currentRow" value="#{record.city}"/>
</a4j:support>
...
</rich:dataTable>
</h:form>
...
In order to reRender table cells with <a4j:support> you should set exact ids values for every updatable components and point this id to the "reRender" attribute.
The value of "reRender" attribute of the <a4j:support> tag defines which part(s) of our page is (are) to be updated. In this case, the only part of the page to update is the <h:outputText> tag because its id value matches to the value of "reRender" attribute. As you see, it's not difficult to update multiple elements on the page, only list their ids as the value of "reRender" attribute .
Example:
...
<rich:column>
<f:facet name="header">
<h:outputText value="Input1"/>
</f:facet>
<f:facet name="footer">
<h:outputText value="#{Controller.totalInput1}"/>
</f:facet>
<h:inputText id="input1" value="#{entry.input1}">
<a4j:support actionListener="{Controller.updateEntry}"event="onblur" reRender="output1"/>
</h:inputText>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Value2"/>
</f:facet>
<f:facet name="footer">
<h:outputText value="#{Controller.totalOutput1}"/>
</f:facet>
<h:outputText id="output1" value="#{entry.output1}"/>
</rich:column>
...
As it could be seen in the example above, the footer with <h:outputText> reRenderes.
In order to create dynamic columns you could use the <rich:column> component with the"rendered" attribute. You should just set the value of defined dynamic cell to the "rendered" attribute field.
Example:
...
<ui:composition template="/WEB-INF/layout/template.xhtml">
<ui:define name="body">
<h2>Table</h2>
<h:form>
<rich:dataTable id="aTable" onRowMouseOver="this.style.backgroundColor='#F1F1F1'"
onRowMouseOut="this.style.backgroundColor='#{a4jSkin.tableBackgroundColor}'" value="#{trb.tableData}" var="row">
<f:facet name="header">
<rich:columnGroup>
<rich:column colspan="2">
Testing
</rich:column>
</rich:columnGroup>
</f:facet>
<f:facet name="footer">
<rich:columnGroup>
<rich:column colspan="2">
Footer
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column rendered="#{trb.cellRendered['value1']}">
<f:facet name="header">
<s:div>
value1 <h:commandLink value="x" action="#{trb.hideColumn('value1')}"/>
</s:div>
</f:facet>
#{row.value1}
</rich:column>
</rich:dataTable>
Generate new table values:
<h:commandButton value="generate" action="#{trb.createData}"/>
</h:form>
<h:form>
Select which columns are rendered.
<br/>
<h:selectBooleanCheckbox title="value1" value="#{trb.cellRendered['value1']}"/>
<br/>
<h:commandButton value="Apply" action="rerender"/>
</h:form>
</ui:define>
</ui:composition>
...
In order to build this application, you can create a managed bean like this one.
Example:
public class TableBackingRendered implements Serializable {
private static final long serialVersionUID = 1L;
private Random rand = new Random(System.currentTimeMillis());
private List<TableItem> tableData;
private Map<String, Boolean> cellRendered = new HashMap<String, Boolean>();
public TableBackingRendered() {
createData();
allCellsRendered();
}
public String createData(){
int count = rand.nextInt(25)+1;
tableData = new ArrayList<TableItem>(count);
for(int i=0; i<count; i++){
tableData.add( new TableItem(
"value1_" +i,
));
}
return null;
}
public String allCellsRendered() {
cellRendered.put("value1", Boolean.TRUE);
return null;
}
public String hideColumn(final String columnToHide) {
cellRendered.put(columnToHide, Boolean.FALSE);
return null;
}
public List<TableItem> getTableData() {
return tableData;
}
public Map<String, Boolean> getCellRendered() {
return cellRendered;
}
public void setCellRendered(Map<String, Boolean> cellRendered) {
this.cellRendered = cellRendered;
}
public void setTableData(List<TableItem> tableData) {
this.tableData = tableData;
}
}
...
Here is a stripped down version of web.xml that integrates RichFaces and Trinidad.
Example:
<?xml version="1.0" ?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"
version="2.5">
<!-- Ajax4jsf -->
<context-param>
<param-name>org.ajax4jsf.SKIN</param-name>
<param-value>blueSky</param-value>
</context-param>
<!-- Seam -->
<listener>
<listener-class>org.jboss.seam.servlet.SeamListener</listener-class>
</listener>
<filter>
<filter-name>Seam Filter</filter-name>
<filter-class>org.jboss.seam.servlet.SeamFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Seam Filter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>Seam Resource Servlet</servlet-name>
<servlet-class>org.jboss.seam.servlet.SeamResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Seam Resource Servlet</servlet-name>
<url-pattern>/seam/resource/*</url-pattern>
</servlet-mapping>
<!-- Facelets -->
<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>
<!-- JSF -->
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<!-- Trinidad - as suggested by a4j-trinidad example-->
<context-param>
<param-name>org.apache.myfaces.trinidad.ALTERNATE_VIEW_HANDLER</param-name>
<param-value>com.sun.facelets.FaceletViewHandler</param-value>
</context-param>
<filter>
<filter-name>Trinidad</filter-name>
<filter-class>org.apache.myfaces.trinidad.webapp.TrinidadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>Trinidad</filter-name>
<url-pattern>*.xhtml</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<context-param>
<param-name>org.apache.myfaces.trinidad.CACHE_VIEW_ROOT</param-name>
<param-value>false</param-value>
</context-param>
<servlet>
<servlet-name>Trinidad Resources</servlet-name>
<servlet-class>org.apache.myfaces.trinidad.webapp.ResourceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Trinidad Resources</servlet-name>
<url-pattern>/adf/*</url-pattern>
</servlet-mapping>
<!-- Security -->
<security-constraint>
<web-resource-collection>
<web-resource-name>Secure Content</web-resource-name>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>AuthorizedUser</role-name>
</auth-constraint>
<user-data-constraint>
<transport-guarantee>NONE</transport-guarantee>
</user-data-constraint>
</security-constraint>
<login-config>
<auth-method>BASIC</auth-method>
<realm-name>The Restricted Zone</realm-name>
</login-config>
<security-role>
<description>The role required to access restricted content</description>
<role-name>AuthorizedUser</role-name>
</security-role>
<!-- Welcome files -->
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
</web-app>
Richfaces 3.1.3 uses 1.6.0 version of prototype.js script instead of 1.5.1 that's been used for earlier versions. There are 2 prototype versions included (the first included implicitly as a dependency of toggle panel components and the second one included explicitly as a link). Versions conflict is the cause of the problem.
RichFaces 3.1.3 is bundled with the same ones as Prototype 1.6.0, Scriptaculous 1.8.0
Example in web.xml::
...
<context-param>
<param-name>org.richfaces.ExcludeScripts</param-name>
<param-value>Prototype,Scriptaculous</param-value>
</context-param>
...
RichFaces components use Prototype very hard. In particular, some patches has been removed that are already included into 1.6.0. Adding feature with exclusion makes it possible to use Prototype with version less than 1.6.0. This will break some of the components.