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.


Several ways.

  1. 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() or window.onload wrapper is unnecessary. Also 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.

  2. As you're already using PrimeFaces, just use its <p:remoteCommand> with autoRun="true".

    <h:form>
        <p:remoteCommand name="onload" action="#{bean.onload}" autoRun="true" update=":results" />
    </h:form>
    <h:panelGroup id="results">
        ...
    </h:panelGroup>

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).

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.

  1. <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.


阅读更多
文章标签: JSF
个人分类: JSF
上一篇Execute managebean method from javascript onload event
下一篇Maven Lifecycle and Goals
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