How To Open Admin Pointers On Button Click To Create Inline Documentation Or Help Popups

The “wp-pointer” class was added to WordPress with the update to version 3.3 and is used to display short alerts for new features inside the admin area of your blog. There are already several great tutorials out there on how to use the wp-pointer class inside your own plugin or theme, for example this article on tuts+ or this post by wpmudev.

All of the tutorials teach you how to replicate the way WordPress itself uses the pointers: Have them open automatically when a specific page is visited and make them disappear forever once a user presses the “Dismiss” button.

For a project of mine I needed a different approach: I wanted to open the pointer only once a user clicks a button. Within the pointer I wanted to have a “Next” button that jumps to the following pointer on a different element like in a slideshow. A “Close” button should simply close the current pointer.

The purpose was to create a inline documentation that would pop up on the click of a button inside my WP management service CMS Commander. A user can open it by pressing the help button at any time and then navigate through the pointers, each of which introduces details about a certain element on the page (e.g. “this button does that”, “here you can do this” and so on).

How to use WordPress admin pointers
Clicking the “?” icon opens the first pointer, the “Next” link allows users to go through the pointers like a slideshow.

So how to use wp-pointer on the click of a button? Maybe not surprisingly it is actually easier than the default way, because you do not need any AJAX calls to store the users dismissal of a pointer.

All you need to do is enqueue the necessary classes, add a button or link to your admin page that is meant to open the first pointer, and use jQuery to open and display the pointers. The pointers themselves are stored in a simple Javascript array in this example (because I only needed a few static ones).

1. Enqueue the wp-pointer script and style

We use the “admin_enqueue_scripts” action to add the wp-pointer class and its styles to the page when necessary. The $hook check beforehand makes sure the script only gets included when needed. In my example I have added the on-click pointers to the WordPress “Dashboard” page, hence the script is checking for “index.php”. If you want the pointers on another page you need to replace it in the code below:

add_action('admin_enqueue_scripts', 'wp_button_pointers_load_scripts');

function wp_button_pointers_load_scripts($hook) {
    if( $hook != 'index.php') {return;}   // stop if we are not on the right page

    wp_enqueue_style( 'wp-pointer' );
    wp_enqueue_script( 'wp-pointer' );
}

2. Add the HTML link or button that should open the first pointer when clicked

This is what will open the first pointer when getting clicked on by the user. It can be a link, button or any HTML element for that matter. Make sure it has the “wp-button-pointer-open-next” class, which we will use to open and cycle through our pointer messages.

Show Help

3. Creating your pointers with Javascript and jQuery

I have split the Javascript code into two parts for the sake of explaining it better. The two parts can follow each other directly in your final code.

The JS code can be added to what is already in your theme / plugin or create a new .js file, which you can then register and enqueue with the wp-pointer class above. If you need help with that have a look ad this detailed tutorial from WPbeginner.

In the first part of the Javascript code below we declare the content of our pointers. Since this was a simple project with static content I have simply used an array variable to hold each pointer. In the example below there are only 2 pointers, but it is easy to add more by continuing with wp_button_pointer_array[3] and so on.

The pointers in the array are displayed one after the other. That means wp_button_pointer_array[1] is shown after clicking the “help” button we added above, wp_button_pointer_array[2] after clicking the “next” button in the first pointer and so on.

Each pointer contains the following information:

  • element: The id of the element to attach the pointer to. For the first pointer I have used the id of the link that opens it (wp-button-pointer), meaning it gets shown next to the “help” button.
  • content: The content displayed inside the pointer message. Use a <h3></h3> tag to create the title bar of the pointer here.
  • position: Where the pointer is displayed in relation to the element it is attached to. You can change edge to left, right, top or bottom and align to top, bottom, left, right or middle depending on where your element is located on the page.
    var wp_button_pointer_array = new Array();
    wp_button_pointer_array[1] = {
        'element' : 'wp-button-pointer',
        'options' : {
            'content': 'The HTML content to show inside the pointer', 
            'position': {'edge': 'top', 'align': 'center'} 
        } 
    }; 
    wp_button_pointer_array[2] = { 
        'element' : 'some-element-id', 
        'options' : { 
            'content': 'The HTML content to show inside the pointer', 
            'position': {'edge': 'top', 'align': 'center'} 
        }
    };
    // ... repeat to add more pointers as needed

After declaring our pointer variable the next part of the Javascript handles opening and displaying them to the user. The relatively short code below is commented, so I hope it is possible to follow. Here is what it does:

  1. If any of the “Next” or “Open” buttons are clicked …
  2. Check if a pointer is open – if so close it.
  3. Open the following pointer (if one exists in the array).
  4. If another pointer exists after the one just opened attach a “Next” link to the current pointer. The “Next” link will repeat this process, without one the user can just close the last pointer.

Since the original “Help” link also has the class of a “Next” link that means the user can also go through the pointer by repeatedly clicking the “Help” link, which is a nice side effect.

