Matthias Wessendorf’s Weblog

Entries from February 2008

Custom JSF components with Facelets

February 29, 2008 · 7 Comments

There are several reasons to use Facelets, like:

  • Problems in JSF 1.1 “Content Interweaving”
  • lightweight Templating Framwork (XHTML-based templates)
  • very friendly to designers (similar to Tapestry)
  • performance
  • JSF 1.2 w/o JavaEE 5 Container

Another is the very easy way of creating custom JSF components. In plain JSF you need these artifacts:

  • a lot of Java (Component, Renderer, JSP-Tag Class)
  • some XML (faces-config, TLD)

With Facelets, it is this:

  • XHTML file
  • Facelets Taglib XML file (very simple syntax)

With Facelets it is very easy to create sexy components, using 3rd party JavaScript libraries, such as Dojo Toolkit. The XHTML file contains all the markup want. The “taglib” is the glue code between the XHTML file and the user’s page, where a page author is using the (new) component.

The Dojo Toolkit contains lot of cool “components”, such as an accordion. It is not hard to make your layout (<div> elements) become a “AccordionContainer”, that contains several “AccordionPane” components, as the previews link shows. But every time reusing this, you repeat your self. So… you finally want a (jsf) component. Easy with Facelets.

All you need is two XHTML files (one for the container and one for the pane) and a little bit of XML to wire the two tags to the new components.

The container xhtml:

<div
  xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets">

  <link rel="stylesheet" type="text/css"
     href="dtk/dijit/themes/tundra/tundra.css" />
  <script type="text/javascript"
    src="http://o.aolcdn.com/dojo/1.0.0/dojo/dojo.xd.js"
    djConfig="parseOnLoad: true"></script>
  <script type="text/javascript">
    dojo.require("dojo.parser");
    dojo.require("dijit.layout.AccordionContainer");
   </script>

    <div dojoType="dijit.layout.AccordionContainer"
         duration="#{duration}" style="#{style}">

     <ui:insert/>

    </div>
</div>

Simply import the required CSS and JavaScript files and make the <div> element a “AccordionContainer” by using the dojoType attribute. The value for the attributes duration and style is provided with a ValueExpression. The user of the accordionContainer tag has to specify the correct value. Inside the <div> element there is a <ui:insert />. This allows us to nest other content (such as the later described pane component) inside the accordion.The pane xhtml:

<div xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  dojoType="dijit.layout.AccordionPane"
  title="#{title}">

  <ui:insert/>

</div>

This one is very simple, just a <div> that is representing the AccordionPane and a <ui:insert/> to nest content. Please note that this “component” doesn’t need to import CSS or JavaScript files. Why? Because it is only used inside the accordion which is already loading the needed files.The XML for the “taglib”:

<facelet-taglib>
  <namespace>
    http://wessendorf.net/kickstart
  </namespace>
  <tag>
    <tag-name>accordionContainer</tag-name>
    <source>facelets/components/accordionContainer.xhtml</source>
  </tag>
  <tag>
    <tag-name>accordionPane</tag-name>
    <source>facelets/components/accordionPane.xhtml</source>
  </tag>
</facelet-taglib>

The taglib file is pretty trivial. It just contains a bunch of tags and points to the source code of the component, the location of the XHTML files.The finally result (the page, that uses these new components) looks like:

<mw:accordionContainer duration="250"
style="margin-right: 30px; width: 400px; height: 300px; overflow: hidden">
  <mw:accordionPane title="html content">
    <p>Hello</p>
  </mw:accordionPane>
  <mw:accordionPane title="some more html content">
    <ul>
      <li>hey!</li>
    </ul>
  </mw:accordionPane>
  <mw:accordionPane title="JSF component content">
    <tr:inputDate />
  </mw:accordionPane>
</mw:accordionContainer>

It is possible to mix content such as regular HTML or some other JSF components, like the <tr:inputDate> component from Trinidad.Very easy and straightforward to add to your project!I updated FacesGoodies to ship this example (only via SVN).

Categories: dojo · facelets · javascript · jsf · jsp · myfaces · web²

