Comment enregistrer l'état d'un éditeur de disposition frontal jQuery UI Sortables?

19

Je construis un éditeur de disposition de publication front-end à l'aide de jQuery UI Sortable .

Les messages sont disposés dans des boîtes de 300 pixels par 250 pixels sur une image d’arrière-plan. Les publications sont créées et modifiées à l’aide de l’administrateur de WordPress, mais je veux permettre à l’administrateur du site d’ajuster l’ordre des boîtes à l’aide d’une interface glisser-déposer au front-end.

J'ai la partie triable par glisser-déposer qui fonctionne mais je dois trouver un moyen de sauvegarder l'état des boîtes. Idéalement, j'aimerais pouvoir enregistrer l'état en tant qu'option et l'intégrer à la requête.

La requête pour les publications est un simple WP_Query qui récupère également des données à partir de méta-boîtes personnalisées pour déterminer la présentation de chaque boîte.:

$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 n'est que les instructions de base triables par défaut

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

Il existe des méthodes disponibles utilisant les cookies pour enregistrer l'état, mais je dois également désactiver le glisser-déposer pouvant être trié les utilisateurs admin donc j'ai vraiment besoin d'enregistrer dans la base de données.

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

Mise à jour:

La réponse de somatic a fonctionné avec un changement mineur.

ajaxurl ne renvoyant pas la valeur sur les pages non admin, j'ai donc utilisé wp_localize_script( 'functions', 'MyAjax', array( 'ajaxurl' => admin_url( 'admin-ajax.php' ) ) ); pour définir la valeur et modifié la ligne javascript sous options en:
url: MyAjax.ajaxurl,

Pour limiter l'accès à la commande aux seuls administrateurs, j'ai 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 tests et marquer cette question comme résolue et attribuer la prime.

    
posée Chris_O 04.05.2011 - 16:12

2 réponses

21

Brady a raison de dire que l'utilisation de la propriété menu_order est la meilleure façon de gérer la sauvegarde et l'affichage des commandes de type publication personnalisées

.

Voici le jQuery pour rendre la liste triable et pour 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 modifications sur le 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');

Pour afficher les publications dans l'ordre que vous avez sauvegardé, vous devez ajouter la propriété menu_order aux arguments 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, lancez votre boucle et affichez chaque élément ... (la première ligne est l’animation de chargement wp - vous voudrez le cacher initialement via css, puis la fonction jquery s’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é de excellent tutoriel de soulsizzle .

    
réponse donnée somatic 06.05.2011 - 23:26
4

enlace

Loin d’être terminé, mais l’idée est d’envoyer une demande ajax par glisser-déposer. Vous pouvez également vouloir déclencher la demande ajax uniquement après avoir cliqué sur un bouton "Enregistrer" ou quelque chose du genre. Un tableau contenant les identifiants de poste et le nouvel ordre sera envoyé.

Ensuite, vous devrez mettre à jour les publications de la base de données côté serveur. Enfin, ajoutez un paramètre order à votre boucle WP_Query .

J'espère que cela vous aide à démarrer. N'importe qui peut continuer à jouer au violon.

    
réponse donnée Geert 04.05.2011 - 17:04

Lire d'autres questions sur les étiquettes