Trigger Javascript on Gutenberg (Block Editor) Save

So I have a metabox which I want to trigger some Javascript when a post is saved (to refresh the page in this use case.)

In Classic Editor, this can be done via a simple redirect hooked to save_post (with a high priority)

But since Gutenberg converts the saving process for existing metaboxes into individual AJAX calls now, it needs to be javascript, so how do I either:

  • Listen for an event where all the saving processes are complete and then trigger the javascript? If so what is this event called? Is there a reference to these events anywhere yet? OR
  • Trigger javascript inside the metabox saving AJAX process, which can then check the state of the parent page saving process before continuing?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Not sure if there is a better way, but I am listening to subscribe rather than adding an event listener to the button:

wp.data.subscribe(function () {
  var isSavingPost = wp.data.select('core/editor').isSavingPost();
  var isAutosavingPost = wp.data.select('core/editor').isAutosavingPost();

  if (isSavingPost && !isAutosavingPost) {
    // Here goes your AJAX code ......

  }
})

Official docs of the Post Editor data: https://wordpress.org/gutenberg/handbook/designers-developers/developers/data/data-core-editor/

Method 2

Okay, so way way more hacky solution than I wanted, but got it working…

Here is a slightly simplified and abstracted way of doing it from my code, in case anyone ever needs to do the same (as I’m sure more plugins will in the near future.)

    var reload_check = false; var publish_button_click = false;
    jQuery(document).ready(function($) {
        add_publish_button_click = setInterval(function() {
            $publish_button = jQuery('.edit-post-header__settings .editor-post-publish-button');
            if ($publish_button && !publish_button_click) {
                publish_button_click = true;
                $publish_button.on('click', function() {
                    var reloader = setInterval(function() {
                        if (reload_check) {return;} else {reload_check = true;}
                        postsaving = wp.data.select('core/editor').isSavingPost();
                        autosaving = wp.data.select('core/editor').isAutosavingPost();
                        success = wp.data.select('core/editor').didPostSaveRequestSucceed();
                        console.log('Saving: '+postsaving+' - Autosaving: '+autosaving+' - Success: '+success);
                        if (postsaving || autosaving || !success) {classic_reload_check = false; return;}
                        clearInterval(reloader);

                        value = document.getElementById('metabox_input_id').value;
                        if (value == 'trigger_value') {
                            if (confirm('Page reload required. Refresh the page now?')) {
                                window.location.href = window.location.href+'&refreshed=1';
                            }
                        }
                    }, 1000);
                });
            }
        }, 500);
    });

…just need to change metabox_input_id and trigger_value to match as needed. 🙂

Method 3

In order to trigger the action (in this case an Ajax request) AFTER the post save is COMPLETE, you can use an interval to wait until the isSavingPost returns false again.

let intervalCheckPostIsSaved;
let ajaxRequest;

wp.data.subscribe(function () {
    let editor = wp.data.select('core/editor');

    if (editor.isSavingPost()
         && !editor.isAutosavingPost()
         && editor.didPostSaveRequestSucceed()) {

        if (!intervalCheckPostIsSaved) {
            intervalCheckPostIsSaved = setInterval(function () {
                if (!wp.data.select('core/editor').isSavingPost()) {
                    if (ajaxRequest) {
                        ajaxRequest.abort();
                    }

                    ajaxRequest = $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: {},
                        success: function (data) {
                            ajaxRequest = null;
                        }
                    });

                    clearInterval(intervalCheckPostIsSaved);
                    intervalCheckPostIsSaved = null;
                }
            }, 800);
        }
    }
});

Method 4

You need collect unsubscribe function from subscribe and call to avoid multiples time call.

const unsubscribe = wp.data.subscribe(function () {
            let select = wp.data.select('core/editor');
            var isSavingPost = select.isSavingPost();
            var isAutosavingPost = select.isAutosavingPost();
            var didPostSaveRequestSucceed = select.didPostSaveRequestSucceed();
            if (isSavingPost && !isAutosavingPost && didPostSaveRequestSucceed) {
                console.log("isSavingPost && !isAutosavingPost && didPostSaveRequestSucceed");
                unsubscribe();


                // your AJAX HERE();

            }
        });


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x