Add a "are you sure you wish to leave" warning to changed settings page.

Hello :slight_smile:

I have a plugin which I'm currently still maintaining but it's not quite ready for release yet.

It's pretty much the JetPack's Custom-CSS plugin but then written for MultiSite installations (JetPack requires a per-site activation to use the plugins... ew.) with added sanitation (e.g. @import, "behavior:", javascript:< etc...)

Anyway, when a user edits the text-area and leaves the page without saving, I'd like to add a warning... just like which is done with TinyMCE..

Unfortunately, I couldn't find this function within WordPress, I guess it's something specific?

Do you guys know any built-in WP way to do so or do I need to write this from scratch using jQuery?

Thank you very much :slight_smile:

  • Predrag Dubajic

    Hey @Sybre Waaijer,

    Hope you're doing well today :slight_smile:

    I was unable to find any direct explanation on how to include this in custom plugin but maybe going through script-loader.php file included in WP will give you some hints on how can you include this.
    https://github.com/WordPress/WordPress/blob/master/wp-includes/script-loader.php

    Also, you can post a job on our job board and see if there are any developers that can assist you more with this.
    https://premium.wpmudev.org/wpmu-jobs/
    Please note that, no WPMU official staff members are allowed to work in the job board.

    Best regards,
    Predrag

  • Sybre Waaijer

    Hi @Predrag Dubajic

    Thanks for your suggestion :slight_smile:

    I've looked into other settings pages which show this behaviour and Genesis seems to have the best one implemented, I've rewritten it a bit and I still need to test it but I think I'm on the right plane here:

    ?>
    <script type="text/javascript">
    jQuery(function( $ ){
    function saveAlert() {
    	'use strict';
    
    	CodemirrorInstance.on('change',( function() {
    		mscss.registerChange();
    	});
    	window.onbeforeunload = function(){
    		if ( mscss.settingsChanged ) {
    			return mscssL10n.saveAlert;
    		}
    	};
    	jQuery( '#submit input[type="submit"]' ).click( function() {
    		window.onbeforeunload = null;
    	});
    }
    $(document).ready(function() { saveAlert(); });
    
    registerChange: function() {
    		'use strict';
    
    		mscss.settingsChanged = true;
    	}
    }
    </script>
    
    <script type='text/javascript'>
    /* <![CDATA[ */
    var mscssL10n = {
    	"saveAlert":"<?php _e( "The changes you've made will be lost when you navigate away from this page", 'secure-css' )?>"
    	};
    /* ]]> */
    </script>
    <?php

    I'll hit this topic back with the fully functioning and safe WordPress way of doing this when I'm satisfied with the results :slight_smile:

    Once again, thanks! :smiley:

  • Sybre Waaijer

    Well then... here goes:

    Notes:
    I wrapped my submit button in a .submit div.
    This function is extended to support CodeMirror. A regular text area wouldn't need the global variable ( mscss.editor ).

    If you're a programmer you'll figure out a way to manipulate this :slight_smile:

    The php:

    function secure_mscss_register_submenu_page() {
    	// param $page returns automatically
    	$page = add_theme_page( __( 'Custom CSS', 'secure_mscss' ), __( 'Custom CSS', 'secure_mscss' ), 'edit_theme_options', 'custom-css', 'secure_mscss_render_submenu_page' );
    
    	// Enqueue styles and scripts
    	add_action( 'admin_print_styles-' . $page, 'secure_mscss_register_codemirror' );
    }
    add_action( 'admin_menu', 'secure_mscss_register_submenu_page' );
    
    function secure_mscss_register_codemirror() {
    		$dir = plugin_dir_path( __FILE__ );
    
    		wp_enqueue_script( 'codemirror-js', plugins_url( 'codemirror/codemirror.min.js', $dir ), array(), '', true );
    		wp_enqueue_script( 'codemirror-css-js', plugins_url( 'codemirror/css.min.js', $dir ), array(), '', true );
    		wp_enqueue_script( 'mscss-js', plugins_url( 'codemirror/mscss.js', $dir ), array( 'jquery' ), '', true );
    
    		// Localize the script with new data
    		$strings = array(
    	 		'saveAlert' => __( 'The changes you made will be lost if you navigate away from this page.', 'plugin-domain' ),
    		);
    		wp_localize_script( 'mscss-js', 'mscssL10n', $strings );
    }

    The mscss-js file is the one we're putting the following code in, and this is where we call back the "saveAlert" string to (which can be translated):

    /**
     * Holds CodeMirror values and alerts user upon navigation after settings change.
     *
     * @since 1.0.0
     *
     * @constructor
     */
    window[ 'mscss' ] = {
    
        settingsChanged: false,
    
        editor: '',
    
        /**
         * Initialize Codemirror settings
         *
         * @since 1.0.0
         *
         * @function
         */
        codeMirrorSettings: function() {
            mscss.editor = CodeMirror.fromTextArea( document.getElementById( "secure_mscss_content" ), {
                lineNumbers: true,
                lineWrapping: true,
                mode: 'css',
                indentUnit: '4',
                tabSize: '4',
                indentWithTabs: true
            } );
        },
    
        /**
         * Have the CodeMirror css textarea set a dirty flag when changed.
         *
         * @since 1.0.0
         *
         * @function
         */
        settingsChangedListener: function() {
            'use strict';
    
            mscss.editor.on('change', function() {
                mscss.registerChange();
            });
    
            window.onbeforeunload = function(){
                if ( mscss.settingsChanged ) {
                    return mscssL10n.saveAlert;
                }
            };
            jQuery( '.submit input[type="submit"]' ).click( function() {
                window.onbeforeunload = null;
            });
        },
    
        /**
         * Set a flag, to indicate css textfield have changed.
         *
         * @since 1.0.0
         *
         * @function
         */
        registerChange: function() {
            'use strict';
    
            mscss.settingsChanged = true;
        },
    
        /**
         * Initialises all aspects of the scripts.
         *
         * @since 1.0.0
         *
         * @function
         */
        ready: function() {
            'use strict';
    
            // Initialise CodeMirror settings
            mscss.codeMirrorSettings();
    
            // Initialise settings changed navigation confirmation
            mscss.settingsChangedListener();
    
        }
    
    };
    jQuery( mscss.ready );

    The plugin isn't ready for w.org publication yet but it's almost there :slight_smile:
    From there the other scripts will be publicly available as well ^^

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.