Archive for March, 2011

March 28th, 2011
11:02 am
Eclipselink error in Eclipse–Schema “null” cannot be resolved….

Posted under JPA
Tags , , ,

This error came up while building a new development environment with the Eclipse Helios SR2 and Eclipselink 2.2.0.
The error appeared for every JPA entity, even after the database drivers/connections were correctly defined.

The simple answer  as detailed here is to right click the project and do a validate – hey presto, all the errors disappear!
This appears to have been around a while and is still not fixed in Eclipselink 2.2.0, but at least it is simple to resolve.

The tip was found on this Oracle tutorial post :-

Note:

If you encounter a Schema “null” cannot be resolved for table “<TABLE_NAME>” error, you’ve hit a known Eclipse bug.
To resolve the issue, right-click the project and choose select Validate from menu. Eclipse will clear the errors.

No Comments »

March 25th, 2011
6:43 pm
Creating Javascript Objects using new – the pros and cons

Posted under Javascript
Tags , ,

There are a number of pros and cons regarding this practice, and they are debated on StackOverflow here. A w3schools tutorial on it may be found here.

I have used this e.g. here, following the lead of the Primefaces dialog.js. A downside is that your code fails if you forget the new and just call the function instead. However, this can be detected and an error thrown as per the StackOverflow post. In my case, the thrown error was not easily detected so I elected to pop an alert as well.

I do not discuss the issue further here – just follow the links and you will find plenty of information on it.

No Comments »

March 25th, 2011
6:42 pm
Implementing confirmation dialogs with Primefaces p:dialog

Posted under JSF
Tags , , , , ,

Update 7/3/2012

Primefaces p:ajax partial refreshes can also be blocked by returning false to the onclick event.  In this case, an If statement needs to be used, so that “return false” is done to block the refresh, but no return at all is done to allow the refresh. This allows the Primefaces ppr logic to execute – returning true explicitly in the onclick actually stops the ppr/ajax logic from executing at all:-

onclick="if (!confirmAction(Arguments)) {return false};"

The nice feature of this method is that it works in an identical fashion for both full page and partial refreshes, so that is is not necessary to mess with logic which couples both the onstart and onclick attributes based on the ajax setting.

The downside is that as before we are adding bare Javascript logic into an element attribute. In defence, this situation has already been forced on us by the JSF/Primefaces design – the interface already requires us to return false to block a request, so whilst this might be distasteful from a purist Javascript point of view, it is a fact of life we have to live with.

 

Original Post

Confirmation dialogs are typically used when for example a form is being edited and a navigation to another page is attempted.

Traditionally, this might be done by using the Javascript confirm function which pops a browser dialog, and returns true or false depending on the user choice. However, modern web apps shy away from using browser popup dialogs. Their styling is browser dependant and they cannot be restyled. A modern app will use custom styled dialogs with features like fade in/out and lightboxing to give a more subtle appearance and to allow the dialog to be displayed in-page to avoid popup blocking problems. Also, component libraries such as Primefaces allow custom themes and theme switching for an application, which would therefore allow their own custom dialogs to be dynamically restyled.

The fundamental complication when using such a custom dialog is that unlike the built-in Javascript confirm function, it does not operate synchronously. This immediately raises major issues when using it to confirm navigation, as it cannot be used inline in a navigation confirmation event on a button or link.  This post looks at how to get around this issue and use a Primefaces p:dialog to implement a confirmation dialog.

 

Allowing or blocking navigation attempts

The first point to address is how we can actually allow or block a navigation attempt on a Primefaces/JSF button or link. There are two options available, which are straightforward and applicable to all buttons and links:-

  • For full page refreshes, returning false from the onclick event aborts the navigation. This is a standard JSF feature which is described here. It is also mentioned in Core Javaserver Faces Edition III on p573, although it must be said that it is rather hidden near the back of the book and hard to dig out.
  • For Primefaces p:ajax partial refreshes, returning false from the onstart event aborts the ajax call.

Note that in both cases, it is important to prefix the function call with the return statement, otherwise the function return value is not correctly returned by the event call. For example, using the traditional Javascript confirm function:-

  • onclick=”return confirm(‘Pending edits will be cancelled, do you want to continue?’);”
  • onstart=”return confirm(‘Pending edits will be cancelled, do you want to continue?’);”

