H: body is not overwritten when using FullAjaxExceptionHandler
I am using OmniFaces FullAjaxExceptionHandler to display error pages. The error pages are displaying correctly, but I am having problems styling these pages.
My app is using a template that has CSS classes defined on the body element. These classes differ for normal and error pages:
Regular page:
<h:body styleClass="main-body layout-compact">
Error page:
<h:body styleClass="exception-body error-page">
When the FullAjaxExceptionHandler handles the exception, an error page is sent (based on the mechanism <error-page>
in web.xml
). Apparently this does not override the tag <h:body>
, because when inspecting the HTML output, I see that the tag <body>
still contains the CSS classes from the normal page (instead of the error page classes).
It looks like the content of the original <h:body>
is being replaced with the content of the error page <h:body>
instead of just replacing the full one <h:body>
. I don't know if this is the default JSF / FullAjaxExceptionHandler behavior.
Is there a way to get it <h:body>
with the correct CSS classes? Moving CSS classes from is <h:body>
not an option.
source to share
This is, unfortunately, "by design". JSF does not replace the entire document when doing ajax navigation, but it only replaces individual elements <head>
and <body>
leaves the parents intact. This is done for historical reasons; older versions of Internet Explorer, namely, do not support their replacement at all.
What I did myself was just put the style on the element <main>
. <header>
and <footer>
are generally identical in the final HTML release. Basically:
<html>
<head>
<title>...</title>
</head>
<body>
<header>...</header>
<main class="#{page.type}">...</main>
<footer>...</footer>
</body>
</html>
If you really need to change <body class>
, your best bet is through the JavaScript built into the error page template.
<h:outputScript rendered="#{faces.ajaxRequest}">
document.body.className = "exception-body error-page";
</h:outputScript>
Note: #{faces}
only available with OmniFaces 2.5, if you are using an older version use instead #{facesContext.partialViewContext.ajaxRequest}
).
source to share