I have a plugin which creates some options in wp_options, but also creates custom post types and is used to populate that post type. Upon install it makes sense to remove the data in wp_options, but with regards to the populated post type, there should be an option for the user to choose whether he wants to keep that data or not.

Ideally I would like a popup when he hits the uninstall link, asking if he wants to delete just the plugin files and options, or delete everything. How can I do such a popup?


3 Answers 3


How about something similar to this:

function wpse65611_script() {
    wp_enqueue_style( 'wp-pointer' );
    wp_enqueue_script( 'wp-pointer' );
    wp_enqueue_script( 'utils' ); // for user settings
    <script type="text/javascript">
    jQuery('#embed-github-gist .delete a').click(function(){
            jQuery('#embed-github-gist .delete a').pointer({
                content: '<h3>Delete this or delete everything?</h3><p><a id="this" class="primary button" href="url1">Delete data</a> <a id="everything" class="button" href="'+jQuery('#embed-github-gist .delete a').attr('href')+'">Delete plugin</a></p>',
                position: {
                    my: 'left top',
                    at: 'center bottom',
                    offset: '-1 0'
                close: function() {
return false;
add_action( 'admin_footer', 'wpse65611_script' );

Which results in this:

enter image description here

Replace url1 with the url that would delete just the data.

Note that this will not run if you put it in the plugin and the plugin is deactivated, putting it in another plugin or in a theme would work but it would be bad practice

Also replace the ID of the embed github gist plugin with your own

  • The actual popup should appear on the next screen, where the user gets the choice. I'm actually thinking that this will be overall too confusing for a user. I haven't seen any other plugin doing this and since I'm still quite inexperienced maybe it's better to do things the normal way and avoid this altogether.
    – urok93
    Sep 25, 2012 at 19:06
  • That's because in order for you to insert the extra choice your plugin needs to eb activated, and for you to be able to even get to that screen your plugin must be deactivated. Thus it is impossible for a plugin to modify its own delete plugin confirmation screen without outside help
    – Tom J Nowell
    Sep 25, 2012 at 19:08
  • But if you really must, just take the selector used and modify it so that it's the selector for the confirmation button link
    – Tom J Nowell
    Sep 25, 2012 at 19:08
  • 3
    Imagine you're trying to demolish a house and you want to add a button that removes all your stuff before it blows up, but to do that you need to be inside the house when it gets demolished
    – Tom J Nowell
    Sep 25, 2012 at 19:10
function wpse65611_confirm_uninstall()
        <input type="button" onclick="wpse65611_confirmation()" value="Delete Data?">

function wpse65611_script()
<script type="text/javascript">
    function wpse65611_confirmation()
        var answer = confirm( "Delete Data?" );
        if ( answer )
            window.location = "<?php admin_url( 'plugins.php?delete=data' ); ?>";
            window.location = "<?php admin_url( 'plugins.php' ); ?>";
add_action( 'admin_footer', 'wpse65611_confirmation' );

You could do it using javascript and ajax. Javascript catches the click asks if you want to delete data if so it calls delete the data ajax in either case it continues to the deactivate.

add_action('admin_enqueue_scripts', 'deactivate_message_enqueue');
function deactivate_message_enqueue($hook) {
    if ( 'plugins.php' != $hook ) {
        // do not enqueue because it is not plugins page

    wp_register_script('deactivation-message', plugins_url('includes/js/message_deactivate.js', __FILE__), array(), SOW_VERSION);
    $deleteParams = array(
        'ajax_url'      => admin_url( 'admin-ajax.php' ),
        'ajax_nonce'    => wp_create_nonce('nonce_salt'),
    wp_localize_script('deactivation-message', 'deactivation_data', $deleteParams);

add_action( 'wp_ajax_hss_so_delete_all_tables', 'hssSoDeleteAllTablesAjax' );
function hssSoDeleteAllTablesAjax() {
  global $wpdb;
  // need to check nonce so it is secure.
  $nonce = isset($_REQUEST['security']) ? sanitize_text_field($_REQUEST['security']) : '';

  if ( ! wp_verify_nonce( $nonce, 'nonce_salt' ) ) {
    wp_send_json_error(array('error' => 'Nonce invalid'));

  // delete what you have to here
  wp_send_json_success(array('error' => ''));


Then in the script file catch the url redirect of the deactivate and call ajax function to delete the data


window.onload = function(){
  document.querySelector('[data-slug="plugin-slug"] .deactivate a').addEventListener('click', function(event){
    var urlRedirect = document.querySelector('[data-slug="plugin-slug"] .deactivate a').getAttribute('href');
    if(confirm('Do you want to delete all the data created for this plugin?')) {
    window.location.href = urlRedirect;

function deleteAllPluginData(){
var data = 'action=delete_all_my_plugin_data&security=' + deactivation_data.ajax_nonce;

    type : "post",
    dataType : "json",
    url : deactivation_data.ajax_url,
    data : data,
    success: function(response) {
        if (response.success == true) {
            console.log('All Data Deleted.');
        } else {
            console.log('There was an error deleting data: ' + JSON.stringify(response.data.error));


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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