Bagaimana cara menyimpan status seret dan jatuhkan editor tata letak ujung depan jQuery UI Sortables?

20

Saya sedang membangun editor tata letak pos ujung depan menggunakan jQuery UI Sortable .

Posting diletakkan dalam kotak 300px x 250px di atas gambar latar belakang. Posting dibuat dan diedit menggunakan admin WordPress tetapi saya ingin mengizinkan administrator situs untuk menyesuaikan urutan kotak menggunakan antarmuka drag and drop di ujung depan.

Saya memiliki fungsi drag and drop sortable yang berfungsi tetapi perlu menemukan cara untuk menyimpan status (urutan) kotak. Idealnya saya ingin dapat menyimpan negara sebagai opsi dan membangunnya ke dalam kueri.

Permintaan untuk posting adalah WP_Query sederhana yang juga mendapatkan data dari kotak meta khusus untuk menentukan tata letak kotak individu .:

$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 hanyalah petunjuk dasar yang bisa diurutkan

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

Ada metode yang tersedia menggunakan cookie untuk menyimpan keadaan tetapi saya juga perlu menonaktifkan drag and drop sortable untuk pengguna non admin jadi saya benar-benar perlu menyimpan ke database.

Saya mencari metode yang paling kreatif dan dapat digunakan dan akan memberikan hadiah 100 poin untuk jawaban terbaik.

Memperbarui:

Saya mendapat jawaban somatic bekerja dengan satu perubahan kecil.

ajaxurl tidak mengembalikan nilai pada halaman non admin jadi saya biasa wp_localize_script( 'functions', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) );mendefinisikan nilainya dan mengubah baris javascript di bawah opsi menjadi:
url: MyAjax.ajaxurl,

Untuk membatasi akses ke mengatur agar hanya admin, saya menambahkan sebuah kondisional ke fungsi wp_enqueue_script saya:

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

Saya akan melakukan sedikit lebih banyak pengujian dan menandai pertanyaan ini sebagai diselesaikan dan memberi hadiah.

Chris_O
sumber
1
Apakah mungkin Anda dapat menggunakan menu_order pada posting? Saya tahu Anda bisa menggunakannya pada lampiran jadi mengapa tidak memposting? jika memungkinkan di sinilah Anda dapat menyimpan urutan posting ...
Brady
1
Sepertinya Anda bisa - 'menu_order' - Dipesan berdasarkan Pesanan. Paling sering digunakan untuk Halaman (bidang Pesanan dalam kotak Edit Halaman Atribut) dan untuk lampiran (bidang bilangan bulat dalam dialog Sisipkan / Unggah Galeri Media), tetapi dapat digunakan untuk semua jenis posting dengan nilai 'menu_order' yang berbeda (semuanya default ke 0).
Brady
@ Brady Ide bagus tentang penggunaan menu_order. @somatis diperluas dan berhasil. Terima kasih!
Chris_O

Jawaban:

21

Brady benar bahwa cara terbaik untuk menangani penyimpanan dan penayangan pesanan jenis pos khusus adalah dengan menggunakan menu_orderproperti

Inilah jquery untuk membuat daftar dapat diurutkan dan untuk meneruskan data melalui ajax ke 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);
        }
    }); 
});

Inilah fungsi wordpress yang mendengarkan panggilan balik ajax dan melakukan perubahan pada 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');

Kunci untuk menampilkan posting dalam urutan yang telah Anda simpan adalah menambahkan menu_orderproperti ke argumen permintaan:

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

$box_query = new WP_Query($args);

Kemudian jalankan loop dan output setiap item ... (baris pertama adalah animasi inti pemuatan wp - Anda akan ingin menyembunyikannya pada awalnya melalui css, dan kemudian fungsi jquery akan ditampilkan saat memproses)

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

Kode terinspirasi oleh tutorial luar biasa soulsizzle .

somatik
sumber
Jawaban yang sangat bagus. Saya akan mencobanya.
Chris_O
Terima kasih banyak untuk ini - benar-benar membantu sesuatu yang sedang saya kerjakan juga. Satu masalah yang saya hadapi adalah bahwa setiap item dalam daftar sortir perlu memiliki ID yang cocok dengan ID posting. Ini dalam tutorial soulsizzle tetapi tidak di pos OP.
Dalton
Benar sekali, Dalton, saya terlalu singkat dalam contoh saya. Kode diperbarui.
somatik
4

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

Jauh dari selesai, tetapi idenya adalah mengirim permintaan ajax pada drag dan drop. Anda juga mungkin ingin memicu permintaan ajax hanya setelah mengklik tombol "simpan" atau sesuatu. Array yang berisi ID pos dan pesanan baru akan dikirim.

Maka Anda harus memperbarui posting di database di ujung server. Akhirnya, tambahkan orderparameter ke WP_Queryloop Anda .

Saya harap ini memulainya. Siapa pun merasa bebas untuk terus mengutak-atik.

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

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

                });

        }
    });
SkyRar
sumber
Tolong jangan hanya membuang kode. Anda diminta untuk menambahkan beberapa penjelasan, mengapa berpikir kode di atas akan menjawab pertanyaan.
Mayeenul Islam
@MayeenulIslam Deskripsi telah ditambahkan di dalam cuplikan kode sebagai baris komentar.
SkyRar