Showing posts with label skin. Show all posts
Showing posts with label skin. Show all posts

Saturday, February 9, 2013

Advanced RichFaces Extended Data Tables

 
With Mardi Gras and Carnival around the corner, this is crêpe season!

This post is the first of a set of recipes that describe useful tips and reusable code and patterns related to Java, JSF 2.0 and RichFaces 4.0.  In this article I am describing practical integration code when using advanced Richfaces Extended Data Tables.

The RichFaces showcase describes well how to start creating your own extendedDataTable. However, here are some additional personal ingredients that can be very handy when preparing an appealing stack of JSF based web pages.





1) Setting your Table

The first time your try to put together a RichFaces extendedDataTable, you might encounter the following behavior: your table does not look like as you expected it: columns have a default size (the length of the label) and the whole size is the size of your whole window, so you end up with a large white space where they are no columns:


 One reason could be that no column or table size has been specified:


 <rich:extendedDataTable id="table" value="#{countries.countryItems} var="country" >
    <f:facet name="header">
        <h:outputText value="Countries" />
    </f:facet>
    <rich:column>
        <f:facet name="header">
            <h:outputText value="Name" />
        </f:facet>
        <h:outputText value="#{country.name}" />
    </rich:column>
    <rich:column>
        <f:facet name="header">
            <h:outputText value="Capital" />
        </f:facet>
        <h:outputText value="#{country.capital}" />
    </rich:column>
    <rich:column>
        <f:facet name="header">
            <h:outputText value="Language(s)" />
        </f:facet>
        <h:outputText value="#{country.languages}" />
    </rich:column>
</rich:extendedDataTable>


One way to quickly fix this is to assign specific sizes to your columns and headers (in my case these are absolute values in pixels and have adjusted the values to take into account the height of a row and the presence of a vertical scroller).  I have also added single selection mode so I can click on a row to retrieve more information about a certain item:

<rich:extendedDataTable id="table" value="#{countries.countryItems}"
    var="country" selection="#{countries.selection}" 
    style="height:190px; width:503px;"
    selectionMode="single">
    <a4j:ajax execute="@form" event="selectionchange" listener="#{countries.selectionListener}"/>
        <f:facet name="header">
            <h:outputText value="Countries" />
        </f:facet>
        <rich:column width="100px">
            <f:facet name="header">
                <h:outputText value="Name" />
            </f:facet>
            <h:outputText value="#{country.name}" />
        </rich:column>
        <rich:column width="100px">
            <f:facet name="header">
                 <h:outputText value="Capital" />
            </f:facet>
            <h:outputText value="#{country.capital}" />
        </rich:column>
        <rich:column width="300px">
            <f:facet name="header">
                <h:outputText value="Language(s)" />
            </f:facet>
            <h:outputText value="#{country.languages}" />
        </rich:column>
</rich:extendedDataTable>
















2) Interaction improvements

Let say now that you want to add a button to load or refresh the information in the table and that this takes some time because you are connected to a remote service. You may want to show to the end-user an indicator that some processing or data retrieval is happening (for this example, I added a waiting function in the iem list bean to simulate a few seconds wait).

I propose to use an animated GIF and take advantage of the RichFaces a4j:status (an indicator of an Ajax request. It has two states: start and stop. The start state indicates that an Ajax request is in progress. When an Ajax response is returned, the component switches to the stop state).

In this case, I refer to a4j:status every time I click on the refresh button to download the countries statistics. I have also added an animated GIF file called processing.gif in my webapp/img folder and top aligned both the button and the ajax indicator into a JSF panel grid:


<h:panelGroup>
    <h:panelGrid columns="2" columnClasses="alignTop, alignTop">
        <a4j:commandButton value="Refresh" status="refreshTable"
     oncomplete="#{countries.refresh()}" />
        <a4j:status name="someProcessing">
            <f:facet name="start">
         <h:graphicImage value="/img/processing.gif" />
     </f:facet>
        </a4j:status>
    </h:panelGrid>
</h:panelGroup>

As a result, the processing indicator appears next to the button when it is clicked and disappear after the table has been refreshed.


















In fact, you can use the same indicator when selecting a row to display detailed information about an item if the retrieval of the additional information takes too long for the user (e.g. more than a couple of seconds):


<a4j:ajax execute="@form" event="selectionchange" status="someProcessing" listener="#{countries.selectionListener}" />


3) Adding some coloring and flavor

If you don't have a predefine look and feel (e.g. a reusable template or UI toolkit), you can easily use the themes and skins that come with RichFaces.  A skin can be quickly added to the web.xml file as follow:


<context-param>
    <param-name>org.richfaces.skin</param-name>
    <param-value>wine</param-value>
</context-param>

