4
votes

I need to convert a Date to a String within a page (I dont want to add loads of toStrings to my domain model so adding to the bean is not an option).

<ice:graphicImage value="bean.image" title="#{bean.date}"/>

The above code works but formats the Date in the default format...I would like to change the format.

I have tried using JSTL fmt but this doesnt seem to be compatible with Facelets JSF Convert dates for title attribute . Is there a workaround for this (doesnt have to use JSTL)?

Thanks.

2
So the other option wasn't an option? (doing formatting right in getter). If so, why not? Do you for example not want to hardcode the pattern in the model but rather in the view? Please elaborate, there may be ways to go around the new problem when just doing the formatting right in the getter.BalusC
The date formatting changes all over the place on each webpage (e.g. header different from title etc) and our domain model is large and has dates all over the place...I dont really want to have to start adding loads of getDateString methods as this doesnt belong in the domain and should be seperated in the MVC model. It would be ideal to be able to do this on the JSF page.DD.
OK. To summarize, the problem is more that JSTL fmt taglib doesn't seem to work in Facelets. Which JSF impl/version? Which server impl/version? (edit: nevermind, you already mentioned that in the other topic stackoverflow.com/questions/2373592/how-do-you-use-jstl JSF 2.1 with Facelets on Tomcat)BalusC
I'm using Icefaces if that makes any differenceDD.
Another example would be what if I want to have a hyperlink with the text a combination of String + double and I want to format the double...e.g. value="#{currency} {price}"DD.

2 Answers

6
votes

Indeed, you cannot use the "good old" JSTL in Facelets anymore the way as you would do in JSP. Facelets only supports a limited subset of JSTL (and has it already builtin, the JSTL JAR file is in fact superfluous).

You're forced to write a custom tag or better, a custom EL function, for this purpose.

Let's assume that we want to be able to do this:

<ice:graphicImage ... title="#{fmt:formatDate(bean.date, 'yyyy-MM-dd')}" />

Roughly said thus the same what the JSTL <fmt:formatDate> tag can do, but then in flavor of an EL function so that you can use it everywhere without the need for an "intermediating" tag. We want it to take 2 arguments, a Date and a SimpleDateFormat pattern. We want it to return the formatted date based on the given pattern.

First create a final class with a public static method which does exactly that:

package com.example.el;

import java.text.SimpleDateFormat;
import java.util.Date;

public final class Formatter {

    private Formatter() {
        // Hide constructor.
    }

    public static String formatDate(Date date, String pattern) {
        return new SimpleDateFormat(pattern).format(date);
    }

}

Then define it as a facelet-taglib in /META-INF/formatter.taglib.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE facelet-taglib PUBLIC
    "-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
    "http://java.sun.com/dtd/facelet-taglib_1_0.dtd">

<facelet-taglib>
    <namespace>http://example.com/el/formatter</namespace>
    <function>
        <function-name>formatDate</function-name>
        <function-class>com.example.el.Formatter</function-class>
        <function-signature>String formatDate(java.util.Date, java.lang.String)</function-signature>
    </function>    
</facelet-taglib>

Then familarize Facelets with the new taglib in the existing /WEB-INF/web.xml:

<context-param>
    <param-name>facelets.LIBRARIES</param-name>
    <param-value>/META-INF/formatter.taglib.xml</param-value>
</context-param>

(note: if you already have the facelets.LIBRARIES definied, then you can just add the new path commaseparated)

Then define it in the Facelets XHTML file as new XML namespace:

<html 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:fmt="http://example.com/el/formatter"
    ...
>

Finally you can use it as intended:

<ice:graphicImage ... title="#{fmt:formatDate(bean.date, 'yyyy-MM-dd')}" />

Hope this helps.

1
votes

You can use a converter method in your bean, as:

public class Bean{
    ...
        public String formatDate(Date fecha, String pattern) {
            return (new SimpleDateFormat(pattern)).format(fecha);
        }
    ...
}

And, in your page:

<ice:graphicImage value="bean.image" title="#{bean.formatDate(bean.date,'yyyy-MM-dd')}"/>