Extending Trinidad’s default renderers

February 20, 2008 · 3 Comments

Once in a while there is a question on the MyFaces user/dev list about how to extend the default rendering of the components, like decorating <tr:inputText /> (for instance).

It’s not hard, but it requires some steps, like creating renderer class(es) and registering these new renderers with the Trinidad renderkit. This demonstrates a very simple example on extending the <tr:inputText />. This tag has a attribute for short descriptions (shortDesc=”blah”), now imagine you need to decorate that inside the renderer, so that the page developer can’t change the extra text (for what ever reason…).

For that you need two Java classes (b/c of extending a <tr:inputXyz/> or <tr:selectXzy />). One is for extending the InputTextRenderer class, which is registered with the Trinidad internal RenderKit. The other one is kind of an internal renderer, that is used to render the component’s content.

The extension of the InputTextRenderer looks like this:

package net.wessendorf.trinidad;

import org.apache.myfaces.trinidad.bean.FacesBean;
import org.apache.myfaces.trinidad.component.core.input.CoreInputText;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.FormInputRenderer;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.InputTextRenderer;

public class CustomInputTextRenderer extends InputTextRenderer
{
  public CustomInputTextRenderer()
  {
    super(CoreInputText.TYPE);
  } 

  protected CustomInputTextRenderer(FacesBean.Type type)
  {
    super(type);
  }

  @Override
  protected FormInputRenderer getFormInputRenderer()
  {
    return new CustomSimpleInputTextRenderer();
  }
}

In Trinidad the *layout* of the <tr:inputXyz/> is done by these renderers (those, that extend the InputLabelAndMessageRenderer class). The custom code isn’t really hard. It is only interesting to see how to create the internal renderer (CustomSimpleInputTextRenderer), which actually renders the content (which we want to decorate):

package net.wessendorf.trinidad;

import javax.faces.context.FacesContext;

import org.apache.myfaces.trinidad.bean.FacesBean;
import org.apache.myfaces.trinidad.component.core.input.CoreInputText;
import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.SimpleInputTextRenderer;

public class CustomSimpleInputTextRenderer extends SimpleInputTextRenderer
{
  public CustomSimpleInputTextRenderer()
  {
    this(CoreInputText.TYPE);
  }

  public CustomSimpleInputTextRenderer(FacesBean.Type type)
  {
    super(type);
  }
  @Override
  protected String getShortDesc(FacesBean bean)
  {
    return super.getShortDesc (bean) + " what ever you want to decorate";
  }
}

As you see this adds some (bogus) text to the short description of the component. That’s it from the java side. If you really want to change the entire rendering of the <tr:inputText /> your custom “content” renderer (CustomSimpleInputTextRenderer) could also override the protected encodeAllAsElement() method.The last step is to register the new renderer in your project’s faces-config.xml file:

...
<render-kit>
  <render-kit-id>
    org.apache.myfaces.trinidadinternal.core
  </render-kit-id>
  <renderer>
    <component-family>
      org.apache.myfaces.trinidad.Input
    </component-family>
    <renderer-type>
      org.apache.myfaces.trinidad.Text
    </renderer-type>
    <renderer-class>
      net.wessendorf.trinidad.CustomInputTextRenderer
    </renderer-class>
  </renderer>
</render-kit>
...

As you see, you register the CustomInputTextRenderer and not the renderer that renders the content (CustomSimpleInputTextRenderer).Now using the <tr:inputText> in your XHTML page will decorate the short description:

<tr:inputText label="Blah" shortDesc="foo bar" ... />

It is important to note, that these classes extend internal features of Trinidad. None of these classes is part of the Trinidad API. This means that anyone subclassing the renderers has to know their code can very well break any time they move to a newer version. Another example of extending a Trinidad renderer (for <tr:message/>), I posted here.

Categories: apache · java · jsf · myfaces · trinidad

Internet Explorer 7 and blur (with input type=file)

February 19, 2008 · 1 Comment