Some of my favorites predefined skins are deepMarine and wine:

 
















4) The missing ingredients

Even though the RichFaces Extended Data Tables have a lot of features such as filtering, sorting, scrolling, frozen columns, here are always missing ingredients that you would like to use to offer a better experience to the end user. One that you will not find in the ExtendedDataTable is the wrapping of text in a column or a robust column horizontal scrolling. Hopefully this feature will be added in future release.


5) Always give a tip if you can

Offering tips is generally a good practice. It makes feel everybody happy: the person who provides it knowing that he/she has done a good job, and the end-user who enjoys it and saves time using them.

In this example, I have added a column to to indicate which countries have a GDP above one Trillion US Dollars. When the use hovers the mouse above the checkbox or the name of the country, a tooltip appears and shows the GDP number for the selected country.

















Tooltips can be easily added as follow:

<rich:column styleClass="#{msg.status}" width="35px">
    <f:facet name="header">
        <h:outputText value="GDP > $1T" />
    </f:facet>
    <rich:tooltip mode="client" target="largeGDPCountry">
        <h:outputText value="#{country.name} - 2011 GDP: #{country.gdp} > $1T" />
    </rich:tooltip>
    <h:graphicImage id="largeGDPCountry" value="/img/checkmark.png" rendered="#{country.largeGdp}" alt="GDP" />
</rich:column>
<rich:column width="100px">
    <f:facet name="header">
        <h:outputText value="Name" />
    </f:facet>
    <h:outputText id="countryName" value="#{country.name}" />
    <rich:tooltip mode="client" target="countryName">
        <h:outputText value="#{country.name} - 2011 GDP: #{country.gdp} $M" />
    </rich:tooltip>
</rich:column>


Ingredients and open source code related to this recipe can be found at YummyCode on the JSF Plate project.

Friday, August 29, 2008

Liferay Portal : My first impressions



My company ICW creates Health Care web applications and solutions.

We have a need to create reusable components that can be bundled into highly customizable and personalized web applications. Our stack uses Java Enterprise and Web 2.0 technologies, so we naturally turned to the open source Liferay Portal.

This was my first experience with Liferay. By looking at the features, it seems that this portal solution had a lot of things we were looking for:
  • A well recognized open source product (1.5 million downloads, 6000+ registered participants ...)
  • A business-friendly MIT License
  • Compatibility with all major servers, databases and operating systems (we are using Tomcat, Oracle, Windows for development and Linux for production).
  • Compatibility with our stack (J2E) and light container (Spring).
  • An easy way to create new skins and branding
  • An integrated content management system
  • Highly secure platform (especially important for Health Care applications)
Installing Liferay (version 5.1.0) was a little bit longer than expected (>1 GB), but after this, it went pretty smoothly besides minor MySQL configuration issues. This installation included all the source code of Liferay (I did not have to customize the code initially, but it seems nice to have all the source code available in case ...).

I did create a specific project for our need - a portal version of our Personal Health Record (PHR) - call phr-portal-assembly (see screen shot on the left):

I liked the fact that the runtime portion of the portal is contained inside the project: bundles/tomcat/ (although this takes a lot of space if you have several projects).

To be up and running, you just have to start MySQL and Tomcat and open a browser at http://localhost:8080/web/guest/home (I am using Firefox).

I find it easy to create new plugins (portlets and themes). You just have to open a prompt under the liferay-plugins-sdk-5.1.0/portlets or liferay-plugins-sdk-5.1.0/themes directory and use the command:

create new_portlet_name new_portlet_title and
create new_theme_name new_theme_title

I was then able to start to modify my portlet skeletons (by modifying the default view.JSP file under docroot) and redeploy them (without having to restart tomcat!) by using the ant deploy command. Easy and efficient!

For the themes, I was a little bit different: The style sheet changes/differences is specified under the docroot/_diffs and the new theme is built by adding the differences to the default classic look and feel.

Becoming familiar with the portal application itself was not too complicated. Especially with version 5.1.0 which can give admin rights to any type of users, so I was able to customize my portal page without having to log a as an administrator.

To make the border/chrome disappear, I just had to click on the look-and-feel icon.








This opens a new window where I had to uncheck 'Show Borders' and refresh the browser.






After this, I had to uncheck the 'Toggle Edit Controls' check box.

The resulting portal had the same look and feel as our initial PHR, but was now highly customizable.I did some also some quick tests with different layouts and themes that was provided by one of my colleague with fast and good and results. We also did some tests encapsulating an existing Flex based application and some widgets with great success.

Overall my first impression of Liferay portal is a very positive one.

I am now looking forward to tackle the re-factoring of our existing products with this technology (we are using JSF, Ajax and Flex as front-end technology)!