8

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?

  • 1
    Making Gutenberg reload just your metabox is also a potential solution, as would implementing the metabox UI in JS and relying on wp.data data stores – Tom J Nowell Nov 13 '18 at 2:07
  • @TomJNowell I have found this reference I can use to check some states, but not sure how to access them: wordpress.org/gutenberg/handbook/data/data-core-editor – majick Nov 13 '18 at 2:37
  • so far I have: eg. wp.data.select('core/editor').isSavingPost() ... this kind of access is not documented anywhere I can see... and it seems also unreliable as it returns false after the post is first saved (before that it is undefined) whether the editor is still saving or not. facepalm – majick Nov 13 '18 at 5:50
  • You can raise an issue on the gutenberg repo for support too, it's on topic here but you might get more knowledgable people answering there. Also the JS WP hooks system might be a possibility but that's just a guess – Tom J Nowell Nov 13 '18 at 7:02
  • Crazily, something simple like this is already asked for and not supported: github.com/WordPress/gutenberg/issues/10044 ... hence I am trying to find a way to do it myself. – majick Nov 13 '18 at 7:14
4

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/

  • this looks much cleaner, just curious where does the subscribe method even come from? is it part of the wp.data function? I don't see it mentioned in the docs. – majick Mar 12 at 13:50
  • Yes, subscribe is a method of the wp.data module. Open the console when editing a post with Gutenberg and run wp.data. This lists all available data module methods. – tomyam Mar 13 at 8:37
  • 1
    well done on finding this! it's unfortunate the gutenberg docs are so obscurely laid out and don't have enough examples. plus the expectation that developers will know and/or want to learn React methods is really too much... I'm sure it can be quite a timesaver if you know it already, but it's a real timewaster if you don't - took me hours just to work out how to access anything useful in wp.data model. it's back to PHP (and classic editor) for me. – majick Mar 14 at 9:30
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. :-)

  • This was useful, the only reference example I could find to accessing the gutenberg javascript module hierarchy: github.com/front/gutenberg-js – majick Nov 13 '18 at 8:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.