Archive for the 'JSF' Category

November 4th, 2010
5:22 pm
Creating Primefaces icon buttons using the built in theme icons

Posted under JSF
Tags , , ,

There is a quite a large collection of useful built in icons, such as those used for the table paginator buttons. It is useful to be able to reuse these in your own buttons:-

  • It simplifies coding as you don’t need to roll your own icons.
  • The Unicode character set has quite an extensive library of symbols (see here for details of how to use numeric unicode references in HTML to access them), and it is at first tempting to use them as they are readily available. The font color used for them will change automatically with your chosen theme, so it seems like you might be home free with minimal effort for buttons with symbols on, by just using them as text labels on a button. However,  you are at the mercy of the theme font stack/Browser font fallback/font rendering as to how well they are represented in a given font. When I tried some of them out the rendering was very poor in some Primefaces themes, and getting them centrally positioned on buttons of various sizes involved some quirky bits of CSS which were dependent on your chosen font size, particularly if you wanted multiple symbols on a button (e.g. 2 triangles to give a double arrow). I decided this was a blind alley and in the end discovered that using the theme icons was better and easier. 
  • You don’t need to tweak a set of new ones for each theme. Themeroller may assist with recolouring them for a theme (haven’t used it yet) but even if it does reusing is still easier than running themeroller to tweak every theme.
  • It promotes consistency – your own e.g. arrow buttons can have the same look and feel as e.g. the table paginator ones, so as well as making your life easier you have scored points for better user interface design. When a user sees the same icon used consistently in different places this gives a strong visual cue on how the interface works and what to expect.
  • Reusing them minimises downloading and caching additional icons.

After quite a bit a bit of experimentation with both commandButtons and commandLinks, and learning about how JQuery (which Primefaces is based on) works,  I came up with the following example page which illustrates how to add a built in theme icon to a commandButton:-

 

<!DOCTYPE HTML>
<html xmlns=’http://www.w3c.org/1999/xhtml’
   xmlns:f=’http://java.sun.com/jsf/core’
   xmlns:h=’http://java.sun.com/jsf/html’
   xmlns:p=’http://primefaces.prime.com.tr/ui’>
<f:view contentType=’text/html’>
<h:head>
    <link type=”text/css” rel=”stylesheet”
     href=”#{request.contextPath}/themes/cupertino/skin.css” />    
    
    <style type=”text/css”>       
        .ui-widget, .ui-widget .ui-widget {
            font-size: 80% !important;
        }
        .ss-iconbutton {
            height:21px;
            width:30px;
        }
        .ss-spacer {margin-right:4px;}
        .ss-iconbutton-icon {
            background-color: transparent;
            border:none;
        }
    </style>
</h:head>
<h:body>
<h:form>
    <p:commandButton styleClass=”ss-iconbutton ss-spacer” onclick=”alert(‘Previous button clicked’)”
      image=”ss-iconbutton-icon ui-icon ui-icon-seek-prev”/>
    <p:commandButton styleClass=”ss-iconbutton” onclick=”alert(‘Next button clicked’)”
      image=”ss-iconbutton-icon ui-icon ui-icon-seek-next”/>                               
</h:form> 
</h:body>
</f:view>
</html>

 