When applying a default case, it is also possible to just return true or false without calling anything, e.g. using onclick=”return true;”

 

Using the p:dialog  to allow/block the navigation

This is a little tricky to get right, but actually turns out to be fairly straightforward, and in particular, we can still initiate the whole process from a single function call in the onclick or onstart event as above. The idea makes use of the fact that we can issue a soft click on an HTML (or in this case jQuery) element using the .click() call. The steps are as follows :-

  1. The user clicks on a button, which causes our own Javascript confirm(elementId) function to be called by say the onstart event. Importantly, the clientId of the target element which was clicked is passed and stored, as it may be needed later.
  2. if edit mode is inactive, the function just returns true to allow the action.
  3. If edit mode is active, then the function sets an internal confirmInProgress flag and shows the confirmation p:dialog via its widget show() function. The function then returns false to (initially) block the Ajax action.
  4. When the dialog is displayed and the user clicks No, a Javascript cancelAction() function is called which hides the dialog and clears the confirmInProgress flag. The Ajax action is not then performed.
  5. When the dialog is displayed and the user clicks Yes, a Javascript performAction() function is called which hides the dialog and forces a second (software) click on the button, using the previously stored elementId. This results in confirm() being called a second time.
  6. When confirm() is called the second time via the software click (because the user clicked yes to confirm), we can detect this as the confirmInProgress flag will be set. The function then clears the confirmInProgress flag and returns true to allow the Ajax action to proceed.

 

Implementation Points

  • When implementing this, my confirmation dialog is a facelets custom tag. Within the tag, I create a Javascript object (whose precise name is passed by the caller) which contains the above logic and manages the confirmation process.
  • The Javascript object is created via the new keyword – see my other post here with links on this topic.
  • I then pass the confirm function call used on this object as a text attribute value to any tags, buttons or links that need to implement confirmation. For a high level tag I would pass it as an onNavigate attribute, and within the tag it would be passed on to any links or buttons to which it applies.
  • In order to do the software click, the clientId of the element that was clicked is passed to the confirm function and stored on the Javascript object. To do this, the confirm function call is passed as a MessageFormat style string with a placeholder which will take the clientId, as this must be added by the target button typically via a reference to #{component.clientId}. In this way the final target could add additional parameters if required, but is nicely decoupled from the actual Javascript call. The only interface contract is the placeholder parameter index, and the fact that a boolean must be returned to permit/deny navigation. I typically add MessageFormat.format (in addition to string concatenation) as custom EL java functions declared in a tag library – in the example below, these functions have the el: prefix.
  • In our case, the actual element clientId is a constant string as far as the Javascript call is concerned, so it must have single quotes added. These are added in the context of the target element – they are not passed in the MessageFormat string. This way, the caller does not decide whether or not a parameter is a Javascript String – this is decided in the target element environment. For example, if an additional argument such as a JavaScript reference such as this was passed in the target element environment, it would not need to be quoted, and the caller’s MessageFormat string containing the Javascript call would not have to know. This maintains good decoupling.
  • The Javascript object also has an internal confirmMode property which indicates whether confirmation mode is actually on, i.e. if edit mode is active. If not, it just permits everything as per the above logic steps. This JS property would normally be set from an edit mode bean property on the actual edit form which triggers the confirm. To do this, I pass the JS property reference in to the tag handling the edit form. and it calls a standard utility tag to issue an inline script statement to assign the property reference from the bean. This assignment needs to be within a div which is updated by ajax when the edit mode changes, to ensure the property is reassigned.

 

Example Code Fragments

Facelets Page declaring the Confirmation Dialog

<util2:confirmActionDialog tagId="confirmDialog" widgetVar="confirmWidget" />           

<cheep:campaignTreeBrowser id="campaignTreeBrowser" idPath="#{form}" currentNodeChange="#{form}:pnlCampaignDetail"
                           currentNodeChangeOnComplete="ss_PanelExpand(widgetVarPnlCampaignDetail)"
                           controller="#{campaignsPage.campaignTreeBrowser}" edit="#{true}"
                           onNavigate="confirmWidget.confirm({0})"/>
                                                             
