1

This is an extension of Update Option Stored in Multi-Dimensional Array which was help getting draggable plugin options to save via ajax (which works), but unfortunately this is specific to the actual plugin settings saving to the database correctly. Ajax re-ordering works, but upon page-save (plugin settings save), the options are cleared from the database. Here is the settings page:

<?php

function mouldings_options_page() {

    global $mouldings_options;

    ob_start(); ?>

    <div class="wrap">
        <h2 style="margin: 0 0 5px;"><?php _e('Mouldings Options','roots'); ?></h2>

        <form method="post" action="options.php" id="mouldings_options">

        <?php settings_fields('mouldings_settings_group'); ?>
                <div id="thumbnail-sizes" class="wp-box">
                    <div class="wp-box-half left">
                        <div class="inner">
                            <h2><?php _e('Thumbnail Sizes'); ?></h2>
                            <table class="widefat">
                                <thead>
                                    <tr>
                                        <th><?php _e('Post Type','roots'); ?></th>
                                        <th><?php _e('Width (px)','roots'); ?></th>
                                        <th><?php _e('Height (px)','roots'); ?></th>
                                    </tr>
                                </thead>
                                <tbody>
                                    <tr>
                                        <td><label class="description" for="mouldings_settings[idea_gallery_thumb_height]"><?php _e('Idea Gallery','roots'); ?></label></td>
                                        <td><input id="mouldings_settings[idea_gallery_thumb_height]" name="mouldings_settings[idea_gallery_thumb_height]" type="text" value="<?php echo (isset($mouldings_options['idea_gallery_thumb_height'])) ? $mouldings_options['idea_gallery_thumb_height'] : ''; ?>"></td>
                                        <td><input id="mouldings_settings[idea_gallery_thumb_width]" name="mouldings_settings[idea_gallery_thumb_width]" type="text" value="<?php echo (isset($mouldings_options['idea_gallery_thumb_width'])) ? $mouldings_options['idea_gallery_thumb_width'] : ''; ?>"></td>
                                    </tr>
                                    <tr>
                                        <td><label class="description" for="mouldings_settings[collection_thumb_height]"><?php _e('Moulding Collection','roots'); ?></label></td>
                                        <td><input id="mouldings_settings[collection_thumb_height]" name="mouldings_settings[collection_thumb_height]" type="text" value="<?php echo (isset($mouldings_options['collection_thumb_height'])) ? $mouldings_options['collection_thumb_height'] : ''; ?>"></td>
                                        <td><input id="mouldings_settings[collection_thumb_width]" name="mouldings_settings[collection_thumb_width]" type="text" value="<?php echo (isset($mouldings_options['collection_thumb_width'])) ? $mouldings_options['collection_thumb_width'] : ''; ?>"></td>
                                    </tr>
                                </tbody>
                            </table>
                        </div>
                    </div>
                    <div class="wp-box-half right">
                        <div class="inner">
                            <?php echo '<h2>'.__('Information','roots').'</h2>';
                            _e('<p>Used to resize the various images that appear throughout the Mouldings plugin. If any values are left blank, they are assumed to be un-restricted.</p>','roots'); ?>
                            <?php
                            if(function_exists('RegenerateThumbnails')) {
                                echo '<div class="m-updated"><p><a href="'.admin_url('tools.php?page=regenerate-thumbnails').'">Regenerate Thumbnails</a> after altering these values</p></div>';
                            }
                            else {
                                echo '<div class="m-error"><p><strong>Notice:</strong> <a href="'.admin_url('plugin-install.php?tab=search&type=term&s=regenerate+thumbnails&plugin-search-input=Search+Plugins').'">Regenerate Thumbnails</a> is not installed. This is required so that you can regenerate thumbnails after changing any of these values.</p></div>';
                            }
                            ?>
                        </div>
                    </div>
                    <div class="clear"></div>
                </div>

                <div id="profile-sidebar-order" class="wp-box">
                    <div class="wp-box-half left">
                        <div class="inner">
                            <h2><?php _e('Profile Sidebar Order'); ?></h2>
                            <table class="widefat psort-list">
                                <thead>
                                    <tr>
                                        <th><?php _e('Name', 'roots'); ?></th>
                                        <th><?php _e('Order', 'roots'); ?></th>
                                    </tr>
                                </thead>
                                <tbody>
                                <?php
                                    $count = 0;
                                    foreach($mouldings_options['profile_element_order'] as $key => $item) :
                                        echo '<tr id="list_items_' . $key . '" class="list_item">';
                                            echo '<td>' . $item . '</td>';
                                            echo '<td>' . $count . '</td>';
                                        echo '</tr>';
                                        $count++;
                                    endforeach;
                                ?>
                                </tbody>
                            </table>
                        </div>
                    </div>
                    <div class="wp-box-half right">
                        <div class="inner">
                            <?php echo '<h2>'.__('Information','roots').'</h2>';
                            _e('<p>Drag \'n drop the order of the elements that appear on the sidebar for both Profiles and Combinations.</p>','roots'); ?>
                        </div>
                    </div>
                    <div class="clear"></div>
                </div>




            <p class="submit">
                <input type="submit" class="button-primary" value="<?php _e('Save Options','roots'); ?>">
            </p>

            </form>
        </div>

    <?php
    echo ob_get_clean();
}