Note the following points about the example:-

  • The image property of the commandButton accepts a CSS class which loads the icon as a background property. If you inspect one of the command buttons e.g. with Firebug you will note that it applies this class to a <span> tag. The advantage of this is that the icon is defined in theme switched CSS rather than HTML. Note that as is normal when applying CSS classes, multiple classes may be passed as a space separated list as I have done.
  • The example uses some of the standard jQueryCSS classes from WebContent/themes/cupertino/skin.css which is the skinning css present for each theme (in this case, the theme used is cupertino).
  • Class ui-icon defines and loads an icon file for the theme. The chosen file may be modified by the jQuery state classes such as ui-state-default, ui-state-disabled, ui-state hover etc. Therefore,the added benefit of using the standard jQuery classes and icon files is that mouse hover automatically causes a switch of icon file to change the colour as determined by the theme, and things like enable/disable of the button also have the correct effect. In short – it all just works as it should with no effort if the built-in classes are correctly used.
  • A fundamental mechanism used by jQuery for states like hover is to use Javascript functions triggered by the hover/mouseover to dynamically add and remove CSS classes from elements. For example, class ui-state-hover is added and removed on hover. this may be seen within Firebug when you hover over the button with the mouse. Note that therefore jQuery does not only use CSS Pseudo-classes such as :hover, :active to support this as one might expect. Examples of the latter will be found in skin.css  but they do not give the whole picture about what is going on internally. This is presumably done for reasons of browser compatibility as CSS pseudo classes do not work consistently across different element types and browsers (IE is especially limited in this regard).
  • Primefaces/jQuery stores multiple icons in a single icon file, and uses the css background-position property with appropriate X and Y pixel coordinates in the file to pick out the desired icon. If an icon file is examined with Windows you will see all the icons store in the file in a matrix fashion. A set of classes is defined in skin.css , one for each icon, to encapsulate the position of that icon within the icon file. In the above example, ui-icon-seek-prev and ui-icon-seek-next have been used to select the next and previous icons used on the dataTable paginator.
  • By default, the icon in a commandButton is given a border and a background colour, which in this case we do not want. These are removed by class ss-iconbutton-icon above which is also passed as one of the classes to the image attribute of the commandButton.
  • Whilst we are to an extent going “under the hood” and using mechanisms and CSS classes which are not part of the documented Primefaces interface, they are a standard part of jQuery upon which Primefaces is based. When extending a user interface a fashion similar to the above, it is highly recommended to gain familiarity with the workings and operation of jQuery, as this can allow additional functionality to be harmonised with the existing functionality. This will typically make adding functionality easier, promote consistency with the existing feature set, and as in this case can give a number of side benefits for no extra work. Of course, using features that are not part of a formally documented Primefaces interface may mean that your code needs to change with later releases, but in this case, as these are jQuery features, it definitely feels the right way to go.

 

The jQuery UI web site, which contains full documentation, tutorials and demos,  may be found here. In my opinion it is certainly worth delving into further to augment your understanding of Primefaces, especially when you want to extend or reuse features and components in ways like the above example.

No Comments »

November 4th, 2010
1:54 pm
How to add inline Javascript to a Facelets/XHTML page

Posted under JSF
Tags , , , ,

This is not immediately obvious; the following are the key points:-

  • The Javascript code between the script tags needs to be embedded in XML “CDATA” sections
  • The CDATA open and close tags need to be preceded with Javascript comment markers “//”
  • You can freely use JSF Expression language within the Javascript and it will be evaluated and inserted (as with the “request.contextPath” below)

The following example xhtml page illustrates this:-

<!DOCTYPE HTML>
<html xmlns=’http://www.w3c.org/1999/xhtml’
   xmlns:f=’http://java.sun.com/jsf/core’
   xmlns:h=’http://java.sun.com/jsf/html’>
