드래그 앤 드롭 jQuery UI Sortables 프론트 엔드 레이아웃 편집기의 상태를 저장하는 방법은 무엇입니까?


20

jQuery UI Sortable을 사용하여 프런트 엔드 포스트 레이아웃 편집기를 작성 중 입니다.

게시물은 배경 이미지 위에 300 x 250 픽셀의 상자에 배치됩니다. 게시물은 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' ) ) );을 정의하고 옵션 아래의 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를 사용할 수 있습니까? 첨부 파일에 사용할 수 있으므로 게시물을 작성하지 않는 이유는 무엇입니까? 가능하다면 게시물 순서를 저장할 수 있습니다 ...
Brady

1
'menu_order'-페이지 순서로 정렬 할 수 있습니다. 페이지 (페이지 속성 편집 상자의 주문 필드) 및 첨부 파일 (미디어 삽입 / 업로드 갤러리 대화 상자의 정수 필드)에 가장 많이 사용되지만 고유 한 'menu_order'값 (모든 기본값)이있는 모든 게시물 유형에 사용할 수 있습니다. 0).
Brady

@Brady menu_order 사용에 대한 좋은 아이디어. @ somatic이 확장되어 효과가있었습니다. 감사!
Chris_O

답변:


21

Brady는 맞춤 게시물 유형 주문의 저장 및 표시를 처리하는 가장 좋은 방법은 menu_order속성 을 사용하는 것입니다.

다음은 목록을 정렬하고 ajax를 통해 데이터를 wordpress에 전달하는 jquery입니다.

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

다음은 ajax 콜백을 수신하고 DB에서 변경을 수행하는 wordpress 함수입니다.

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

그런 다음 루프를 실행하고 각 항목을 출력하십시오 ...

<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와 일치하는 ID가 있어야한다는 것입니다. 이것은 soulsizzle의 자습서에 있었지만 OP의 게시물에는 없었습니다.
Dalton

당연 하죠, 달튼, 저는 제 예제에서 너무 짧았습니다. 코드가 업데이트되었습니다.
체세포

4

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

완료와는 거리가 멀지 만 드래그 앤 드롭으로 아약스 요청을 보내는 것이 좋습니다. "저장"버튼이나 다른 것을 클릭 한 후에 만 ​​아약스 요청을 트리거 할 수도 있습니다. 게시물 ID와 새로운 주문이 포함 된 배열이 전송됩니다.

그런 다음 서버 쪽 데이터베이스의 게시물을 업데이트해야합니다. 마지막으로 루프에 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 );

자바 스크립트 파일 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 이슬람

@MayeenulIslam Description은 코드 스 니펫 안에 주석 행으로 이미 추가되었습니다.
SkyRar
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.