Version 1

    Hello the community

     

    In many cases with richfaces, we are lacking a 'rerender' event, or a 'onReRender' property inside of richfaces components. For exeample, the choices made by the developpers are ok, but you can't afford to use an extendedDataTable because it is very heavy. So you use a simple datatable, and you add some custom javascript on it. Problem: If you use the filter or sort functionnality, there will be a rerender on the datatable, and all the customizations added by javascript will go to trash.

     

    There are many others examples I have met, where I am willing to make an action when a component is rerendered. In many case, the oncomplete method does the job, but in every cases where it is automatic, you can't provide an oncomplete method and you are screwed.

     

    Yesterday, I decided to inspect the javascript of the framework, and I found a smart little hack, which saved me a lot of trouble. In case you would wonder, I am using Richfaces 3.3 with JSF 1.2. The hack is the folowing: I use the two following functions inside a custom javascript file:

     

    // overrides the default richfaces Sarissa function to add inside the options 
    // a parameter storing the name of the form which launched the Ajax request
    A4J.AJAX.Submit = function(containerId, formId, event, options) {
        //HACK BEGIN
        options.triggerrerender=formId;
        //HACK END
        var domEvt = A4J.AJAX.CloneEvent(event);
        var query = A4J.AJAX.PrepareQuery(containerId, formId, domEvt, options);
        if (query) {
            var queue = A4J.AJAX.EventQueue.getOrCreateQueue(options, formId);
            if (queue) {
                queue.push(query, options, domEvt);
            } else {
                A4J.AJAX.SubmitQuery(query, options, domEvt);
            }
        }
        return false;
    };
    
    //overrides the default richfaces Sarissa function to add the launch of a 
    //'reRenderEnd' event inside the form whenever an ajax call is made
    A4J.AJAX.finishRequest = function(request) {
        var options = request.options;
        if (!request._oncomplete_aborted) {
            //HACK BEGIN
            if(options.triggerrerender){
                var formID=options.triggerrerender;
                jQuery('#'+formID).trigger('reRenderEnd');
            }
            //HACK END
            var oncomp;
            try {
                oncomp = request.getElementById('org.ajax4jsf.oncomplete');
            } catch (e) {
                LOG.warn("Error reading oncomplete from request " + e.message);
            }
            if (oncomp) {
                LOG.debug("Call request oncomplete function after processing updates");
                window.setTimeout(
                        function() {
                            var event = request.domEvt;
                            var data;
                            try {
                                data = request.getJSON('_ajax:data');
                            } catch (e) {
                                LOG.warn("Error reading data from request "
                                        + e.message);
                            }
                            try {
                                var target = null;
                                if (event) {
                                    target = event.target ? event.target
                                            : event.srcElement;
                                }
                                var newscript = Sarissa.getText(oncomp, true);
                                var oncomplete = new Function("request", "event",
                                        "data", newscript);
                                oncomplete.call(target, request, event, data);
                                if (options.queueoncomplete) {
                                    options.queueoncomplete.call(target, request,
                                            event, data);
                                }
                            } catch (e) {
                                LOG.error('Error evaluate oncomplete function '
                                        + e.Message);
                            }
                            A4J.AJAX.status(request.containerId, options.status,
                                    false);
                        }, 0);
            } else if (options.oncomplete || options.queueoncomplete) {
                LOG.debug("Call local oncomplete function after processing updates");
                window.setTimeout(function() {
                    var event = request.domEvt;
                    var data;
                    try {
                        data = request.getJSON('_ajax:data');
                    } catch (e) {
                        LOG.warn("Error reading data from request " + e.message);
                    }
                    if (options.oncomplete) {
                        options.oncomplete(request, event, data);
                    }
                    if (options.queueoncomplete) {
                        options.queueoncomplete(request, event, data);
                    }
                    A4J.AJAX.status(request.containerId, options.status, false);
                }, 0);
            } else {
                LOG.debug("Processing updates finished, no oncomplete function to call");
                setTimeout(function() {
                    A4J.AJAX.status(request.containerId, options.status, false);
                }, 0);
            }
        } else {
            LOG.debug("Aborted request, won't call oncomplete at all");
            setTimeout(function() {
                A4J.AJAX.status(request.containerId, options.status, false);
            }, 0);
        }
        A4J.AJAX.popQueue(request);
    };
    

     

    These functions are nothing but just the functions of the framework, I have marked my additions with the //HACK BEGIN and //HACK END comments. I uses the jQuery that comes embeded inside richfaces, you don't need to add it. The principle is very simple: whenever an ajax submit is made, we store the formID in a parameter, and whenever an ajax call terminates, we launch an event 'reRenderEnd' inside this form. This is very convenient, because from now on, on any page we need to perform a systematic action after the rerender, we just need to add the folowing snippet inside the xhtml of the page:

     

    <script type="text/javascript">
                jQuery('#form').bind('reRenderEnd', function() {
                    console.log("submit-complete");
                });
            </script>
    

     

    Here the console.log instruction will just print "submit complete" in Firebug's console.

     

    I have to precise that I am not a very advanced user with javascript, so there must be smarter ways to do the trick. So I hope to have some comments on the tip, and in case there wouldn't, I hope that at least it will help some others people . BTW english is not my mother language, so I hope I didn't make to many mistakes