Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
438 views
in Technique[技术] by (71.8m points)

ajax - How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?

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.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Several ways.

  1. 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, set autorun="true".

    <h:commandScript ... autorun="true" />
    

  2. 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, set autoRun="true".

    <p:remoteCommand ... autoRun="true" />
    

  3. 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: by o: in the first example. Historical note: the <h:commandScript> is entirely based off <o:commandScript>.


  4. 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 of click() in case of <h:commandButton>. The onclick() immediately invokes the onclick function while the click() only triggers the "click" event on the element, which is not supported in IE. If you were using a <h:commandLink>, you can safely use click() 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">. The target="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>
    

  5. Or, create a custom UIComponent which extends UICommand and generates the necessary JSF native jsf.ajax.request() call. As an example you could look at source code of OmniFaces <o:commandScript>.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...