<cheep:campaignDetailPanel tagId="pnlCampaignDetail" idPath="#{form}" editModeFlag="confirmWidget.confirmMode"
                           controller="#{campaignsPage.campaignDetailPanel}"/>

confirmActionDialog.xhtml custom tag

<!DOCTYPE HTML>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jsp/jstl/core"   
xmlns:p="http://primefaces.prime.com.tr/ui"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:util="http://java.sun.com/jsf/composite/uk.co.salientsoft/util">

<ui:composition>
    <h:outputScript library="uk.co.salientsoft/util" name="confirmActionDialog.js" target="head"/>
       
    <script type="text/javascript">#{widgetVar} = new uk.co.salientsoft.ConfirmActionDialog();</script>   
   
    <p:confirmDialog id="#{tagId}" widgetVar="#{widgetVar}.dialogWidget" styleClass="ss-confirmaction-dialog"
                message="#{empty confirmMessage ? mainMsg.confirmEditCancel : confirmMessage}"
                showEffect="fade" hideEffect="fade"
                header="#{empty confirmTitle ? mainMsg.confirmEditCancelTitle : confirmTitle}" severity="alert">
               
        <util:iconTextButton id="cmdAbort"  image="ui-icon ui-icon-close"
                label="#{mainMsg.optionNo}" title="#{mainMsg.optionTitleNo}" onclick="#{widgetVar}.cancelAction()" />                                                    
       
        <util:iconTextButton id="cmdConfirm"  image="ui-icon ui-icon-check" 
                label="#{mainMsg.optionYes}" title="#{mainMsg.optionTitleYes}" onclick="#{widgetVar}.performAction()" />
    </p:confirmDialog>
</ui:composition>
</html>

Setting the EditMode flag in the campaignDetailPanel edit form

<!– Set the edit mode state in the specified Javascript flag used by the navigation confirmation dialog when in edit mode –>
<util2:setScriptVar name="#{editModeFlag}" value="#{controller.editMode}" defaultValue="false" />

Custom tag util2:setScriptVar

<!DOCTYPE HTML>
<html xmlns="http://www.w3c.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"   
xmlns:el="http://salientsoft.co.uk/EL">

    <ui:composition>   
        <!– Set the specified Javascript variable/property from the given EL expression –>
        <c:if test="#{not empty name}">
            <script type="text/javascript">#{name} = #{empty value ? defaultValue : value};</script>
        </c:if>
    </ui:composition>
</html>

Code within a link which adds the actual onstart event (this example is taken from a composite component)

<p:commandLink id="link" ajax="#{cc.attrs.ajax}" async="#{cc.attrs.async}" disabled="#{cc.attrs.disabled}"
         action="#{cc.attrs.controller.iconButtonAction(cc.attrs.eventHandler, cc.attrs.actionMethod,
                              cc.attrs.actionParam, cc.attrs.passController, cc.attrs.passActionParam)}"
         actionListener="#{cc.attrs.controller.iconButtonActionListener}"
         process="#{cc.attrs.process}" update="#{cc.attrs.update}" immediate="#{cc.attrs.immediate}"
         href="#{cc.attrs.href}" title="#{cc.attrs.title}" tabindex="#{cc.attrs.tabIndex}"
        onstart="return #{empty cc.attrs.onNavigate ? ‘true’ : el:format1(cc.attrs.onNavigate, el:concat3(‘\”, component.clientId, ‘\”))}"
         oncomplete="#{cc.attrs.oncomplete}" onsuccess="#{cc.attrs.onsuccess}" onerror="#{cc.attrs.onerror}">
…   

</p:commandLink>

Javascript object ConfirmActionDialog.js