<f:view contentType=”text/html”>
<h:head>
<script type=”text/javascript”>
//<![CDATA[
    alert(“Hello World from #{request.contextPath}”);
//]]>
</script>
</h:head>
<h:body></h:body>
</f:view>
</html>

No Comments »

October 27th, 2010
2:07 pm
Primefaces Hotkey Component

Posted under JSF
Tags , , ,

This component binds a hotkey combination to specified javascript event handlers or ajax calls.
Unfortunately The Primefaces docs do not fully document the hotkey bindings.

This component appears to be based on the JQuery  js-hotkeys plugin which is documented here and has more details about the bindings and operation.

Note that some bindings are browser dependent – i.e. some browsers may not allow a browser hotkey to be overridden.
Also one gotcha to look out for is that hotkey prefixes (alt, ctrl) etc. are case insensitive but must be placed in alphabetic order, so ctrl-alt-s will not work.

No Comments »

September 25th, 2010
11:32 am
Primefaces test application does not display correctly with Google Chrome

Posted under JSF
Tags , , , , ,

A simple Primefaces table sample application was not displaying in Chrome. Some of the output data from the cells plus some other metadata was displayed as raw text with no formatting.

This answer to FAQ question 6 in the documentation PDF details the problem and the solution:-

6. With facelets some components like charts do not work in Safari or Chrome but there?s no problem with Firefox.
The common reason is the response mimeType when using with PrimeFaces with facelets. You need to make sure responseType is “text/html”. With facelets you can use the <f:view contentType=”text/html”> to enforce this setting.

I added this to the sample code and Chrome then worked correctly. I checked the Primefaces Showcase and note that the same is done there.

No Comments »

January 8th, 2010
9:30 pm
JSF 1.2/Facelets event & state handling

Posted under JSF
Tags , , ,

The issue here came about when trying to propagate click events from a child table pair tag to its parent facelet page. The table pair contained buttons to move rows between the tables, and to reorder rows on the target table – a typical design pattern used in this case to assign roles and rights to a user. The table pair tag is responsible for all the buttons for this function – move row selection left/right, move all left/right, reorder target row selection up, reorder target row selection down.

My general design in this situation is for the backing bean structure to mirror the objects on the page. There is therefore an overall page bean which has a child table pair bean for the table pair facelet tag, which in turn has 2 child table beans for its subsidiary facelet table tags. Whilst the parent facelet page does not need to know about the above button logic (it just pulls the result rows out of the child beans e.g. when a save is done), it does need to know when the child table pair has caused the page to be dirty, i.e. to have unsaved changes, which comes about when one of the above buttons is clicked.

My ideal solution to this would be to add an additional action listener on the table pair buttons – the main one is handled by the table pair bean, and an additional one on each button calls a single method on the overall page bean to notify that the page has changed. The parent does not need to know which button was clicked or why, but merely to know that a change has occurred. However this idea is scuppered in JSF 1.2 by the fact that a secondary f:actionListener tag on a button does not accept a method binding like the primary actionListener, but takes a fully qualified class name which must implement the ActionListener interface. This is a right pain as it is a class and not even an instance – you cannot tie the event to a particular bean.

My next attempt was to simply inject a parent reference in the TablePair bean in faces-config.xml, however this fails because JSF does not allow cyclic references in faces-config.

My final solution was therefore to pass a value binding for my own ChangeListener interface on the parent bean to the TablePair tag as a parameter, and declare this on each button using f:attribute. The TablePair bean then fetches the bean reference from the attribute when its actionListener is fired and calls the notify method on the reference’s Change Listener implementation. (I could also have used setPropertyActionListener to simplify this but an ICEfaces bug prevented this working – setPropertyActionListener was being called after the actionListener so the latter only ever saw a null value). The following code fragment illustrates what was used to pull the reference out of the attribute (note that this is incomplete and imports etc. are missing) :-

// Calling code
  private static final String CHANGE_LISTENER_ATTRIBUTE = "changeListener";
  ...
  ChangeListener changeListener =
    JSFUtil.fetchComponentAttribute(actionEvent, CHANGE_LISTENER_ATTRIBUTE);
  if (changeListener != null)
    changeListener.notify(this);
...
// Utility Class
public class JSFUtil {
  public static<F> F fetchComponentAttribute(ActionEvent actionEvent, String attribute) {
    UIComponent component = actionEvent.getComponent();
    Map<String, Object> attributes = component.getAttributes();
    return (F)(attributes.get(attribute));
  }
}

When propagating changes like this, it is important that the design does not cause recursive notifications, for example where a change gets passed up from one child to a parent, back down from the parent to all its children, who send it back up and so on. To this end, I therefore distinguish between the following concepts to avoid this happening:-

  1. Action Notification Events are only propagated upwards from children to parents, and are only raised in respect of external actions,  for example when a button click in a child tag causes a change which the parent needs to know about. ActionNotifications are never raised as a result of a property change on a component which could have been initiated by a parent. For clarity, if an external action causes a property change and needs to propagate this upwards, it is the fact that an external action occurred which is being propagated, and not the fact that a property has changed, i.e. in JSF terms it is the result of an action event and not a value change event. This means that whilst such an external action will pass an event up as well as changing a property, if a parent directly changes the same property, no event will be propagated up.  A child cannot directly change properties in its parent so it needs this mechanism to tell the parent “something external such as a button or link click has happened in me which you need to be aware of”. Typically this will be because a click action on the child has made the whole page dirty and the parent therefore needs to change component state throughout the page to reflect this (for example to enable the save and discard buttons and disable navigation from the page). As notifications only travel upwards, recursive notifications cannot therefore occur.
  2. Property Changes are only performed by a component on itself or on its child components. On itself, it can change any of its internal properties. On a child component, it can change any of the publically changeable properties of the child. As stated above, such changes will never give rise to action notification event propagation. However, property changes can certainly propagate downwards as required.

The state determination of a JSF page or a custom component can become complex when a number of components need to be, for example, selectively enabled and disabled depending on various property combinations. If the logic to determine the state is scattered throughout the component’s managed bean, or even worse, is coded in value expressions on a JSF page, it is hard to make sense of the state determination logic, easy to miss logic that is required, and easy to break the state determination when the code is changed. Therefore, I always use a private changeState method on a bean to perform all the state determination and changes. Typically this will involve a ladder of if..else based logic which checks properties on the bean, and then for example sets or clears various enable/disable properties for the JSF components. In State Machine terms, the various properties of the bean are inputs to the changeState method, and the method uses these inputs to determine a new state for the bean, setting various properties for the new state. I am not fussy about the precise implementation of this – in complex cases, it may be worth using a state machine/state table driven approach to determine state, and maintain a ‘current state’ for the bean which is independant of the beans properties, but for most normal cases this is overkill. What is important is to use an implementation which is clear, correct and easy to maintain, and where the mechanism is easy to understand and flows naturally from the state change requirements. This method should be called whenever a change happens to any of the inputs which the method uses to determine state, and therefore will normally be called many times throughout the bean. If AOP is in use, this might be a good candidate for using a pointcut and advice to dynamically insert the calls, for example on various property changes. In typical cases, I end up with a dirty flag on the bean which indicates that something has changed, and the changeState method checks the flag and sets various enable/disable properties as required. It is therefore often worth having an overloaded version of changeState which allows new values of such inputs to be passed in and set, and then the state change logic performed, in a single call.

As mentioned earlier, I specifically do not perform any such logic on a JSF page. The presence of logic in value expressions on a JSF page is a warning bell as it may indicate that either MVC controller logic or worse,  business logic has been placed on the page. As an example, my TablePair bean allows the ‘move selected rows to destination’ button to be clicked if any rows have been selected in the source table – otherwise the button is disabled. It would be possible to code an ‘anyRowsSelected’ property on the bean, and call this property directly from the disable attribute on the JSF page. Whilst this is a simple example, I would contend that this effectively places a controller logic decision in the MVC view. The correct way would be for the disable property on the button to directly refer to an enable/disable flag on the bean, and for the changeState method in the bean to call anyRowsSelected as a method, and set the enable/disable flag as required. This removes all evidence of the logic from the view, and also means that if the logic changes, for example if other conditions can occur on the bean which affect the button state, the change is made in the correct place – only in the changeState method on the bean. The JSF page would not need to be touched and has no knowledge of this.

No Comments »

January 8th, 2010
5:35 pm
ICEfaces ice:form tag adds extra auto margin in IE7

Posted under JSF
Tags , , , ,

The ice:form tag renders a stateSavingMarker div which declares a couple of hidden fields for use by ICEfaces.

In IE7, (or IE8 in IE& compatibility mode), this div has its margin to auto which can cause an extra 10px or so margin to be added in between any elements outside the form and those inside.

This can be eliminated by adding a style to the form, either by adding a StyleClass attribute to refer to a CSS class, or by using the Style attribute to code an inline style. As this is a ‘one off’ just to clear a margin, the following example uses an inline style :-

<ice:form style=”margin:0″>

No Comments »

January 8th, 2010
4:22 pm
Unable to execute JSF Lifecycle – Duplicate ID tags in JSF

Posted under JSF
Tags ,

A common gotcha this one which has had me scratching my head a few times. ID tags on elements must be unique, and if you duplicate one as I did on an ICEfaces table, you get a nice big stack trace saying “Unable to execute JSF lifecycle” amongst many other things. It is not obvious that this is the cause, and the IDE does not appear to pick it up even if you do a validate, so it is worth remembering and checking for, as it gives the impression that something much nastier has happened! (Some duplicates do not appear cause the problem but should be weeded out anyway).

No Comments »

January 8th, 2010
4:20 pm
Adding jsf view state to domain objects

Posted under JSF
Tags , ,

A classic example of this is the need to add a selected flag to each row if you are using row selection with an ICEfaces table.

The fundamental point here is that you do not want to pollute the domain objects with state that is specific to the view – in this case, the flag is merely a convenience for supporting the user interface.

This post details a good solution to this problem, which is to use the decorator pattern to decorate the row domain objects with a decorator containing the row selected flag. Often, a decorator has an identical interface to its decorated object, but that is not always the case, and in this case we actually need to add a property. This does however mean that you have to be aware of which class you are using at a given point in the code, and you cannot use a generic decorator interface to declare the concrete decorators if they have new properties added. Also, if you have a number of such decorators, you cannot wrap the domain objects with them transparently in turn for the same reason. You can get around some of this with some clever use of reflection, but it does complicate matters and impact performance.

The ICEfaces page on row selection may be found here.

No Comments »

January 8th, 2010
3:25 pm
JSF: #{…} is not allowed in template text

Posted under JSF
Tags , , , , ,

This error can occur when loading a JSF/Facelets page :-

org.apache.jasper.JasperException: /home.jspx(16,17)
   #{...} is not allowed in template text

One reason for this, described on JavaRanch here, is that the JSF page is not being routed properly via the servlet mapping in web.xml. The following extract from web.xml shows a mapping for .iface, to route urls ending in .iface to the ICEfaces Persistent Faces Servlet:-

    <servlet-mapping>
        <servlet-name>Persistent Faces Servlet</servlet-name>
        <url-pattern>*.iface</url-pattern>
    </servlet-mapping>

Even though the page itself may be a .jspx file, using .jspx rather than .iface in the url would not route the page to the above servlet, causing it to be parsed incorrectly. This post describes the cause in more detail – the #{…} syntax is unified EL, which is not allowed in template text in a JSP (hence the error). In the above case the page was being treated as a JSP rather than a Facelet due to the incorrect routing.

No Comments »

January 8th, 2010
10:42 am
ICEfaces facelets strips DOCTYPE, puts IE in quirks mode

Posted under JSF
Tags , , , , ,

By default when you create a new ICEfaces Facelets project with a sample page, it codes the DOCTYPE directive directly. Unfortunately, this is stripped out during processing/rendering and does not  appear in the final HTML for the page. When running IE without a suitable DOCTYPE directive, it switches into Quirks Mode and is not fully standards compliant, which may cause pages to display incorrectly.

the DOCTYPE can be added back by using the <ice:outputDeclaration> tag. To do this, you also need to add an <f:view> tag as you would in JSP mode, as in the following example :-

<?xml version="1.0" encoding="UTF-8"?>
<f:view xmlns="http://www.w3.org/1999/xhtml"
 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:ice="http://www.icesoft.com/icefaces/component">
 <ice:outputDeclaration
  doctypeRoot="HTML" doctypePublic="-//W3C//DTD XHTML 1.0 Transitional//EN"
  doctypeSystem="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" />
 <html>
    <head>
    ...
    </head>
    <body>
    ...
    </body>
 </html>
</f:view>

The issue is discussed and solved in this ICEfaces forum post. Interestingly, a page created by ICEfaces for a  JSP (non-facelet) project also uses the <ice:outputDeclaration> tag, presumably for the same reason.

Note that you cannot omit the <f:view> tag and add the xmlns namespace declarations to the <ice:outputDeclaration> tag as this fails – the <f:view> tag needs to be present.

Another post about Quirks mode and DOCTYPE switching, which also contains a useful Bookmarklet (Javascript link) which will tell you directly what mode a page is running in, may be found here.

No Comments »