Today I noticed an interesting issue with IE 7 and the blur event, when using the <input type=”file”> HTML widget. A friend called me to tell me that their web app is validating the form fields, when the user is pressing the native “Browse…” button. But only in IE 7 (well, I don’t have IE6 installed). Interesting…

A simple test case for that:

<form>
  <input id="file" type="file"
    onblur="alert('blur');"
    onchange="alert('file');" />
  <br/><br/>
  <button>Blah</button>
</form>

And indeed! In IE 7, the alert(‘blur’) is visible, when you hit the “Browse…” button. FF works fine. Please note that the widget was not focused before. Very annoying…But, as almost always there is a way around that ;-) This little jQuery-based hack helps to get rid of it (in the particular use case…):

<script>
$(document).ready(function(){
 $("#file").removeAttr("onblur");
});
</script>

Not a clean generic solution, but I think it does its job…

I personally haven’t noticed this bug before, but I am sure it is “known” since ages ;-)

Categories: jQuery · javascript

Using Dojo and Apache Trinidad

February 16, 2008 · 9 Comments

In Trinidad there is an ExtendedRenderKitService interface, which allows you to add JavaScript to be rendered during the following request, like:

ExtendedRenderKitService service =
  Service.getRenderKitService(facesContext,
    ExtendedRenderKitService.class);
service.addScript(facesContext, "alert('hello Trinidad');");

Once the rendering is complete, you will notice a simple alert() in your browser window.Having this feature in mind, you can “call” your custom JavaScript from the server. Well, the reality is that the implementation of the interfaces (the Trinidad renderkit) adds your JavaScript call to the (ajax) response. When processing a PPR request, the XHR response will look like:

<?xml version="1.0" ?>
  <?Tr-XHR-Response-Type ?>
  <content  action="/app/faces/ajax.xhtml">
  ...
  <script><![CDATA[alert('hello Trinidad');]]></script>
  </content>

As you see the JS is added to the very end of the response and the browser simple evaluates the added JavaScript. This ExtendedRenderKitService feature offers you the possibility to easily integrate 3rd party JavaScript libraries, such as Dojo Toolkit.Imagine that your application needs to give feedback, when you created/deleted something (like a user). Using the JavaScript alert() function is fine, but well, that really doesn’t look nice! Dojo has a great Dialog component to display a notification like “User ABC has been created!”.

On the server you need to do something like:

...
extendedRenderKitService.addScript(context,
  "showDialog('" +
    newUser.getSecondname() + ", "+
    newUser.getFirstname() +
  "');");
...

The required showDialog(…) JavaScript function could look like:

function showDialog(user)
{
  var dialog = new dijit.Dialog(
{id:"dialog1", title: "New User created!"});
  var dialogContent =
"Successfully created the user: \"" + user + "\"";
  dialog.setContent(dialogContent);
  dialog.show();
}

Once the response is rendered completely, you’ll notice something like:

dojodialog.png

This way enables an easy integration of nice 3rd party JavaScript. Today I updated FacesGoodies (in SVN only) to reflect this integration.

Have fun!

Categories: ajax · apache · dojo · javascript · jsf · myfaces · trinidad · web²

JSFDays 2008 in Vienna

February 14, 2008 · Leave a Comment

JSFDays is the international conference on JavaServer Faces technology. It helps experts and professional users of JavaServer Faces and related technologies to share their knowledge on JSF. The event will take place in Vienna, Austria, from March 12th to 14th 2008.

Attendees will pay a very small conference fee – 100€. Speakers are Ed Burns (Sun),  Kito Mann (JSFCentral.com), Jürgen Höller (Spring Source), and many many more!

There will be a supporting programm alongside the conference – so you will (additionally to learning about JSF and improving your JSF knowledge) have a good chance of getting to know Vienna and its surroundings.

Click here to get more infos on this event: http://conference.irian.at.

Categories: ajax · apache · java · javascript · jsf · myfaces · orchestra · trinidad · web²

Dialogs with (popular) JavaScript libraries

February 12, 2008 · Leave a Comment

The Dojo Toolkit and jQuery UI both offer a dialog “component” (with drag-and-drop). Dojo has two ways of creating such a dialog. There is a declarative and a programmatic way to do so. The declarative approach looks like:

