Làm cách nào để lưu trạng thái kéo và thả Trình soạn thảo bố cục giao diện người dùng jQuery Sắp xếp?


20

Tôi đang xây dựng một trình soạn thảo bố cục bài trước bằng cách sử dụng jQuery UI Sortable .

Các bài viết được đặt trong các hộp 300px x 250px trên một hình ảnh nền. Các bài đăng được tạo và chỉnh sửa bằng quản trị viên WordPress nhưng tôi muốn cho phép quản trị viên trang web điều chỉnh thứ tự của các hộp bằng giao diện kéo và thả ở mặt trước.

Tôi đã có một phần kéo và thả có thể sắp xếp làm việc nhưng cần phải tìm ra cách để lưu trạng thái (thứ tự) của các hộp. Lý tưởng nhất là tôi muốn có thể lưu trạng thái dưới dạng tùy chọn và xây dựng nó thành truy vấn.

Truy vấn cho các bài đăng là một WP_Query đơn giản cũng lấy dữ liệu từ các hộp meta tùy chỉnh để xác định bố cục hộp riêng lẻ.:

$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>

Các javascript chỉ là các hướng dẫn sắp xếp mặc định cơ bản

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

Có các phương thức có sẵn bằng cookie để lưu trạng thái nhưng tôi cũng cần phải vô hiệu hóa tính năng kéo và thả có thể sắp xếp cho người dùng không phải quản trị viên vì vậy tôi thực sự cần lưu vào cơ sở dữ liệu.

Tôi đang tìm kiếm phương pháp sáng tạo và có thể sử dụng nhất và sẽ trao phần thưởng 100 điểm cho câu trả lời hay nhất.

Cập nhật:

Tôi nhận được câu trả lời của somatic làm việc với một thay đổi nhỏ.

ajaxurl không trả về giá trị trên các trang không phải quản trị viên nên tôi đã sử dụng wp_localize_script( 'functions', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );để xác định giá trị và thay đổi dòng javascript theo các tùy chọn thành:
url: MyAjax.ajaxurl,

Để giới hạn quyền truy cập vào việc sắp xếp thứ tự chỉ quản trị viên, tôi đã thêm một điều kiện vào hàm wp_enqueue_script của mình:

    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' ) ) );
    }
}

Tôi sẽ làm thêm một chút kiểm tra và đánh dấu câu hỏi này là giải quyết và trao giải thưởng.


1
Có thể bạn có thể sử dụng menu_order trên bài viết? Tôi biết bạn có thể sử dụng chúng trên tệp đính kèm, vậy tại sao không đăng bài? nếu có thể thì đây là nơi bạn có thể lưu trữ thứ tự của bài viết ...
Brady

1
Có vẻ như bạn có thể - 'menu_order' - Sắp xếp theo thứ tự trang. Được sử dụng thường xuyên nhất cho Trang (Trường thứ tự trong hộp Chỉnh sửa thuộc tính trang) và cho tệp đính kèm (trường số nguyên trong hộp thoại Chèn / Tải lên thư viện phương tiện), nhưng có thể được sử dụng cho bất kỳ loại bài đăng nào có giá trị 'menu_order' riêng biệt (tất cả đều mặc định đến 0).
Brady

@Brady Ý tưởng tuyệt vời về việc sử dụng menu_order. @somatic mở rộng trên nó và nó hoạt động. Cảm ơn!
Chris_O

Câu trả lời:


21

Brady là chính xác rằng cách tốt nhất để xử lý lưu và hiển thị các đơn đặt hàng loại bài tùy chỉnh là sử dụng thuộc menu_ordertính

Đây là jquery để làm cho danh sách có thể sắp xếp và chuyển dữ liệu qua ajax sang 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);
        }
    }); 
});

Đây là chức năng wordpress lắng nghe cuộc gọi lại ajax và thực hiện các thay đổi trên DB:

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');

Chìa khóa để hiển thị các bài đăng theo thứ tự bạn đã lưu là thêm thuộc menu_ordertính vào truy vấn args:

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

$box_query = new WP_Query($args);

Sau đó chạy vòng lặp của bạn và xuất từng mục ... (dòng đầu tiên là hoạt hình tải wp lõi - bạn sẽ muốn ẩn nó ban đầu qua css, và sau đó chức năng jquery sẽ hiển thị khi xử lý)

<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>

Mã lấy cảm hứng từ hướng dẫn tuyệt vời của soulsizzle .


Câu trả lời tuyệt vời. Tôi sẽ cho nó một shot.
Chris_O

Cảm ơn bạn rất nhiều vì điều này - hoàn toàn giúp đỡ về một cái gì đó tôi đang làm việc quá. Một vấn đề tôi gặp phải là mỗi mục trong danh sách có thể sắp xếp cần phải có ID phù hợp với ID bài đăng. Đây là trong hướng dẫn của soulsizzle nhưng không phải trong bài viết của OP.
Dalton

Hoàn toàn đúng, Dalton, tôi đã quá ngắn gọn trong ví dụ của tôi. Mã cập nhật.
somatic

4

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

Chưa hoàn thành, nhưng ý tưởng là gửi yêu cầu ajax khi kéo và thả. Bạn cũng có thể muốn kích hoạt yêu cầu ajax chỉ sau khi nhấp vào nút "lưu" hoặc một cái gì đó. Một mảng chứa ID bài đăng và thứ tự mới sẽ được gửi.

Sau đó, bạn phải cập nhật các bài đăng trong cơ sở dữ liệu ở cuối máy chủ. Cuối cùng, thêm một ordertham số vào WP_Queryvòng lặp của bạn .

Tôi hy vọng điều này sẽ giúp bạn bắt đầu. Bất cứ ai cảm thấy tự do để tiếp tục nghịch ngợm.


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 );

Tập tin 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);
                }

                });

        }
    });

Xin đừng chỉ đổ mã. Bạn được yêu cầu thêm một số giải thích, tại sao nghĩ đoạn mã trên sẽ trả lời câu hỏi.
Hồi giáo Mayeenul

@MayeenulIslam Mô tả đã được thêm vào bên trong đoạn mã dưới dạng dòng nhận xét.
SkyRar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.