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 »

Trackback URI | Comments RSS

Leave a Reply

You must be logged in to post a comment.