One of the promises of Java Server Faces is the ability for developers to use a rich mix of UI Components from different libraries and vendors. You may pick one JSF implementation as your main library, yet complement it with components from other libraries that may be better suited to specific needs you have or provide functionality not available in your core set. In this article I will discuss the implementation of a popup element – not in a new window, susceptible to popup blockers and far too clumsy at any rate – but as a floating DIV that gets displayed and hidden on request. My main JSF Library is ADF Faces – aka Apache MyFaces Trinidad. However, since the ADF Faces library does not have such a light weight popup feature, I turn to the Apache MyFaces Tomahawk library that offers a popup element. I will show how you can incorporate this Tomahawk popup component in an otherwise ADF Faces page and have it display more ADF Faces components.
The purpose of this exercise in this particular case is the following: I have a page with a table component that displays multiple records and for each record multiple columns. I have created a control for the end user to govern the sequence of the columns in the table and also which columns are shown in the first place.
However, this control takes up a lot of real estate – half of my page is eaten up by it, sort of defeating the purpose. I would like the control only to be shown when desired, which will not be very often, as I do not expect my users to constantly change the layout of the table.
What I want to achieve, is to display the column control in a popup, floating DIV that only appears when explicitly asked for by the user. However, displaying the control should not require a server round-trip, as I feel that damages the Rich UI experiences I want to give my users.
My aim – and final result – will be much like this:
When the user leaves the popup or presses the Apply Column-settings button, the page will rerender like this:
Hovering the cursor over the text Column Control Panel.. will bring out the popup again.
Steps to implement the Tomahawk Popup in an ADF Faces page
The steps for implementing the Tomahawk Popup component in an ADF Faces project are pretty straightforward. Here is what you have to do:
Note: these steps start from the assumption that you already have a JDeveloper 10.1.3 Application with an ADF Faces based JSF JSP page with the Table Component as shown above. See also the original article on creating the Column Control: Changing the order of columns in a JSF Table Component -in the client, at run-time, by the end user.
- Download the Tomahawk binaries
- Extract and copy tomahawk-1.1.3.jar (or whichever release you are using) to the WEB-INF/lib directory
- Specify the Library and Taglib Library for Tomahawk in the JDeveloper project
- Update the web.xml file – configure the Tomahawk Extension Filter
- Create a CSS with the popup-style
- Add the tomahawk namespace to your JSPX page
- Include the Popup element in the page and add content to its popup facet.
- Run the application
- Done.
Step 1 – Download the Tomahawk Binary Distribution
Go to http://myfaces.apache.org/download.html and download Tomahawk 1.1.3 (or whatever the latest release happens to be)
Step 2 – Extract and copy tomahawk-1.1.3.jar (or whichever release you are using) to the WEB-INF/lib directory
The file I downloaded was called tomahawk-1.1.3-bin.zip. I have extracted the file tomahawk-1.1.3.jar from this archive and copied it to the WEB-INF/lib directory of my (View-Controller) project. In that directory, I have also copied some Jakarta Commons libraries. I am not entirely sure which ones are needed, but it does not hurt to have them all in there:
Step 3 – Specify the Library and Taglib Library for Tomahawk in the JDeveloper project
Open the Project properties for the ViewController project. In the tab “Libraries”, create a new library by clicking on the Add Library button and subsequently on the New button. Enter MyFaces Tomahawk as the name and add the following libraries: tomahawk-1.1.3.jar, commons-[something].jar , jakarta-oro.jar; Close the dialog.
Click on the node JSP Tag Libraries. Click on the Add button. The Choose Tag Libraries dialog opens; this shows under the node User all available taglibraries for all libraries in the project. In my case, I could select the t 1.0.10 Tag Library that is defined inside the tomahwak-1.1.3.jar file. Select that tag library and click on OK (twice).
Step 4 – Update the web.xml file – configure the Tomahawk Extension Filter
Some MyFaces components do more than include some HTML in the pages. They may need additional support scripts, style sheets, images, … Those resources are included in the MyFaces’ jar file (tomahawk-1.1.3.jar) and the Extensions Filter adds the code and URL needed to provide those resources to the generated HTML.
Configuring the Extension Filter is required to get our popup component to work properly. It is an easy task. Open the web.xml file, and add the following code – setting up the filter as well as the filter-mappings to url patterns:
<!-- Extensions Filter --> <filter> <filter-name>extensionsFilter</filter-name> <filter-class>org.apache.myfaces.component.html.util.ExtensionsFilter</filter-class> <init-param> <param-name>uploadMaxFileSize</param-name> <param-value>100m</param-value> <description>Set the size limit for uploaded files. Format: 10 - 10 bytes 10k - 10 KB 10m - 10 MB 1g - 1 GB </description> </init-param> <init-param> <param-name>uploadThresholdSize</param-name> <param-value>100k</param-value> <description>Set the threshold size - files below this limit are stored in memory, files above this limit are stored on disk. Format: 10 - 10 bytes 10k - 10 KB 10m - 10 MB 1g - 1 GB </description> </init-param> <!-- <init-param> <param-name>uploadRepositoryPath</param-name> <param-value>/temp</param-value> <description>Set the path where the intermediary files will be stored. </description> </init-param>--> </filter> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>*.jsf</url-pattern> </filter-mapping> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>*.jspx</url-pattern> </filter-mapping> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping> <filter-mapping> <filter-name>extensionsFilter</filter-name> <url-pattern>/faces/*</url-pattern> </filter-mapping>
See http://myfaces.apache.org/tomahawk/extensionsFilter.html for more details on the extension filter.
Step 5 – Create a CSS with the popup-style (optional)
We can setup a CSS with specific style definitions to use for the popup. However, these definitions are optional and the popup will display fine without additional stylesheet.
Step 6 – Add the tomahawk namespace to your JSPX page
In order to be able to use Tomahawk components, we need to add the Taglib URI as a namespace to the page. The following entry is added to the jsp:root element:
xmlns:t="http://myfaces.apache.org/tomahawk"
Step 7 – Include the Popup element in the page and add content to its popup facet
Now at long last we can start using the Popup element for real. The element itself is very simple:
<t:popup styleClass="popup" closePopupOnExitingElement="false" closePopupOnExitingPopup="true" displayAtDistanceX="60" displayAtDistanceY="-150"> <h:outputText value="Text to hover in order to bring up the popup"/> <f:facet name="popup"> <h:outputText value="Content of the Popup"/> </f:facet> </t:popup>
It is up to us to specify the content of the popup, by adding components to the popup facet, like this:
<t:popup styleClass="popup" closePopupOnExitingElement="false" closePopupOnExitingPopup="true" displayAtDistanceX="60" displayAtDistanceY="-150"> <h:outputText value="Column Control Panel ..."/> <f:facet name="popup"> <af:panelBox> <af:panelGroup layout="vertical"> <af:outputLabel for="colsMonitor" value="Specify which columns to display as well as their sequence "/> <af:selectOrderShuttle value="#{tableBean.columns}" reorderOnly="false" id="colsMonitor"> <af:selectItem label="Empno" value="Empno"/> <af:selectItem label="Name" value="Ename"/> <af:selectItem label="Job" value="Job"/> <af:selectItem label="Department" value="Deptno"/> <af:selectItem label="Hiredate" value="Hiredate"/> <af:selectItem label="Salary" value="Sal"/> <af:selectItem label="Commission" value="Comm"/> <af:selectItem label="Manager" value="Mgr"/> </af:selectOrderShuttle> <af:objectSpacer height="15"/> <af:commandButton text="Apply Column-settings" action="#{tableBean.commandButton_action}"/> </af:panelGroup> </af:panelBox> </f:facet> </t:popup>
Step 8 – Run the application
And behold…
Resources
The original article describing the implementation of the Column Control: Changing the order of columns in a JSF Table Component -in the client, at run-time, by the end user
A previous article on setting up Apache MyFaces with JDeveloper 10.1.3: Getting started with Java Server Faces (JSF) using Apache MyFaces – in JDeveloper 10.1.3EA
Homepage for Apache MyFaces – Tomahawk: http://myfaces.apache.org/tomahawk/index.html and more specifically the Popup Component.
Helo Lucas,
I used your example to add Tomahawk to Jdeveloper.
I am trying to run t:dataTable and t: dataScroller example from tomahawk examples, didn’t make any changes to the code, but buttons links are not rendering correctly.
I get first and next, it should be and image tag inside the tag
Do you have any suggessions?
Thank you, Irina.
Is there a way to tie the popup to a row of a table? For example, I have a three by nine table and want each of the nine rows to have a different popup in the 3rd column. The behavior I’m seeing is that each of the nine rows is displaying the same text as the first row in the popup. Any ideas how to uniquely set this? The source of the page does have the specific text associated with each row.
That’s fine,
I am trying to pop a page. How can do it within t:popup
Hello Lucas,
Thanks for a nice article,
I could get the tomahawk popup div(Shuttle) displayed ,but I’m getting roblem with ADF faces.I could not get the ADF faces table displayed.
I entered the web.xml entries for Extensions filter.
Still
I’m getting the following error :
WARNING: No AdfRenderingContext available
Jan 29, 2007 3:31:08 PM org.apache.myfaces.renderkit.html.util.MyFacesResourceLoader getLastModified
SEVERE: Unparsable lastModified : @lastModified@
Jan 29, 2007 3:31:15 PM oracle.adfinternal.view.faces.renderkit.AdfRenderingContext attach
WARNING: Trying to attach AdfRenderingContext to a thread that already had one.
Jan 29, 2007 3:31:15 PM oracle.adfinternal.view.faces.renderkit.core.CoreRenderKit encodeFinally
WARNING: No AdfRenderingContext available
could you please help me fix the issue.
Thanks in advance,
Samba.
Has anyone been successful with this example. I’ve invested a couple of hours with no success. I can’t even get jspx to compile following instructions.
I think the versions of adf/jsf / bc4j / commons, tomahawk are incompatible I’m using.
not working