Thursday, September 29, 2005

Mixing JSF and HTML

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


A subject that comes up regularly is how to mix HTML with JSF. There are several gotchas and limitations you need to be aware of.


  1. The "content inter-weaving problem". The issue here is that if you mix and match JSF components and normal "plaintext", these are processed separately, and it's possible for the text to appear out-of-sync with the component. See this article for more information. However, the good news is that this issue is fixed in JSF 1.2! (Creator however is still using JSF 1.1; JSF 1.2 is not out yet.) You need to be aware of this issue, and obviously test your application thoroughly. The problem does not show up
    at designtime in Creator because we don't process the page using the normal JSP engine.

    • You can use a <f:verbatim> tag around your markup to make it "JSF friendly". This will force the embedded text to be processed by JSF rather than the JSP handler, so the right thing will happen.

    • In Creator 2 you can also use the <ui:markup> component. It's easier to use than <f:verbatim> for some use cases. It's in the Advanced palette.




  2. Components that render their own children frequently don't handle HTML child content. (Examples of these are the Data Table, and the Panel Grid components.) These are the UIComponents that return true from getRendersChildren.
    These components specifically state that they want to handle rendering of their children themselves, and unless they
    are really careful, they won't pick up the HTML markup children nodes (whereas the standard child iteration used for
    most components does get this right.)
    Thus, for these components you need to resort to the <f:verbatim> technique again.




  3. By now you may wonder why you wouldn't ALWAYS just put <f:verbatim> around your HTML tags - and all your problems would be solved. The problem is that what verbatim does what its name suggests - it renders its child content verbatim. That means you don't get to put other JSF components inside of it! You'll see your JSF tags emitted as text. In other words, you can't freely insert <div> tags around your JSF content to do normal HTML page layouts.




  4. Your HTML needs to be well formed XHTML. This isn't necessarily a JSF requirement, although it should be noted JSF emits XHTML, not HTML. However, Creator requires this. Specifically this means that you need to remember to close your tags - I've often seen people write <br> which is invalid XHTML. It needs to be <br/>. As another example, remember that your tags need to be lowercase - don't insert <STYLE>color:blue</STYLE>.




  5. The way you actually add HTML to your web pages is to switch to the JSP view and edit away.
    However, note that you don't get to write plain HTML there, because you're actually editing an XML-formatted JSP
    file. Tags work the same way as in HTML - you can for example add <hr> to add a horizontal ruler.
    But entities are different. They need to be "XML escaped". If you want to write the HTML entity for the Spanish n for example,
    ñ, you cannot simply write &ntilde;. You have to replace the & with &amp;. Thus, if you want the page to render in the browser as Piña Colada, in HTML you would have had to type, Pi&ntilde;na Colada, but in the JSP file you need to escape the & such that you end up with Pi&amp;ntilde;a Colada.




With all those potential problems, you may wonder why you should bother with HTML at all?
It would be ideal if you didn't have to.
However, if you restrict yourself to standard JSF components there is simply too much markup you cannot get to. For example, you cannot add a horizontal ruler since there's no component for that. In Creator 2 we have a new component library which adds a wide array of new components.






However, there are two remaining areas where you might find yourself resorting to HTML.


  • Flexible layouts. If you want to achieve a really advanced layout that offers good resize behavior etc. you may need to resort to old-school HTML tables with rowspans and colspans. However, I urge you to consider using CSS for your layouts instead. It may be a bit harder at first, but it will pay off. True, CSS is not supported well in older browsers, but many of these older browsers aren't supported for similar reasons in the existing markup rendered for many components already.



  • Pre-existing content. You may have existing HTML that you want to reuse directly - perhaps it was crafted by a web designer and you want the same look in your JSF app with no rewrite effort. You can import these into Creator using File | Add Existing Item. The screenshot on the right for example shows the java.net page imported into Creator. The import mechanism will not catch all the gotchas above however so you need to Test, Test, Test.




As should be evident from the gotchas list however, you need to consider this carefully.


12 comments:

  1. Hi Tor,
    Just tested my app. on IE
    http://www.hca.ath.cx:8080/ods
    and it does not display the background images of gridpanel. i set the image in a stylesheet according to the category selected. I can see the image file being downloaded on the status bar but it is not being displayed.
    works fine on mozilla and firefox.
    In the uncategorized page of my app the image is
    attached directly as a background image to the page
    (there is no gridpanel here and it renders fine.
    any another thing my buttons are coming out too big
    in IE. Any tips as too how I can get them to look
    roughly the same size on all browsers. I am targeting
    1024x768 resolution.
    Your help would be very much appreciated.
    cheers,
    paul.

    ReplyDelete
  2. Speaking of mixing HTML and JSF...
    I have need of a way to create a scrollable panelGrid. I've tried using div sections but with limited success (the gridPanel is scrollable but the button below the panel gets sucked into it and gets scrolled along with the panel).
    I then tried to use IFrame, but that didn't work as well as the div section.
    So, is there a way to mix html with the JSF gridPanel in order to make it, and it alone, scrollable?

    ReplyDelete
  3. Hi Tor,
    Yes, I tried adding the style="overflow: scroll" on the gridPanel itself but that didn't do anything (no scroll bars ever show up). Using the div sections was the closest I could get.
    It seems like there is a problem with mixing these. I guess that I could replace the gridPanel with a table, but from this blog entry, I just thought that what I have should work.

    ReplyDelete
  4. I have been trying to get a scrollable grid panel working as well, and "overflow: scroll" did not work on the grid panel, however it DID work on a tree component. Only guess there is that a grid panel will actually resize the component where as a tree will not resize the component, but will just overflow its boundries? Not sure, just a guess.
    I also saw an example where someone used "<div style="overflow: scroll"> and it worked, but that was in a regular JSP page. When I tried that in JSC, it did not work, and when I viewed source on the page, my div statment ended up before the form tag! That was very odd....

    ReplyDelete
  5. OOPS! in my last post I used a div tag with style="overflow: scroll" in it, but rather then printing the text, it used the tag and added the scroll bars! Oh-well, I guess now you can see for real how the style="overflow: scroll" works in a div tag! To bad I have not gotten that to work from creater yet.. Sorry for the confusing posts!

    ReplyDelete
  6. I ended up using a single select listbox to get the scrolling to work.
    Something must not be quite right with the way things are working with mixing div sections just yet (note that it still seems to be broken in the Early Access version as well).

    ReplyDelete
  7. Hi I'm having a problem in jsf with scrollbars. I can get it to work fine in IE but no scrollbars appear in mozilla. I'm scrolling over a datatable like this:
    "<h:panelGroup styleClass="scroll"> <h:dataTable >
    </h:dataTable>
    </h:panelGroup>"
    ".scroll {
    overflow: auto;
    height: 100%;
    width: 100%;
    }"
    Iv left out the stuff in the datatable. but this is just to show how i'v scrolled over it in IE.

    ReplyDelete
  8. Download 7 penis enlargement videos. User ratings & reviews of 55 penis enlargement pills.

    ReplyDelete
  9. Download 7 penis enlargement videos. User ratings & reviews of 55 penis enlargement pills.

    ReplyDelete
  10. [url=http://www.oksextoys.com/]penis enlargement[/url]
    do penis enlargement work for you ?

    ReplyDelete
  11. Download 7 penis enlargement videos. User ratings & reviews of 55 penis enlargement pills.

    ReplyDelete