Comment sauvegarder l'état d'un glisser-déposer éditeur de mise en page de l'extrémité avant jQuery UI Sortables?

wordpress.stackexchange https://wordpress.stackexchange.com/questions/16342

  •  16-10-2019
  •  | 
  •  

Question

Je construis un éditeur de poste frontal de mise en page en utilisant jQuery UI Sortable .

Les postes sont disposés dans des boîtes 300 x 250 pixels sur une image d'arrière-plan. Les postes sont créés et modifiés à l'aide de l'administrateur WordPress, mais je veux permettre à l'administrateur du site pour ajuster l'ordre des cases à l'aide d'une interface glisser-goutte à l'extrémité avant.

J'ai le glisser-déposer triables travail partiel mais qui ont besoin de trouver un moyen de sauver l'état (ordre) des boîtes. Idéalement, je voudrais être en mesure d'enregistrer l'état en option et construire dans la requête.

La requête pour les postes est une WP_Query de simple qui obtient également des données de boîtes de méta personnalisées pour déterminer la mise en page de boîte individuelle:.

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

Le javascript est juste les instructions triables par défaut de base

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

Il existe des méthodes disponibles à l'aide les cookies pour sauver l'État, mais je dois aussi désactiver le triables glisser-déposer pour les utilisateurs non admin, donc je vraiment besoin d'enregistrer dans la base de données.

Je cherche la méthode la plus créative et utilisable et attribuera une prime de 100 points à la meilleure réponse.

Mise à jour:

Je suis somatiques de travail de réponse avec un changement mineur.

ajaxurl ne retourne pas la valeur sur des pages non admin si je wp_localize_script( 'functions', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); pour définir la valeur et changé la ligne de javascript dans les options pour:
url: MyAjax.ajaxurl,

Pour limiter l'accès à l'organisation de l'ordre pour que j'admins ajouté une condition à ma fonction 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' ) ) );
    }
}

Je vais faire un peu plus de tester et marquer cette question comme résolue et l'attribution de la prime.

Était-ce utile?

La solution

Brady est exact que la meilleure façon de gérer l'enregistrement et l'affichage des commandes de type poste personnalisé est en utilisant la propriété menu_order

Voici le jquery pour faire la liste triables et de transmettre les données via 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);
        }
    }); 
});

Voici la fonction wordpress qui écoute le rappel ajax et effectue les changements sur la base de données:

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

La clé pour afficher les messages dans l'ordre que vous avez enregistré est d'ajouter la propriété menu_order aux args de la requête:

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

$box_query = new WP_Query($args);

Ensuite, exécutez votre boucle et sortie chaque élément ... (première ligne est le noyau animation de chargement wp - vous aurez envie de le cacher d'abord via css, puis la fonction jquery affichera lors du traitement)

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

code inspiré par l'excellent soulsizzle tutoriel .

Autres conseils

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

Loin d'être terminé, mais l'idée est d'envoyer une demande de paiement ajax sur le glisser-déposer. Vous pouvez également déclencher la demande ajax seulement après avoir cliqué sur un bouton « enregistrer » ou quelque chose. Un tableau contenant les ID poste et nouvel ordre sera envoyé.

Ensuite, vous auriez à mettre à jour les messages dans la base de données sur la fin du serveur. Enfin, ajoutez un paramètre order à votre boucle WP_Query.

J'espère que cela vous permet de démarrer. Tout le monde se sentent libres de continuer tripoter.

/**
 *  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 fichier Javascript

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

                });

        }
    });
Licencié sous: CC-BY-SA avec attribution
Non affilié à wordpress.stackexchange
scroll top