How to re-execute javascript function after form r

2019-01-08 12:41发布

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.

3条回答
ら.Afraid
2楼-- · 2019-01-08 13:27

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

查看更多
做个烂人
3楼-- · 2019-01-08 13:39

You could add jQuery to your application and do something like:

$(#yourComponentId).load(function(){
   //execute javascript.
});

You can take a look here http://api.jquery.com/load/

LE: that being on

$(document).ready(function(){
}

ofc.

查看更多
Summer. ? 凉城
4楼-- · 2019-01-08 13:40

BalusC first answer is the most appropriate if you want to do complex operations with JQuery/JS and are not particularly concerned about this

For more complex JS, if you decide to use a global event handler and for example you use JS to bind functions to elements, these functions are going to be re-bound (hence executed twice), so you need some way to identify what needs to be re-executed.

What I finally did, was to get the id's from the event callback and execute only the relevant JS/JQuery:

jsf.ajax.addOnEvent(ajaxCompleteProcess);


function ajaxCompleteProcess(data) {
    if (data.status && data.status === 'success') {
        var children1 = data.responseXML.children;
        for (i = 0; i < children1.length; i += 1) {
            var children2 = children1[i].children;
            for (j = 0; j < children2.length; j += 1) {
                var children3 = children2[j].children;
                for (y = 0; y < children3.length; y += 1) {
                    if (children3[y].id.indexOf('javax.faces.ViewState') != -1)
                        continue;
                    elementProcess(('#' + children3[y].id.replace(/\:/g, '\\:')));
                }
            }
        }
    }
}

Note: these ugly for loops are probably not required (you could use clildren[0]), but I haven't found the time yet to check the spec.

查看更多
登录 后发表回答