add_meta_boxes action with refresh on save

So I managed to cobble something together with a bit of javascript… It’s hacky but somewhat elegant I think.

add_action('admin_init', function () {
    if ( current_user_can("send_notifications") ) {
        $post_types = ["post", "go_live"];
        foreach ($post_types  as $post_type) {
            add_meta_box(
                'cabtv_notif_on_post',
                'Notifications',
                function ($post) {
                    wp_nonce_field( 'cabtv_notif_metabox', 'cabtv_notif_metabox' );
                    $sent = (bool) get_post_meta( $post->ID, 'cabtv_notifications_sent', true );
                    $checked = cabtv_should_post_send_notification($post->ID);
                    ?>
                    <div id="cabtv_notification_sent" style="margin-bottom:10px; <?php if (!$sent) echo "display: none'; ?>'><span style="color:red; font-weight:bold;">Notifications have been sent for this post.</span></div>
                    <label><input type="checkbox" id="cabtv_send_notification" name="cabtv_send_notification" value="1" <?php if ($checked) echo 'checked'; ?>></input> <?php echo esc_attr('Send notification on '.($post->post_status === 'publish' ? 'update' : 'publish') ); ?></label>
                    <script>
                    $(document).ready(()=>{
                        function update_meta_box() {
                            var cb = document.querySelector("#cabtv_send_notification");
                            if (cb.checked) document.querySelector("#cabtv_notification_sent").style.display = null;
                            cb.checked = false;
                        }
                        var dispatch = wp.data.dispatch( 'core/edit-post' );
                        var oldMetaBoxUpdatesSuccess = dispatch.metaBoxUpdatesSuccess;
                        dispatch.metaBoxUpdatesSuccess = function(...args) {
                            update_meta_box();
                            return oldMetaBoxUpdatesSuccess.apply(this, args);
                        }
                    });
                    </script>
                <?php },
                $post_type,
                'side',
                'high'
            );
        }
    }
});

I looked through wordpress’ edit-post.js and found a function called metaBoxUpdatesSuccess that seemingly does nothing, but it’s called right at the moment when the spinner in all the metabox headers disappears.
So I replaced the function with a wrapper, which would also trigger my metabox html to update.
Annoyingly though it means having to write the same thing twice in PHP & JS essentially, and I can imagine a scenario where it would require additional AJAX to fetch the essential data.

Anyway, it’s better than nothing!

Leave a Comment