วิธีบันทึกสถานะของตัวแก้ไขโครงร่างด้านหน้าของ jQuery UI Sortables ส่วนหน้า?


20

ฉันกำลังสร้างแก้ไขส่วนหน้าโพสต์รูปแบบการใช้jQuery UI การจัดเรียง

โพสต์มีการจัดวางในกล่องขนาด 300px x 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>

จาวาสคริปต์เป็นเพียงคำแนะนำพื้นฐานในการเรียงลำดับเริ่มต้น

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

มีวิธีการใช้คุกกี้เพื่อบันทึกสถานะ แต่ฉันต้องปิดการใช้งานการลากและวางแบบเรียงลำดับสำหรับผู้ใช้ที่ไม่ใช่ผู้ดูแลระบบดังนั้นฉันจึงต้องบันทึกลงในฐานข้อมูลจริงๆ

ฉันกำลังมองหาวิธีที่สร้างสรรค์และใช้งานได้มากที่สุดและจะมอบรางวัล 100 แต้มให้กับคำตอบที่ดีที่สุด

ปรับปรุง:

ฉันได้รับคำตอบของโซมาติกที่ทำงานกับการเปลี่ยนแปลงเล็กน้อย

ajaxurl ไม่ได้คืนค่าในหน้าผู้ดูแลระบบดังนั้นฉันจึงใช้wp_localize_script( 'functions', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );เพื่อกำหนดค่าและเปลี่ยนบรรทัดจาวาสคริปต์ภายใต้ตัวเลือกเพื่อ:
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' - สั่งซื้อตามลำดับของหน้า ใช้บ่อยที่สุดสำหรับหน้า (ฟิลด์คำสั่งซื้อในกล่องแก้ไขแอททริบิวหน้า) และสิ่งที่แนบมา (ฟิลด์จำนวนเต็มในกล่องโต้ตอบแทรก / อัปโหลดแกลเลอรีสื่อบันทึก) แต่สามารถใช้กับประเภทโพสต์ใด ๆ ถึง 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:

$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

ขอบคุณมากสำหรับสิ่งนี้ - ช่วยเหลืออย่างเต็มที่กับสิ่งที่ฉันกำลังทำอยู่ ปัญหาหนึ่งที่ฉันเจอคือแต่ละรายการในรายการที่เรียงลำดับได้ต้องมี ID ที่ตรงกับรหัสโพสต์ นี่คือการสอนของ Soulsizzle แต่ไม่ได้อยู่ในโพสต์ของ OP
ดาลตัน

ใช่แล้วดัลตันฉันเป็นแบบอย่างสั้นเกินไป อัปเดตรหัสแล้ว
โซมาติก

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

                });

        }
    });

โปรดอย่าเพิ่งถ่ายโอนรหัส คุณถูกขอให้เพิ่มคำอธิบายทำไมคิดว่ารหัสข้างต้นจะตอบคำถาม
Mayeenul Islam

@MayeenulIslam คำอธิบายได้ถูกเพิ่มไว้ในตัวอย่างโค้ดเป็นบรรทัดความคิดเห็น
SkyRar
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.