Skip to main content

Hide AJAX success messages after few seconds

I

I want to close all success messages automatically after a short delay so I don't have to close them manually anymore.

There are two ways how to get success (or error) message on a page. First is embedded into the page during the page rendering and it is easy to target these messages because they are part of the page source code. Second way is to get them from AJAX calls. These are more difficult to target, because they don't exists yet. You have to catch them when they are created.


As you might guessed, the solution lies in JavaScript.

I have a global.js file in workspace files (shared through all applications). With a help of Stack Overflow article I created a wait_for_element function. Then I added hide_success_message function and few comments. I believe the functionality is clear just from the names and comments. I had to do some #APEX_SUCCESS_MESSAGE element cleanup to make this work even if you receive multiple messages without page reload.

//
// WAIT FOR ELEMENT TO EXIST
//
var wait_for_element = function(search, start, fn, disconnect) {
    var ob  = new MutationObserver(function(mutations) {
        if ($(search).length) {
            fn(search, start);
            if (disconnect) {
                observer.disconnect();  // keep observing
            }
        }
    });
    //
    ob.observe(document.getElementById(start), {
        childList: true,
        subtree: true
    });
};

//
// HIDE SUCCESS MESSAGE
//
var hide_success_message = function(search, start) {
    var $start = $('#' + start);
    //
    setTimeout(function() {
        apex.message.hidePageSuccess();  // hide message
        var content = $start.text().trim();
        if (content.length) {
            console.log('MESSAGE CLOSED:', content);
        }
        $start.html('').removeClass('u-visible');  // clean APEX mess
    }, 4000);
};


Then you need to start the observer when page loads. I put this into the apex_page_loaded function in the same global.js file, because I already have some other functionality there. I am calling this function via DA on page 0, but you can do it multiple ways. I prefer this way for the visibility, so other developers knows (without checking all JS files) that there is an apex_page_loaded function executed after page loads.

//
// WHEN PAGE LOADS
//
var apex_page_loaded = function() {
    //
    // WAIT FOR SUCCESS MESSAGE
    //
    const search    = '#APEX_SUCCESS_MESSAGE.u-visible > .t-Body-alert > #t_Alert_Success';
    const start     = 'APEX_SUCCESS_MESSAGE';
    //
    wait_for_element(search, start, hide_success_message);
    hide_success_message(search.replace('.u-visible', ''), start);  // hide existing messages
};


Now, after 4 seconds every success message will be closed. Same for success messages generated at the page load. What a relief.

You should explore apex.message documentation and also APEX_ERROR package documenation. And if you manage to create same functionality with promises, please let me know.


Update

Few people notified me about this: https://apex.oracle.com/pls/apex/apex_pm/r/ut/javascript-apis


Comments

  1. But what's about

    $(".t-Alert.t-Alert--defaultIcons.t-Alert--success").delay(1500).fadeOut();

    It can be placed on o gljbal page ot in Dialog closed event after
    apex.message.showPageSuccess("Success!");

    ReplyDelete

Post a Comment