如何保存一个拖放状态的jQuery UI可排序前端布局编辑器?

时间:2011-05-04 作者:Chris_O

我正在使用jQuery UI Sortable.

这些柱子在背景图像上以300px×250px的方框布置。这些帖子是使用WordPress管理员创建和编辑的,但我想让网站管理员使用前端的拖放界面来调整框的顺序。

我已经让拖放排序部分工作,但需要想出一种方法来保存框的状态(顺序)。理想情况下,我希望能够将状态保存为选项并将其构建到查询中。

帖子的查询是一个简单的WP\\U查询,它还从自定义元框中获取数据,以确定单个框的布局

$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();
  });
可以使用以下方法cookies 要保存状态,但我还需要禁用非管理员用户的可排序拖放,因此我确实需要保存到数据库。

我正在寻找最有创意和最实用的方法,并将奖励100分奖励给最佳答案。

更新:

我得到somatic\'s 回答一个小改动。

ajaxurl在非管理页面上不返回值,因此我使用wp_localize_script( \'functions\', \'MyAjax\', array( \'ajaxurl\' => admin_url( \'admin-ajax.php\' ) ) ); 定义值并将选项下的javascript行更改为:
url: MyAjax.ajaxurl,

为了将安排订单的权限限制为仅管理员,我在wp\\u enqueue\\u脚本函数中添加了一个条件:

    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\' ) ) );
    }
}
我将做更多的测试,并将此问题标记为已解决,然后授予悬赏。

3 个回复
最合适的回答,由SO网友:somatic 整理而成

Brady是正确的,处理保存和显示自定义post类型订单的最佳方法是使用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);
        }
    }); 
});
下面是wordpress函数,它侦听ajax回调并对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\');
按保存顺序显示帖子的关键是添加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的代码excellent tutorial.

SO网友:Geert

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

虽然还远未完成,但其想法是通过拖放发送ajax请求。您可能还希望仅在单击“保存”按钮或其他按钮后触发ajax请求。将发送一个包含post ID和新订单的数组。

然后,您必须更新服务器端数据库中的帖子。最后,添加order 您的WP_Query

我希望这能让你开始。任何人都可以继续摆弄。

SO网友:SkyRar

/**
 *  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文件顺序。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);
                }

                });

        }
    });

结束

相关推荐

将jQuery UI数据选取器添加到管理面板

我创建了一个自定义帖子类型,其中包含两个字段,用户可以在其中输入项目的开始日期和结束日期。我试图实现jQuery datepicker,但当我使用1.7.3单击输入字段时,什么都没有发生;如果我使用1.8,它会抛出一个错误$(input).zIndex is not a function更新时间:下面是函数 function webfolio_show_timespan_box(){ ?> <script type=\"text/javascript\" src=\"