Як зберегти стан перетягувача редактора макетів інтерфейсу jQuery UI Sortables?


20

Я будую редактор макетів передньої частини за допомогою JQuery UI Sortable .

Пости викладені в 300px на 250px на фоновому зображенні. Записи створюються та редагуються за допомогою адміністратора WordPress, але я хочу дозволити адміністратору сайтів регулювати порядок скриньок за допомогою інтерфейсу перетягування на передній частині.

У мене працює сортувальна частина перетягування, але потрібно придумати спосіб збереження стану (порядку) скриньки. В ідеалі я хотів би мати можливість зберегти стан як варіант і вбудувати його у запит.

Запит для публікацій - це простий WP_Query, який також отримує дані зі спеціальних метаполев для визначення індивідуального макета вікна:

$args= array(
      'meta_key' => 'c3m_shown_on',
       'meta_value'=> 'home' );
    $box_query = new WP_Query($args);  ?>
        <ul id="sortable">
            <?php
    while ($box_query->have_posts()) : $box_query->the_post(); global $post; global $prefix;           
    $box_size = c3m_get_field($prefix.'box_size', FALSE);
    $box_image = c3m_get_field($prefix.'post_box_image', FALSE);
    $overlay_class = c3m_get_field($prefix.'overlay_class', FALSE);

    if ( c3m_get_field($prefix.'external_link', FALSE) ) {
    $post_link = c3m_get_field($prefix.'external_link', FALSE);
    } else
            { $post_link = post_permalink(); 
    } ?>     
     <li class="<?php echo $box_size;?>  ui-state-default">
        <article <?php post_class() ?> id="post-<?php the_ID(); ?>">
            <?php echo  '<a href="'.$post_link.'" ><img src="'.esc_url($box_image).'" alt="Image via xxxxx.com" /></a>'; ?>
                <div class="post-box <?php echo $overlay_class;?>">
                <?php if ( c3m_get_field( $prefix.'text_display', FALSE) ) { ?>     
                <h2><a href="<?php echo $post_link?>"><?php the_title();?></a></h2> 
                <p><?php echo substr($post->post_excerpt, 0, 90) . '...'; ?></p>            
                <?php } ?>               
                </div>
         </article>
     </li>              
    <?php endwhile; ?>
       </ul>
</section>

Javascript - це лише основні інструкції щодо сортування за замовчуванням

jQuery(document).ready(function() {
    jQuery("#sortable").sortable();
  });

Є методи, доступні за допомогою файли cookie для збереження стану, але мені також потрібно вимкнути перетягування сортування для користувачів, які не є адміністратором, тому мені дійсно потрібно зберегти в базі даних.

Я шукаю найкреативніший і зручніший спосіб і присуджую 100 балів за найкращу відповідь.

Оновлення:

У мене соматичні відповідь, працюючи з однією незначною зміною.

ajaxurl не повертає значення на сторінках, які не є адміністратором, тому я wp_localize_script( 'functions', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );визначав значення і змінив рядок javascript у параметрах на:
url: MyAjax.ajaxurl,

Щоб обмежити доступ до упорядкування замовлення лише адміністраторам, я додав умовну функцію до своєї wp_enqueue_script:

    function c3m_load_scripts() { 
    if ( current_user_can( 'edit_posts' ) ) {
        wp_enqueue_script( 'jquery-ui' );
        wp_enqueue_script( 'functions', get_bloginfo( 'stylesheet_directory' ) . '/_/js/functions.js', array( 'jquery', 'jquery-ui' ), false);
        wp_localize_script( 'functions', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );
    }
}

Я збираюся зробити ще трохи тестування і відзначу це питання як вирішене та нагородити щедротою.


1
Чи можливо ви можете використовувати menu_order для публікацій? Я знаю, що ви можете використовувати їх у вкладеннях, то чому б не дописувати? якщо можливо, саме тут ви можете зберігати порядок публікацій ...
Брейді

1
Схоже, ви можете - "menu_order" - упорядкувати за порядком сторінки. Найчастіше використовується для Сторінок (поле для замовлення у вікні Редагувати атрибути сторінки) та для вкладень (цілі поля в діалоговому вікні "Вставити / Завантажити медіагалерею"), але може використовуватися для будь-якого типу публікації з різними значеннями "menu_order" (усі вони за замовчуванням до 0).
Брейді

@Brady Чудова ідея використання menu_order. @somatic на ньому розширився, і це спрацювало. Спасибі!
Chris_O

Відповіді:


21

Брейді вважає, що найкращим способом обробки збереження та відображення замовлень на замовлення типу пошти є використання menu_orderвластивості

Ось jquery, щоб зробити список сортуванням та передати дані через ajax до wordpress:

jQuery(document).ready(function($) {        
    var itemList = $('#sortable');

    itemList.sortable({
        update: function(event, ui) {
            $('#loading-animation').show(); // Show the animate loading gif while waiting

            opts = {
                url: ajaxurl, // ajaxurl is defined by WordPress and points to /wp-admin/admin-ajax.php
                type: 'POST',
                async: true,
                cache: false,
                dataType: 'json',
                data:{
                    action: 'item_sort', // Tell WordPress how to handle this ajax request
                    order: itemList.sortable('toArray').toString() // Passes ID's of list items in  1,3,2 format
                },
                success: function(response) {
                    $('#loading-animation').hide(); // Hide the loading animation
                    return; 
                },
                error: function(xhr,textStatus,e) {  // This can be expanded to provide more information
                    alert(e);
                    // alert('There was an error saving the updates');
                    $('#loading-animation').hide(); // Hide the loading animation
                    return; 
                }
            };
            $.ajax(opts);
        }
    }); 
});