/*
* This object handles the logic for confirming Primefaces Ajax actions via a confirmation dialog.
* It is typically used to pop a confirmation when in edit mode on a form and e.g. a navigation link/button has been clicked.
* A navigation link/button should call confirm() in its onstart Ajax event. The following then happens:-
*
* 1/ if EditMode is inactive, confirm() just returns true to allow the action.
* 2/ If EditMode is active, then confirm() pops the confirm dialog and returns false to (initially) block the Ajax action.
* 3/ When the dialog is popped and the user clicks No, hide the dialog and return to the idle state (Ajax action not performed).
* 4/ When the dialog is popped and the user clicks Yes, we hide the dialog and force a software click on the Ajax link/button.
* 5/ When confirm() is called the second time via the software click (because the user clicked yes to confirm),
*    return to the idle state and return true to allow the Ajax action.
*/

var uk=uk||{}; uk.co=uk.co||{}; uk.co.salientsoft=uk.co.salientsoft||{};
uk.co.salientsoft.ConfirmActionDialog = function () {
    this.confirmInProgress = false; //initialise to the idle state
    this.confirmMode = false; //set no confirmation needed initially (e.g. not in edit mode)
};

uk.co.salientsoft.ConfirmActionDialog.prototype.show = function() {
    this.dialogWidget.show();
};

uk.co.salientsoft.ConfirmActionDialog.prototype.hide = function() {
    this.dialogWidget.hide();
};

uk.co.salientsoft.ConfirmActionDialog.prototype.confirm = function(elementId) {
    if (this.confirmMode && !this.confirmInProgress) {
        var escapedId = ‘#’ + elementId.replace(/:/g, ‘\\3A ‘);
        this.element = jQuery(escapedId);
        this.dialogWidget.show();
        this.confirmInProgress = true;
        return false; //first time in, cancel the Primefaces Ajax action until confirmed
    }
    else {
        /*
         * Either we are not in confirm mode (e.g. edit mode is off),
         * or we are in confirm mode and this is the second time in, called as a result of a confirm.
         * Either way we allow the Primefaces Ajax action, and return to the idle state.
         */
        this.confirmInProgress = false;
        return true;
    }
};

uk.co.salientsoft.ConfirmActionDialog.prototype.performAction = function() {  
    this.dialogWidget.hide();
    this.element.click(); //This will cause confirm() to be called again; this time the Ajax action will be allowed.
};

uk.co.salientsoft.ConfirmActionDialog.prototype.cancelAction = function() {  
    this.dialogWidget.hide();
    this.confirmInProgress = false; //we will not be performing the Ajax action, so return to the idle state
};

No Comments »

March 24th, 2011
6:41 pm
Escaping quotes and other characters in JSF Expression Language

Posted under JSF
Tags , , ,

Some quick points on this are as follows:-

  • If you are using double quotes at the out level e.g. for HTML attributes, use single quotes inside the EL expressions
  • If you need quotes inside the EL, escape them with backslash as per normal Java standards

An example of an attribute containing EL with escaped quotes follows (note that the blog post may mess up the quote appearance slightly) :-

onstart="return #{empty cc.attrs.onstart ? ‘true’ : el:format1(cc.attrs.onstart, el:concat3(‘\”, component.clientId, ‘\”))}"

No Comments »

March 23rd, 2011
4:08 pm
Mapping Browser Keyboard events to Element Clicks

Posted under Javascript
Tags , , ,

I wanted to do this as a way to add keyboard accelerators, mainly for enter and escape when doing editing etc.

The code was already implemented to be driven from mouse click events, so causing keyboard events to soft click particular target buttons for save and cancel was convenient as this was then completely isolated from the rest of the code, which only had to be concerned with being button driven.

I found the following issues during the implementation:-

A keypress event was fine for trapping Enter, but it did not trap escape correctly. For escape, I needed to drive from the keyup event.

My enter event was bubbling up and causing unwanted navigation. I initially tried cancelling bubbling and propagation as detailed here on Quirksmode.org:-

function doSomething(e)
{
    if (!e) var e = window.event;
    e.cancelBubble = true;
    if (e.stopPropagation) e.stopPropagation();
}

This involves catering for browser differences , as shown, as the Microsoft/IE model uses cancelBubble, whereas the W3C model uses stopPropagation. In my case, this did not solve the issue.

My simple solution was for the event handler to return false when it had trapped and handled a keyclick such as enter, and to return true otherwise. Returning false blocked any further action on the event, and was also a standard mechanism. I did not bottom out the actual problem in my case, but this solved it completely.