function mouldings_plugin_admin_styles() {
    wp_enqueue_style('mouldings-admin-styles', MOULDINGS_BASE_URL . 'css/admin-global.css','','',$media = 'all');
    wp_enqueue_script('jquery-ui-sortable');
    wp_enqueue_script('mouldings-admin-settings-scripts',  MOULDINGS_BASE_URL . 'js/admin-settings.js', array('jquery'), '', true);
}

function mouldings_add_options_link() {
    $mouldings_options_page = add_options_page(__('Mouldings Options','roots'),__('Mouldings','roots'),'manage_options','mouldings-options','mouldings_options_page');
    add_action( 'admin_print_styles-' . $mouldings_options_page, 'mouldings_plugin_admin_styles' );
}
add_action('admin_menu','mouldings_add_options_link');

function mouldings_register_settings() {
    register_setting('mouldings_settings_group','mouldings_settings');
}
add_action('admin_init','mouldings_register_settings');

?>

I'm thinking this may have something to do with "how" the profile_element_order items are rendered? They are properly created on activation using this hook:

<?php

function mouldings_activate() {
    global $wpdb, $mouldings_options;
    if( false == get_option( 'mouldings_settings' ) ) {
        $mouldings_options = array(
            'img_base64_enable'         => '1',
            'moulding_combination_page' => '',
            'moulding_collection_page'  => '',
            'idea_gallery_thumb_height' => '200',
            'idea_gallery_thumb_width'  => '200',
            'collection_thumb_height'   => '200',
            'collection_thumb_width'    => '200',
            'profile_item_columns'      => '4',
            'idea_item_columns'         => '2',
            'collections_item_columns'  => '2',
            'combinations_item_columns' => '4',
            'profile_element_order'     => array(
                'Option 1',
                'Option 2',
                'Option 3',
                'Option 4',
                'Option 5'
            )
        );
        update_option( 'mouldings_settings', $mouldings_options );
    }
}
register_activation_hook( MOULDINGS_PLUGIN_FILE, 'mouldings_activate' );

but are removed upon save. Thanks!

1 Answer 1

2

So the option profile_element_order forms is an array term - and WordPress considers that entire array to be on option. When you click 'save' the form data is posted to WordPress. WordPress recieves this as an array and it updates your option-row in the database by over-riding the old options array with a the one its just recieved.

The problem is that your option profile_element_order is not forming part of that recieved array, because its not posted (it's just printed to the page, but there are no inputs).

It seems though you are trying to update with both AJAX and a standard form - but you need to sync them. So when your profile_element_order option is updated via AJAX it updates some hidden forms, so when the user clicks 'save' the form is sending the updated options.

But then why bother with AJAX? If the user is going to click save and have the form data posted, then AJAX here is redundant and only causing syncing problems.

I would use hidden inputs to store the order, and this updated when the user re-orders them. That order is only saved when the user clicks save (along with all the other options).

Also, you may want to read up on the settings API. You seem to be using only part of it... see this answer (and linked tutorials).

4
  • Hi Stephen - thanks for your thoughts on that. It does make perfect sense to get rid of AJAX in this case -- do you have any tips on how to create those hidden inputs to make sure they save correctly/are posted to the DB table (within that foreach statement)? Thanks.
    – Zach
    May 11, 2012 at 15:44
  • I would have a hidden input for each draggable element that contains their order (1 through to 5). When you come to validate your settings, use that to order them and then place them, in order, into your validated settings array to be saved to db. May 11, 2012 at 15:55
  • Hi Stephen, I edited to the foreach() statement to look like this: pastebin.com/hjnBC1Bj (which I believe does what you are saying). The part I'm still struggling with is how to save that order based on the drag 'n drop that is done via jQueryUI Sortable (that function is here: pastebin.com/MHxgh7qK ). My AJAX processing function currently look like this: pastebin.com/Ft7sK65r which the sortable JS is calling via AJAX (which I know is not what I want to do) -- so it's the disconnect I'm having on how to save that order without AJAX. Thanks.
    – Zach
    May 11, 2012 at 16:17
  • Got this one working over the weekend. Thanks for the insights.
    – Zach
    May 14, 2012 at 14:52

Your Answer

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

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