Facelets and JSTL (Converting a Date to a String for use in a field)
Asked Answered
P

2

4

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.

Parallax answered 4/3, 2010 at 11:25 Comment(6)
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.Chigoe
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.Parallax
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 https://mcmap.net/q/832521/-how-do-you-use-jstl JSF 2.1 with Facelets on Tomcat)Chigoe
I'm using Icefaces if that makes any differenceParallax
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}"Parallax
Any idea BalusC? Would appreciate your help on this.Parallax
C
6

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.

Chigoe answered 4/3, 2010 at 17:39 Comment(1)
@Drew: The answer was targeted on JSF 1.2 + Facelets 1.x, but should work for JSF 2.0 as well. The param-name of facelets.LIBRARIES is deprecated in 2.0 (but should still work) and needs to be replaced by javax.faces.FACELETS_LIBRARIES. If you have any problems, ask a new question and include the errors.Chigoe
C
1

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')}"/>
Chandless answered 23/6, 2015 at 14:10 Comment(1)
Not really an answer to the question, but it helped me. Got stuck trying to do ajax updates over an h:outputText with an f:convertDateTime that would not refresh, resorted to backing bean method as shown.Iodous

© 2022 - 2024 — McMap. All rights reserved.