How to re-execute javascript function after form reRender?

I need to re-execute javascript just after form gets re-rendered. Simply, putting in javascript after XHTML content won't help since its a partial request. Also, I cannot use "onComplete" as the commandButton from which I am re-rendering form is in JSF component used at several places. I need to get the fix in locally.

Is there any way? I was wondering whether f:ajax would help in this case.

Please let me know, if anyone has clue about it.


Solution 1:

Simplest way is to just put the JS function call in the to-be-updated component itself.

<h:form>
    ...
    <h:commandButton value="submit"><f:ajax render="@form" /></h:commandButton>
    <h:outputScript>someFunction();</h:outputScript>
</h:form>

This way it's executed as the page loads and also if the form get updated by ajax.

As to the <f:ajax> itself, you could also use its onevent attribute.

<f:ajax ... onevent="handleAjax" />

with

function handleAjax(data) {
    var status = data.status;

    switch(status) {
        case "begin":
            // This is invoked right before ajax request is sent.
            break;

        case "complete":
            // This is invoked right after ajax response is returned.
            break;

        case "success":
            // This is invoked right after successful processing of ajax response and update of HTML DOM.
            someFunction();
            break;
    }
}

You could add a global hook by jsf.ajax.addOnEvent() so that you don't need to specify it in every single onevent attribute of <f:ajax> if the functional requirement applies to every ajax request.

jsf.ajax.addOnEvent(handleAjax);

An alternative is to use the OmniFaces JSF utility library which offers the <h:onloadScript> for exactly this purpose. You can place it in the head so you want.

<h:onloadScript>someFunction();</h:onloadScript>

This is automatically re-excuted on every single ajax request on the view so that you don't need to copy it over multiple individual places in the view which can be ajax-updated, or to repeat its parent ID in every <f:ajax render>.