jQuery(document).ready( function($) {

    jQuery('.wp-button-pointer-open-next').click(function(e) {
        e.preventDefault();	
        if(typeof(jQuery().pointer) != 'undefined') { // make sure the pointer class exists

            if(jQuery('.wp-pointer').is(":visible")) { // if a pointer is already open...
                var openid = jQuery('.wp-pointer:visible').attr("id").replace('wp-pointer-',''); // ... note its id
                jQuery('#' + wp_button_pointer_array[openid].element).pointer('close'); // ... and close it
                var pointerid = parseInt(openid) + 1;
            } else {
                var pointerid = 1; // ... otherwise we want to open the first pointer
            }

            if(wp_button_pointer_array[pointerid] != undefined) { // check if next pointer exists
                jQuery('#' + wp_button_pointer_array[pointerid].element).pointer(wp_button_pointer_array[pointerid].options).pointer('open');	// and open it
                var nextid = pointerid + 1;
                if(wp_button_pointer_array[nextid] != undefined) { // check if another next pointer exists
                    jQuery('#wp-pointer-' + pointerid + " .wp-pointer-buttons").append('Next'); // and if so attach a "next" link to the current pointer
                }					
            }
        }
    });			
});

That is all there is to using the “wp-pointer” class on button click and then allowing the user to “slide” through the different pointers. I hope this tutorial was useful to you.

Please note this code is far from perfect and could be extended in many ways. Depending on your needs you could look into loading the pointer contents from a database for example. If you have suggestions or improvements be sure to post them in the comments below!

Photo by Randy Heinitz

About Thomas Höfter

I am a WordPress plugin developer from Germany. Some might know me from my WP Robot plugin or one of my free plugins but most don't know me at all. To change that you can write me a message or find me on Google+.

9 Comments


  1. This is an outstanding tutorial. I have one question.

    How can I make the first pointer open on page load (instead of clicking on the link)?


    1. Also, I just tested your code exactly as it you detailed but it is not functioning as proposed. I think it may be a similar issue as the other commenter had.

      I am running the scrips on the post-new.php page. It is the page when you Add a new Post.

      Here is the full code in case you want to test it yourself to confirm:

      pastebin.com/QqnqiBhb

      The problem is that the popup DOES appear, but the next button is not working. I tested this on a fresh install of WordPress 4.

      Can you please advice?


      1. Hi James,

        sorry, as another user has reported the code in this tutorial seems to need an update for WP4. I did not have time to look into that yet unfortunately but will try to update the guide as soon as possible.


        1. Thomas, thank you for the reply and keep up updated. This is a great approach to the pointers feature so it would be great to have a working version of it for WP4.


  2. Haha no prob! I think that the main problem was when dealing with the array positions and pointers IDs. For me, the next link was not appending and when i fixed, the next pointer was not triggering.

    But was the best solution for pointers i have found so far!


  3. Hey Thomas, many thanks for sharing, this code had a great value on my project.

    Actually your actual code was not working for the next pointers. After some tests, i decided to rewrite, based on your idea, using a helper function.

    My next plan is to add link option to make redirects to something like a virtual tour.

    Thanks again,

    Best Regards,

    Guilherme

    Here is:

    var wp_button_pointer_array = new Array();
    wp_button_pointer_array[0] = {
    'element' : 'wp-button-pointer',
    'options' : {
    'content': 'The HTML content to show inside the pointer',
    'position': {'edge': 'top', 'align': 'center'}
    }
    };
    wp_button_pointer_array[1] = {
    'element' : 'toplevel_page_hdc_options',
    'options' : {
    'content': 'The HTML content to show inside the pointer',
    'position': {'edge': 'top', 'align': 'center'}
    }
    };
    wp_button_pointer_array[2] = {
    'element' : 'toplevel_page_hdc_noivos_options',
    'options' : {
    'content': 'The HTML content to show inside the pointer',
    'position': {'edge': 'top', 'align': 'center'}
    }
    };
    // ... repeat to add more pointers as needed

    jQuery(document).ready( function($) {

    jQuery('.wp-button-pointer-open-next').click(function(e) {
    e.preventDefault();
    if(typeof(jQuery().pointer) != 'undefined') { // make sure the pointer class exists

    // Checks if pointer is visible
    if(jQuery('.wp-pointer').is(":visible")) {
    var currentId = parseInt(jQuery('.wp-pointer:visible').attr("id").replace('wp-pointer-','')); // Current id of visible element
    var nextId = currentId + 1; // Next id to open
    // If is there a next, open it
    openPointer(nextId);

    } else {
    openPointer(); // Open the first pointer
    }

    }
    });

    });

    function openPointer (currentId) {

    // Check how many pointers in array
    var arraySize = wp_button_pointer_array.length;

    // Check if is the first pointer, if so, set the array poisition
    if(currentId) {
    currentId = currentId;
    } else {
    currentId = 0;
    }

    // Check if the first pointer is open
    if(currentId != 0) {
    jQuery(‘#’ + wp_button_pointer_array[(currentId – 1)].element).pointer(‘close’);
    }

    // Opens the pointers
    jQuery(‘#’ + wp_button_pointer_array[currentId].element).pointer(wp_button_pointer_array[currentId].options).pointer(‘open’);

    var limit = arraySize – 1;

    if((arraySize > 1) && currentId != limit) { // Append the next button if its not the last pointer
    var nextId = currentId + 1;
    jQuery(‘#wp-pointer-‘ + currentId + ” .wp-pointer-buttons”).append(‘Next‘);
    }
    }


    1. Hi Guilherme,

      thanks for your comment and for posting your code here!

      The code from the original post is still working fine for me for including admin pointers in my project. I will check if maybe some error crept in while copying it to this blog post.


  4. ok the problem is “var” need to change with “$” for php.

    $wp_button_pointer_array = new Array();

    but now i get another error:
    Parse error: syntax error, unexpected T_ARRAY


    1. Please note that this part is Javascript code, not php! I guess the reason for your errors is you are using it in the wrong context / as php.

Comments are closed.