Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

h:body not rerendered when using FullAjaxExceptionHandler

Tags:

jsf

omnifaces

I'm using the OmniFaces FullAjaxExceptionHandler to display error pages. The error pages are shown correctly, but I'm having issues with the styling of those pages.

My application is using a template which has CSS classes defined on the body element. These classes are different for normal and error pages:

Normal page:

<h:body styleClass="main-body layout-compact">

Error page:

<h:body styleClass="exception-body error-page">

When the FullAjaxExceptionHandler processes an exception, a forward to the error page is performed (based on the <error-page> mechanism in web.xml). Apparently this does not rerender the <h:body> tag, because when checking the HTML output, I can see that the <body> tag still contains the CSS classes from the normal page (instead of the classes of the error page).

It seems that the content of the original <h:body> is replaced with the content of the error page <h:body> instead of just replacing the full <h:body>. I don't know if this is default JSF / FullAjaxExceptionHandler behaviour.

Is there any way to have the <h:body> rendered with the correct CSS classes? Moving the CSS classes away from <h:body> is not an option.

like image 935
baraskae Avatar asked Apr 05 '17 07:04

baraskae


1 Answers

This is unfortunately "by design". JSF doesn't replace the entire document when performing ajax navigation, but it only replaces the children of individual <head> and <body> elements, leaving the parents untouched. This is done so for historical reasons; older Internet Explorer versions namely doesn't support replacing them altogether.

What I have done myself is to simply put the style into the <main> element instead. The <header> and <footer> are usually identical anyway in the final HTML output. Basically:

<html>
    <head>
        <title>...</title>
    </head>
    <body>
        <header>...</header>
        <main class="#{page.type}">...</main>
        <footer>...</footer>
    </body>
</html>

If you really need to have the <body class> modified, then your best bet is to do so via JavaScript embedded in the error page template.

<h:outputScript rendered="#{faces.ajaxRequest}">
    document.body.className = "exception-body error-page";
</h:outputScript>

Note: #{faces} is only available since OmniFaces 2.5, if you're using an older version, use instead #{facesContext.partialViewContext.ajaxRequest}).

like image 92
BalusC Avatar answered Oct 23 '22 04:10

BalusC