How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?
Several ways.
-
Use
<h:commandScript>
. Note that this is only available since JSF 2.3.<h:form> <h:commandScript name="commandName" action="#{bean.action}" render=":results" /> </h:form> <h:panelGroup id="results"> ... </h:panelGroup>
You can invoke it in JS as below:
commandName();
The parameters can be passed as below:
commandName({ name1: "value1", name2: "value2" });
And obtained as below:
String name1 = externalContext.getRequestParameterMap().get("name1"); // value1 String name2 = externalContext.getRequestParameterMap().get("name2"); // value2
To invoke it during
load
event, setautorun="true"
.<h:commandScript ... autorun="true" />
-
If you're using PrimeFaces, use its
<p:remoteCommand>
.<h:form> <p:remoteCommand name="commandName" action="#{bean.action}" update=":results" /> </h:form> <h:panelGroup id="results"> ... </h:panelGroup>
You can invoke it in JS as below:
commandName();
This however doesn't use JSF native
jsf.ajax.request()
, instead it uses PrimeFaces native jQuery (you know, PrimeFaces is a JSF component library on top of jQuery/UI).The parameters can be passed as below:
commandName([{ name: "name1", value: "value1" }, { name: "name2", value: "value2" }]);
And obtained as below:
String name1 = externalContext.getRequestParameterMap().get("name1"); // value1 String name2 = externalContext.getRequestParameterMap().get("name2"); // value2
To invoke it during
load
event, setautoRun="true"
.<p:remoteCommand ... autoRun="true" />
-
If you're using OmniFaces, use its
<o:commandScript>
. The usage is exactly the same as with<h:commandScript>
but then available for older JSF 2.x versions.Simply replace
h:
byo:
in the first example. Historical note: the<h:commandScript>
is entirely based off<o:commandScript>
.
-
Use the "hidden form" trick (actually, "hack" is given the ugliness a better wording).
<h:form id="form" style="display:none;"> <h:commandButton id="button" action="#{bean.action}"> <f:ajax render=":results" /> </h:commandButton> </h:form> <h:panelGroup id="results"> ... </h:panelGroup>
You can invoke it in JS as below:
document.getElementById("form:button").onclick();
Note the importance of triggering
onclick()
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. If you were using a<h:commandLink>
, you can safely useclick()
instead.You can pass parameters via
<h:inputHidden>
in same form which you fill by JS beforehand. This is demonstrated in How to pass JavaScript variables as parameters to JSF action method?To invoke it during
load
event, consider putting it in<h:outputScript target="body">
. Thetarget="body"
automatically puts the<script>
in end of<body>
, thus a$(document).ready()
wrapper is unnecessary.<h:outputScript target="body"> document.getElementById("form:button").onclick(); </h:outputScript>
Or, create a custom
UIComponent
which extendsUICommand
and generates the necessary JSF nativejsf.ajax.request()
call. As an example you could look at source code of OmniFaces<o:commandScript>
.