Search code examples
javajavascriptjsfjsf-2

Execute managebean method from javascript onload event


How can I make an ajax request that updates a <h:dataTable> from javascript? I am currently loading the initial data using @Postconstruct but that is significantly delaying the initial page load.

I am thinking about using onload event of <body> HTML tag to fire the request and update the datatable.


Solution

  • In theory the following should do it.

    <h:body>
        <f:ajax event="load" listener="#{bean.onload}" />
    </h:body>
    

    with

    public void onload(AjaxBehaviourEvent event) {
        // ...
    }
    

    However, this is not supported for some reason. I've ever posted an issue report about that.

    The following works, but it's in essence a hack.

    <h:head>
        <title>JSF 2.0 onload hack</title>
        <script>
            window.onload = function() {
                document.getElementById('hidden:link').onclick();
            }
        </script>
    </h:head>
    <h:body>
        <h:form id="hidden" style="display:none">
            <h:commandLink id="link">
                <f:ajax event="click" listener="#{bean.onload}" />
            </h:commandLink>
        </h:form>
    </h:body>
    

    If you happen to use PrimeFaces, then you can use its <p:remoteCommand> with autoRun set to true.

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

    Or if you're using OmniFaces, then you can use its <o:commandScript>

    <h:body>
        <h:form>
            <o:commandScript name="onload" action="#{bean.onload}" />
            <h:outputScript target="body">onload()</h:outputScript>
        </h:form>
    </h:body>
    

    The <h:outputScript target="body"> renders the <script> in the end of the <body>. The upcoming OmniFaces 2.2 will remove this need by new autorun attribute.

    <h:body>
        <h:form>
            <o:commandScript name="onload" action="#{bean.onload}" autorun="true" />
        </h:form>
    </h:body>