Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I need to delay the display of a Primefaces AJAX Status dialog by X milliseconds

I need to delay the display of a Primefaces AJAX Status dialog by X milliseconds but OmniFaces ExceptionHandler reacts badly to javascript timeout solution.

Here's what I got so far:

<p:ajaxStatus onstart="showStatusDialog();" onsuccess="hideStatusDialog();" onerror="hideStatusDialog();"/>

<script type="text/JavaScript">
    var statusDlgTimer = null;

    function showStatusDialog()
    {
        if (statusDlgTimer === null) 
        {
            statusDlgTimer = setTimeout("statusDialog.show()", 700);
        }
    }

    function hideStatusDialog()
    {
        if (statusDlgTimer !== null) 
        {
            clearTimeout(statusDlgTimer);
            statusDialog.hide();
            statusDlgTimer = null;
        }
    }
</script>

This works perfectly as long as no error occurs in the AJAX call. I'm using OmniFaces FullAjaxExceptionHandler to handle AJAX/non-AJAX exceptions.

My hypothesis is that since the JavaScript is reloaded when the error page is rendered the reference to the statusDlgTimer is never detected to be !== null, but I've not yet been able to find a good workaround.

like image 787
matsa Avatar asked Sep 20 '13 12:09

matsa


2 Answers

The FullAjaxExceptionHandler replaces basically the entire HTML document tree with the content of the error page and hereby the <p:ajaxStatus> "get lost" and its oncomplete is never invoked. You basically need to invoke hideStatusDialog() from inside the HTML source of the error page as well. Perhaps something like this:

<h:outputScript target="body">hideStatusDialog();</h:outputScript>

Better yet, use $(document).ajaxStart(), ajaxComplete() and ajaxError() in a global JS file instead of the whole <p:ajaxStatus>.

like image 127
BalusC Avatar answered Sep 18 '22 05:09

BalusC


With the help of a collegue I actually found two other work arounds, the latter of which resembles BalusC's solution.

  1. By setting a variable 'var displaydialog = false' onload and setting it to true before setting the timeout the dialog. I checked that same variable in an intermediary function before actually displaying the variable. A bit difficult and hackish but it worked.
  2. My JavaScript was included in my Facelets template, which the error page also used. By creating another template I was able to use ui:insert to avoid inserting the JavaScript at all into the error page and the dialog is not displayed. I went with this solution.
like image 2
matsa Avatar answered Sep 22 '22 05:09

matsa