When implementing the solution, I used the following technique:-

  1. An object literal was created which did a reverse map from all the key codes I might want to trap, to a mnemonic name for them (such as enter, escape, leftArrow).
  2. My event handler call accepts a keyActions object literal argument where the names are the above mnemonics, and the values are the element IDs which need to be clicked when the matching key code is detected.
  3. In the event handler, I reverse lookup the key code to the mnemonic, and then look up the element Id in the passed object literal using the mnemonic.
  4. If I find an element Id, I click it and return false. If I do not find one, I return true as I am not trapping that key.
  5. I also try a lookup on the passed keyActions object using the raw key code. This means that the caller can either use a mnemonic or a key code to specify what key is handled.
  6. The event handler therefore has very little code, and does not need any loops – it just does 2 associative lookups to get the target element to click.
  7. As an additional feature, I allow an idPath key/value to be passed in keyActions. If this is present, any element value which is not prefixed with ‘#’ will be prefixed with the id path, to simplify the call site where a number of elements with a common ID prefix are specified. Elements already prefixed with ‘#’ are left untouched.

This technique would also work well when implementing global key handling attached to the <body> tag. In this case, it may be desirable to switch the global handling depending on what is open on the page. For example, there might be an in-page detail form which is opened in-place and client side using a Primefaces p:panel. In this case, the keyActions object could be switched when the detail panel is opened, and switched back when it is closed.

Another useful trick if the complexity warrants it could be to implement a stack such that detail panels on the page push their own keyActions onto the stack, perhaps inheriting the global ones and modifying them as required. When a detail level is closed, it can just pop the stack and does not need to know about the higher levels of actions on the page. To assist with this, it would be useful to be able to clone the previous level actions when adding a new level. Prototypes could be used for this, but they need constructor functions etc. and do not map well to our simple case which just uses JSON like object literals. The jQuery extend method could be a good choice for this, and is detailed here on StackOverflow by none other than Mr jQuery himself, John Resig (!)

The following example code fragment from a utility object illustrates the idea:-

