I need to execute a JSF managed bean action method using ajax during HTML DOM load
event, similar to jQuery's $(document).ready(function() { $.ajax(...) })
. I can only use the JavaScript generated by JSF in this project. Is there a way to do it in native JSF? Which event can I use or which JSF ajax function can I use?
I'm using JSF 2.0, Facelets and PrimeFaces.
Several ways.
-
Use the "hidden form" trick (actually, "hack" is given the ugliness a better wording).
<h:outputScript target="body"> document.getElementById("form:button").onclick(); </h:outputScript> <h:form id="form" style="display:none;"> <h:commandButton id="button" action="#{bean.onload}"> <f:ajax render=":results" /> </h:commandButton> </h:form> <h:panelGroup id="results"> ... </h:panelGroup>
Note that
<h:outputScript target="body">
automatically puts the<script>
in end of<body>
, thus a$(document).ready()
orwindow.onload
wrapper is unnecessary. Also note the importance of triggeringonclick()
instead ofclick()
in case of<h:commandButton>
. Theonclick()
immediately invokes theonclick
function while theclick()
only triggers the "click" event on the element, which is not supported in IE. -
As you're already using PrimeFaces, just use its
<p:remoteCommand>
withautoRun="true"
.<h:form> <p:remoteCommand name="onload" action="#{bean.onload}" autoRun="true" update=":results" /> </h:form> <h:panelGroup id="results"> ... </h:panelGroup>
jsf.ajax.request()
, instead it uses PrimeFaces native jQuery (you know, PrimeFaces is a JSF component library on top of jQuery/UI).
3. Create a custom UIComponent
which extends UICommand
and generates the necessary JSF native jsf.ajax.request()
call. You're then in essence reinventing the <p:remoteCommand>
to use native JSF ajax instead of jQuery. The JSF utility library OmniFaces has a <o:commandScript>
component which does exactly that. See also the showcase and the source code.
-
<h:outputScript target="body"> onload(); </h:outputScript> <h:form> <o:commandScript name="onload" action="#{bean.onload}" render=":results" /> </h:form> <h:panelGroup id="results"> ... </h:panelGroup>
<prime:remoteCommand>
is intended to call back end bean methods from Javascript. Combine it with the update
property to update the screen. Another property, autoRun
, allows you to use<prime:remoteCommand>
without Javascript code. autoRun="true"
makes sure the back end method is called automatically after the form is displayed. Insert the remoteCommand immediately before the closing </form>
tag:
<
prime:remoteCommand
autoRun
=
"true"
action
=
"#{myBean.init}"
update
=
"content"
name
=
"longRunningInit"
/>
</
form
>
Be careful to define the update
property correctly. The updated region of the screen shouldn’t include the remoteCommand
. You don’t want to get an infinite loop.
You can call an arbitrary method of the bean. If you call <prime:remoteCommand>
from Javascript, you can even pass parameters to the bean’s method. Of course, usingautoRun="true"
doesn’t allow us to pass parameters, so a simple parameterless method will do.