<div dojotype="dijit.Dialog" title="First Dialog">

 Hello New York!
</div>

The div element here is containing a special attribute (dojoType) to tell Dojo, that this is a component of type “dijit.Dialog“. This is straightforward, but… it is reasonable that some don’t like the extra expando (dojoType). The programmatic way is IMO more natural to developers:

var dialog = new dijit.Dialog(
  {id:"dialog1", title: "First Dialog"});

var dialogContent = "Hello New York!";
dialog.setContent(dialogContent);
dialog.show();

Now you are using the JavaScript-API of Dojo to create (and launch) the dialog, when ever you want.In jQuery UI, this is done in a really cool way:

<div id="dialog1" class="flora"
  title="First Dialog">

  Hello New York!
</div>

This little snippet of HTML is not visible (b/c of the used CSS) and when you want to launch the dialog, you just have a very easy JS callback:

launchMyDialog = function()
{
  $("#dialog1").dialog();
}

This is cool. Even more cool is the ready-callback that jQuery “core” is offering you:

$(document).ready(function(){
  $("#dialog1").dialog();
});

When the DOM is ready, the dialog is launched. Pretty neat!

Categories: ajax · javascript · web²

jQuery – A fluent JavaScript API

February 11, 2008 · 1 Comment

Nowadays you read more and more about DSL and Fluent APIs / Fluent Interface, which I was to reminded when I bumped into jQuery today (by doing some JS related work).

In jQuery you can do things like:

  $('<p></p>')
  .html("Blah, blah, blah")
  .addClass("foobar")
  .appendTo("body");

This code simply adds a new paragraph to the current page, nothing special with that, but it is done with a very sexy and well readable syntax. It is truly worth to evaluate jQuery in detail!

Categories: javascript · web²

Release of Apache MyFaces Trinidad 1.2.6

February 11, 2008 · Leave a Comment

The Apache MyFaces Trinidad team is pleased to announce the release of
Apache MyFaces Trinidad Core 1.2.6.

Apache MyFaces Trinidad is a JavaServer(tm) Faces 1.1 component library.

Trinidad Core 1.2.6 is available in both binary and source distributions:

* http://myfaces.apache.org/trinidad/download.html

Apache MyFaces Trinidad is available in the central Maven repository under
Group ID “org.apache.myfaces.trinidad”.

Release Notes:
https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12310661&styleName=Html&version=12312923

In case you use Trinidad, would be cool if you add your company to this page.

Categories: apache · java · jsf · myfaces · trinidad · web²

Release of Apache MyFaces Trinidad 1.0.6

February 11, 2008 · Leave a Comment

The Apache MyFaces Trinidad team is pleased to announce the release of
Apache MyFaces Trinidad Core 1.0.6.

Apache MyFaces Trinidad is a JavaServer(tm) Faces 1.1 component library.

Trinidad Core 1.0.6 is available in both binary and source distributions:

* http://myfaces.apache.org/trinidad/download.html

Apache MyFaces Trinidad is available in the central Maven repository under
Group ID “org.apache.myfaces.trinidad”.

Release Notes:
https://issues.apache.org/jira/secure/ReleaseNote.jspa?projectId=12310661&styleName=Html&version=12312922In case you use Trinidad, would be cool if you add your company to this page.

Categories: ajax · apache · java · jsf · jsp · myfaces · trinidad · web²

Java User Group Cologne

February 6, 2008 · Leave a Comment

The JUGCologne invited me to talk about … JSF. On Friday, July the 25th (2008 ;-) ) I will be in Cologne. The talk is called “Advanced JavaServer Faces – Using cool JSF Technologies”. The talk is about MyFaces, Facelets, Apache Trinidad and Ajax (of course). I will also over the integration of JSF with the business tier, using the Spring 2 Framework, the JPA and Orchestra.

I used to live in Cologne a while ago, so it is very cool to “come back”.

Hope to see you there!

Categories: Cologne · ajax · apache · jsf · myfaces · orchestra · trinidad · web²