var uk=uk||{}; uk.co=uk.co||{}; uk.co.salientsoft=uk.co.salientsoft||{};
uk.co.salientsoft.util= {
    clearElement: function(elementId) {
        jQuery(uk.co.salientsoft.util.escapeId(elementId)).val(”);
    },
    escapeId: function(elementId) {
        //a value tests true if it is non-null, non-blank, not NAN, not undefined, and not false
        var escapedId = (elementId) ? ((elementId.charAt(0) == ‘#’ ? ” : ‘#’)  + elementId.replace(/:/g, ‘\\3A ‘)) : ”;
        return escapedId;
    },
    keyCodeNames: {
        /*
         * Common list of keycodes, allowing reverse lookup of name from code.
         * Derived from: http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
         * This only includes the common function/special keys which should be browser independant.
         */
        8:’backspace’,
        9:’tab’,
        13:’enter’,
        16:’shift’,
        17:’ctrl’,
        18:’alt’,
        27:’escape’,
        33:’pageUp’,
        34:’pageDown’,
        35:’end’,
        36:’home’,
        37:’leftArrow’,
        38:’upArrow’,
        39:’rightArrow’,
        40:’downArrow’,
        45:’insert’,
        46:’delete’,
        112:’f1′,
        113:’f2′,
        114:’f3′,
        115:’f4′,
        116:’f5′,
        117:’f6′,
        118:’f7′,
        119:’f8′,
        120:’f9′,
        121:’f10′,
        122:’f11′,
        123:’f12’       
    },
    clickOnKey: function(event, keyActions) {
        /*
         * This is a keyup/keydown/keypress event handler.
         * keyActions is an object literal containing key mnemonics for the keys, and target elements for the values.
         * As well as mnemonics, raw key code numbers can be used.
         * A special object literal key, idPath, may be used to specify a default ID prefix.
         * If present, it is applied to all element IDs which are not prefixed with a ‘#’. 
         * Examples:-
         *    onkeypress="return uk.co.salientsoft.util.clickOnKey(event, {enter:’frm1:cmdSaveNew:link’});"
         *    onkeyup="return uk.co.salientsoft.util.clickOnKey(event, {escape:’cmdCancelNew:link’, idPath:’frm1:’});"
         *
         * NOTE – escape handling does not work on a keypress event.
         * The event is detected, but the click fails to do anything.
         * onkeyup should be used for escape, as this does not suffer from the problem.
         */
        var keycode = (event.keyCode ? event.keyCode : event.which);
       
        /*
         * Try to fetch the target element id from the passed keyActions assuming a string key code name was used, e.g. ‘enter’
         * If this fails, try a lookup based on the raw key code.
         * Doing it this way avoids looping.
         */       
        var actionElement = keyActions[uk.co.salientsoft.util.keyCodeNames[keycode]];
        if (actionElement == null) {
            actionElement = keyActions[keycode];
        }       
       
        /* If found a target for the event keycode, click it
         * and return false to stop any propagation, else return true
         */
        if (actionElement != null) {
            if (actionElement.charAt(0) != ‘#’ && keyActions.idPath != null) {
                actionElement = keyActions.idPath + actionElement;
            }
            jQuery(uk.co.salientsoft.util.escapeId(actionElement)).click();
            return false;
        }
        return true;
    }
};

No Comments »

March 23rd, 2011
3:24 pm
Java Generics–Class literals as run time type tokens

Posted under Java
Tags , , , ,

This post refers to the section on page 16 of the Generics tutorial document by Gilad Bracha.

The example here uses the Cojen dynamic bytecode generation library in order to create custom sort comparators. The advantage of Cojen is that you end up with a fully compiled comparator and therefore do not incur the performance hit of reflective code. Furthermore, comparators generated by Cojen can be cached in a map so that they are only generated once. This particular example borrows some code originally used for Icefaces table sorting, which I adapted for use with Primefaces. Whilst Primefaces does have its own table sorting, I had some issues with it. I wanted visibility of the current sort column and direction, and I wanted control over the sorting – I wanted to reapply the sort to a table when rows were added to it from another table, so that it was always maintained in order. Furthermore, I wanted to maintain the current sort column and direction that had been selected by the user via the column headers when applying the sort when new rows were added. As I had trodden this route before for Icefaces, it was straightforward to move the code over and incorporate it into a standard table controller class which I was already developing.

One issue which I had not previously bottomed out in the Icefaces version was making the code fully generic and fully eliminating all the generic warnings when using a class literal as a run time type token. With Cojen, you call a static forClass method on its BeanComparator to construct a comparator, passing in the class and the comparator ordering details:-

if (beanComparator == null) {
    beanComparator = BeanComparator.forClass(rowClass).orderBy(key);               
    comparatorMap.put(key, beanComparator);
}   

In my first Icefaces attempt, I pulled the first row out of the current row list for the table, and passed that to Cojen to create the class. The problem with this was that I could not do it generically this way. My second attempt, with the Primefaces version, passed the class in to an init method generically. As this tied up all the generics loose ends correctly, everything was happy and the class was recognised as having the correct parameterised type. The cost of this was the need to pass it explicitly as an argument to an init method (or a setter), but this was simple and made the parameterised type clear and explicit. This is the correct approach and one that I will use from now on.

The following code fragments illustrate the mechanism:-

Call Site


    private @Inject TableCtrl<Person, RowMetadata> personTable;

        personTable.init(Person.class, RowMetadata.class, this);

 

TableCtrlImpl.java

@Dependent
public class TableCtrlImpl<C, D extends RowMetadata> implements Serializable, TableCtrl<C, D>, Iterable<C> {

    private Class<C> rowClass;

    private Map<String, BeanComparator<C>> comparatorMap = new HashMap<String, BeanComparator<C>>();

@Override public void init(Class<C> rowClass, Class<D> rowMetadataClass, TableCtrlEvent<C, D> tableCtrlEvent) {       
    rowMeta = new RowMetaMap<C, D>();
    this.rowClass = rowClass;
    this.rowMetadataClass = rowMetadataClass;
    this.tableCtrlEvent = tableCtrlEvent;
}

    @Override public void sort() {
        if (sortColumn != null && !rows.isEmpty()) {
            String key = (sortAscending ? “” : “-“) + sortColumn;
            BeanComparator<C> beanComparator = comparatorMap.get(key);
            if (beanComparator == null) {
                beanComparator = BeanComparator.forClass(rowClass).orderBy(key);               
                comparatorMap.put(key, beanComparator);
            }
           
            Collections.sort(rows, beanComparator);
        }
    }

No Comments »

March 23rd, 2011
2:35 pm
HTML Text string plus floated right hand icon–the order matters!

Posted under HTML
Tags , , ,

A column header consisted of a text string, plus a Primefaces icon which was to be floated right in the header, in line with the text.

My initial HTML consisted of the following :-

header text<span style=”float:right;” class=”iconclass”></span>

where iconclass was one of the standard Primefaces classes for rendering icons using CSS backgrounds.

In this case, I could not stop the icon from being dropped onto a new line below the text. It was still floated right correctly, but dropped down a line.

I compared it with another similar example (not one of mine) which did work correctly, and could see no difference at all in the technique or the CSS properties of any of the elements – I would absolutely have expected both to behave the same but they did not.

In the end, simply swapping the order of the elements made it work correctly :-

<span style=”float:right;” class=”iconclass”></span> header text

I.E. putting the floated icon first and then specifying the text worked correctly and did not drop the icon down!

I am not clear on the precise reasoning for this behaviour – it was consistent across various browsers. I suspect it has to do with some of the subtleties of floating behaviour.

However, the lesson was simple – the order of elements in cases like this matters, and may result in a solution in similar cases which ‘should’ work but don’t!

No Comments »

March 22nd, 2011
8:42 pm
Facelets executes EL expressions in HTML comments by default

Posted under JSF
Tags , , , ,

This one caught me out when I was relying on <!– –> to comment out debug code when developing a facelets page. I found that methods in my Java code were being called seemingly from nowhere!

According to the specification, Facelets should honour (i.e. skip) comments by default, but in my case it did not appear to do so.

This can be enforced by adding the following context parameter to web.xml. Once done, you can safely rely on the use of commenting out when debugging. You can also use ui:remove to tell facelets to ignore sections of markup. This post here gives the details.

Note that the linked post from the above post uses the deprecated parameter name facelets.SKIP_COMMENTS. The correct parameter is as below, as you will be warned about in your server log file if you use the deprecated one!

 

<context-param>
  <param-name>javax.faces.FACELETS_SKIP_COMMENTS</param-name>
  <param-value>true</param-value>
</context-param> 

No Comments »

March 22nd, 2011
8:35 pm
JSF rendered attribute calls the getter multiple times

Posted under JSF
Tags , , ,

Initially when I saw this I thought it was a strange bug – the getter for the value expression referenced in a rendered attribute on a JSF2.0 facelets page was called 7 (yes seven) times when I would have expected one call only!

There are logical and historical reasons for this which are detailed in this post here.

The moral of the tale would seem to be that you should not make any assumptions about how often getters for value expressions are called, nor when exactly they are called. If you are doing for example database access you should never do this in a getter, but should use system events (JSF2) or Phase events (JSF1) for the database access as these give fully predictable behaviour as to when the calls happen and give you full control.

No Comments »

March 22nd, 2011
8:27 pm
Using the Browser Resize Event in jQuery

Posted under JSF
Tags , , , ,

jQuery ties into this event in a browser independant way. The following code fragment illustrates the use of this. Note tha following points:-

  • Different browsers implement resize differently. Most fire continual events during the resize, but some browsers (e.g. I believe older versions of Firefox) just fire the resize at the end of the drag. You therefore cannot predict how often and when the resize is called.
  • You need to place the code in the body section – I placed it in the head initially and it was never called.
  • When referring to a function defined in the head section as I have here, you need to prefix the call with “document.” otherwise the target function appears out of scope. The example assumes that yourFunctionName is a Javascript function defined elsewhere, e.g. in the header section of the page.

 

        <script type=”text/javascript”>
                /*
                 * This script block executes the target function on a resize.
                 * Note that jQuery has a browser independant means to hook into the event.
                 */
                jQuery(window).resize(function() {
                //alert(‘resize called’);
                document.yourFunctionName(args);
            });
        </script>

No Comments »