6

In WordPress 4.2 the is-dismissible class was introduced to allow notices to be dismissed.

This code is working to add the notice.

function prefix_deprecated_hook_admin_notice() {
    if ( has_filter( 'prefix_filter' ) ) { ?>
        <div class="updated notice is-dismissible">
            <p><?php _e( 'Notice', 'my-text-domain' ); ?></p>
        </div>
    <?php }
}
add_action( 'admin_notices', 'prefix_deprecated_hook_admin_notice' );

I am able to dismiss the notice but I am unsure how I can save the state when the notice is dismissed with AJAX.

4

There's no need for a library, it's fairly straightforward to accomplish. If you are coding your own plugin (which it appears you are), then you can do this in a fairly lightweight way:

A slightly modified version of the notice, which checks if it's been dismissed before displaying, and stores the "type" of notice in the markup for access in javascript:

function prefix_deprecated_hook_admin_notice() {
    if ( has_filter( 'prefix_filter' ) ) { 
        // Check if it's been dismissed...
        if ( ! get_option('dismissed-prefix_deprecated', FALSE ) ) { 
            // Added the class "notice-my-class" so jQuery pick it up and pass via AJAX,
            // and added "data-notice" attribute in order to track multiple / different notices
            // multiple dismissible notice states ?>
            <div class="updated notice notice-my-class is-dismissible" data-notice="prefix_deprecated">
                <p><?php _e( 'Notice', 'my-text-domain' ); ?></p>
            </div>
        <?php }
    }
}

add_action( 'admin_notices', 'prefix_deprecated_hook_admin_notice' );

And then, the following jQuery

  // shorthand no-conflict safe document-ready function
  jQuery(function($) {
    // Hook into the "notice-my-class" class we added to the notice, so
    // Only listen to YOUR notices being dismissed
    $( document ).on( 'click', '.notice-my-class .notice-dismiss', function () {
        // Read the "data-notice" information to track which notice
        // is being dismissed and send it via AJAX
        var type = $( this ).closest( '.notice-my-class' ).data( 'notice' );
        // Make an AJAX call
        // Since WP 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
        $.ajax( ajaxurl,
          {
            type: 'POST',
            data: {
              action: 'dismissed_notice_handler',
              type: type,
            }
          } );
      } );
  });

In PHP, set up the AJAX hooks to capture the AJAX call:

add_action( 'wp_ajax_dismissed_notice_handler', 'ajax_notice_handler' );

/**
 * AJAX handler to store the state of dismissible notices.
 */
function ajax_notice_handler() {
    // Pick up the notice "type" - passed via jQuery (the "data-notice" attribute on the notice)
    $type = self::request( 'type' );
    // Store it in the options table
    update_option( 'dismissed-' . $type, TRUE );
}

And that's it! No library needed - especially if you've already got PHP and javascript files loading.

This method is per the WordPress Core dev team blog

  • Thanks for the write up, very helpful. For those that have issues with $type = self::request('type'); you can also access the value via POST super global as $type = $_POST['type']. Im unsure about self here, as it looks as the OP is using procedural functions and not methods. At any rate I received Fatal warning: Cannot use "self" when no class scope is active .... – orionrush Feb 5 '17 at 15:51
  • Also it's worth mentioning, if you're using this as a quick primer for wp ajax transactions in general, this example doesn't include the use of a nonce or sanitise the incoming $type data. In this case it's okay, but if applied to more complex ajax transactions, you'd want to use both for security reasons. – orionrush Feb 5 '17 at 15:56
  • After a quick look at the documentation for WP_Http::request() method, I'm not seeing any in-built sanitisation, so a quick application of 'sanitize_html_class($type)` might not be such a bad idea for either the request method or POST. codex.wordpress.org/Function_Reference/sanitize_html_class – orionrush Feb 5 '17 at 16:16
0

The best solution I found was a small library. https://github.com/CalderaWP/dismissible_notice

It is backward compatible till WordPress 3.8.

  • 1
    Also an alternative library is here, small and solid. – bueltge Oct 24 '16 at 19:37

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.