Ось функція wordpress, яка слухає зворотний виклик ajax і виконує зміни в БД:

function my_save_item_order() {
    global $wpdb;

    $order = explode(',', $_POST['order']);
    $counter = 0;
    foreach ($order as $item_id) {
        $wpdb->update($wpdb->posts, array( 'menu_order' => $counter ), array( 'ID' => $item_id) );
        $counter++;
    }
    die(1);
}
add_action('wp_ajax_item_sort', 'my_save_item_order');
add_action('wp_ajax_nopriv_item_sort', 'my_save_item_order');

Ключовим для відображення публікацій у збереженому порядку є додавання menu_orderвластивості до аргументів запиту:

$args= array(
    'meta_key' => 'c3m_shown_on',
    'meta_value'=> 'home'
    'orderby' => 'menu_order',
    'order' => 'ASC'
);

$box_query = new WP_Query($args);

Потім запустіть цикл і виведіть кожен елемент ... (перший рядок - це анімація завантаження основного wp - ви хочете спочатку сховати його за допомогою css, а потім функція jquery відобразиться при обробці)

<img src="<?php bloginfo('url'); ?>/wp-admin/images/loading.gif" id="loading-animation" />
<ul id="sortable">
    <li id="{echo post ID here}">{echo title or other name here}</li>
</ul>

Код, натхненний чудовим підручником soulsizzle .


Відмінна відповідь. Я дам йому постріл.
Chris_O

Дякую вам за це - повністю допоміг над тим, над чим я теж працював. Одна з проблем, на яку я зіткнувся, полягала в тому, що кожен елемент у списку сортування повинен мати ідентифікатор, який відповідає ідентифікатору публікації. Це було в навчальному посібнику, але не на посаді ОП.
Далтон

Абсолютно правильно, Далтоне, я був занадто коротким у своєму прикладі. Код оновлено.
соматично

4

http://jsfiddle.net/TbR69/1/

Далеко не закінчено, але ідея полягає в тому, щоб надіслати запит на ajax при перетягуванні. Ви також можете запустити запит ajax лише після натискання кнопки "зберегти" або чогось іншого. Буде відправлений масив, що містить ідентифікатори пошти та нове замовлення.

Тоді вам доведеться оновити публікації в базі даних на кінці сервера. Нарешті, додайте orderпараметр до свогоWP_Query циклу.

Я сподіваюся, що з цього ви почнете працювати. Будь-хто сміє продовжувати лаятись.


0
/**
 *  Enqueue javascript and css files
 */
function uc_enqueue_my_assets() {
    wp_enqueue_script( 'jquery-ui-sortable');
    wp_register_script( 'order', plugins_url( '/js/order.js', __FILE__ ), array( 'jquery' ) );
    wp_enqueue_script( 'order' );
}

function uc_is_user_logged_in()
{
    if ( is_user_logged_in()) {
        add_action( 'wp_enqueue_scripts', 'uc_enqueue_my_assets' );
        add_action( 'admin_enqueue_scripts', 'uc_enqueue_my_assets' );
    }
}
add_action('init', 'uc_is_user_logged_in');


/**
 *  Update order of posts by ajax on trigger of drag and drop event
 */
function uc_sort_post_items() {

    $order = wp_parse_id_list(explode(',', $_POST['order']));
    write_log($order);

    global $wpdb;
    $list = join(', ', $order);
    $wpdb->query('SELECT @i:=0');
    $wpdb->query(
        "UPDATE wp_posts SET menu_order = ( @i:= @i+1 )
        WHERE ID IN ( $list ) ORDER BY FIELD( ID, $list );"
    );

    wp_die();
}
add_action('wp_ajax_uc_sort_post_items', 'uc_sort_post_items');
add_action('wp_ajax_nopriv_uc_sort_post_items', 'uc_sort_post_items');



/**
 *  Display sorted posts
 */
function uc_pre_get_posts( $wp_query ) {
    write_log(basename($_SERVER['PHP_SELF']));
    $wp_query->set('orderby', 'menu_order');
    $wp_query->set('order', 'ASC');
}
add_action( 'pre_get_posts', 'uc_pre_get_posts', 1 );

Javascript-файл order.js

$('#the-list').sortable({
        update: function(event, ui) {

            $.ajax({

                url: '/wp-admin/admin-ajax.php',
                type: 'post',
                dataType: 'json',
                data:{
                    action: 'uc_sort_post_items', // Tell WordPress how to handle this ajax request
                    order: '4567,4569,4565 ' // Passes ID's of list items in  1,3,2 format. Write your own js method to access the list of id from frontend.
                },
                success: function(data, response) {
                    console.log(response);
                },
                error: function(xhr,textStatus,e) {
                    alert(e);
                }

                });

        }
    });

Будь ласка, не просто дамп-код. Вас просять додати пояснення, чому, на думку, наведений вище код відповість на питання.
Іслам Мейєнеул

@MayeenulIslam Опис уже додано до фрагментів коду як рядок коментарів.
SkyRar
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.