2017-09-05 1 views
1

Actuellement dans mon système, via CakePHP 3, une recherche dans une base de données MySQL est effectuée pour rechercher une liste de photos utilisées dans un slideshow plugin. L'utilisateur choisit les photos à utiliser dans le diaporama et peut ajouter ou supprimer des photos du diaporama. Cependant, ils ne peuvent pas actuellement choisir l'ordre dans lequel le diaporama affiche ces photos.CakePHP 3 - Permettre à l'utilisateur d'affecter et de modifier une commande à une requête d'enregistrements

Dans le contrôleur, la requête ressemble à ceci:

$imagesUsed = $this->Gallery->find('all',[ 
    'conditions' => ['status' => 'shown', 'type' => 'image'] 
])->toArray(); 

Sur la page pour afficher le diaporama:

<script> 
    $(function() { 
     jQuery(document).ready(function() { 
      $('#header').backstretch([ 
       <?php foreach ($imagesUsed as $image){ ?> 
       "<?= $host.$basepath ?>/webroot/uploads/<?= $image->link ?>", 
       <?php } ?> 
      ], {duration: 2000, fade: 750}); 
     }); 
    }); 
</script> 

Je me demandais comment attribuer des numéros aux photos du diaporama requêtés pour afficher la commande clairement à l'utilisateur, et aussi leur permettre de changer cette commande. Par exemple:

  • Un diaporama de fruits contient actuellement une image Apple (1) et une image Banana (2).
  • L'utilisateur veut alors télécharger une image Peach pour le diaporama, mais ne veut pas qu'il soit ajouté en tant que 3ème image, à la place, il souhaite que Peach soit la première image. Ils ne veulent pas avoir à supprimer toutes les images du diaporama, puis rajouter les images dans le bon ordre.

Mise à jour: J'ai ajouté une colonne custom_sort dans la table DB. J'ai également créé un formulaire avec une boucle foreach et un menu déroulant qui inclut une fonction JavaScript onchange lorsqu'une option est sélectionnée. J'ai du mal à trouver un moyen de rejoindre les deux ensemble.

forme avec boucle foreach (incomplète):

<?php $this->Form->create($gallery) ?> 
<legend><?= __('Update Image Order') ?></legend> 
<fieldset> 
    <div class="container col-sm-12"> 
     <?php foreach ($galleries as $gallery): ?> 
      <div class="col-sm-4"> 
       <?php echo $this->Form->input('link',['class' => 'form-control', 'readonly']); ?> 
      </div> 
      <div class="col-sm-4"> 
       <?php echo $this->Form->input('name',['class' => 'form-control', 'readonly']); ?> 
      </div> 
      <div class="col-sm-2"> 
       <?php echo $this->Form->input('page', ['class' => 'form-control', 'readonly']); ?> 
      </div> 
      <div class="col-sm-2"> 
       <?php echo $this->Form->input('custom_sort', ['label' => 'Slideshow Order', 'class' => 'form-control']); ?> 
      </div> 
     <?php endforeach ?> 
    </div> 
</fieldset> 
<div style="text-align: center"> 
    <?php echo $this->Form->button(__('Submit'), ['class' => 'btn btn-secondary btn-xl page-scroll']) ?> 
</div> 
<?php $this->Form->end() ?> 

Et dans le contrôleur:

public function updateorder() 
{ 
    $galleries = $this->Galleries->find('all',[ 
     'conditions' => ['status' => 'shown', 'type' => 'image'], 
     'order' => ['custom_sort' => 'ASC'] 
    ])->toArray(); 

    if ($this->request->is(['patch', 'post', 'put'])) { 
     $galleries = $this->Galleries->patchEntities($galleries, $this->request->data); 
     if ($this->Galleries->updateAll([$galleries], [])) { 
      $this->Flash->success(__('The image slideshow orders have been updated.')); 

      return $this->redirect(['action' => 'managemedia']); 
     } else { 
      $this->Flash->error(__('The image slideshow orders could not be updated. Please, try again.')); 
     } 
    } 
    $this->set(compact('galleries')); 
    $this->set('_serialize', ['galleries']); 
} 

Dropdown Sélectionnez et JavaScript onchange fonction (incomplète):

<label for="page" id="pageLabel" style="text-align: left">Page</label> 
<select name="page" id="page" onchange="changePage()" class="form-control"> 
    <option value="" disabled selected hidden>Select a page</option> 
    <option value="Home">Home</option> 
    <option value="Fruits">Fruits</option> 
    <option value="Vegetables">Vegetables</option> 
</select> 

<script> 
function changePage() { 
    var pageChoice = document.getElementById('page'); 
    var selectedPageChoice = pageChoice.options[pageChoice.selectedIndex].value; 
    $.ajax({ 
     url: "<?= $host . $basepath ?>/gallery.json", 
     type: 'POST', 
     success: function (res) { 
      console.log(res); 
     } 
    }) 
} 
</script> 

console.log(res) me montre ceci dans la console du navigateur:

> Object 
    > galleries: Array (x) //galleries being the array variable set in the AJAX request URL, Array (x) referring to the number of elements in that array. 
    > 0: {id: 1, link: "images/apples.jpg", name: "Apple", page: "Fruits", custom_sort: 1} 
    > 1: {id: 2, link: "images/banana.jpg", name: "Banana", page: "Fruits", custom_sort: 2} 
    > 2: {id: 3, link: "images/pumpkin.jpg", name: "Pumpkin", page: "Vegetables", custom_sort: 1} 
    > 3: {id: 4, link: "images/peach.jpg", name: "Peach", page: "Fruits", custom_sort: 3} 

je peux récupérer une valeur unique de cette façon:

console.log(res.galleries.0.link); imprimerait Peach dans la console.

Actuellement, le formulaire affiche 4 doublons d'entrées de formulaire (égal au nombre d'entrées existantes), bien qu'ils soient tous vides.

Répondre

0

Vous pouvez utiliser jQuery UI Sortable (http://jqueryui.com/sortable/). Vous pouvez sérialiser votre ordre de tri lors de la publication et mettre à jour votre base de données avec une requête AJAX.

+0

Pas exactement ce que je suis après - il est plus d'un: je peux entrer un nouveau numéro pour le point 3 pour en faire l'article 1. Toutes les images sont affichées dans une table, pas une liste HTML comme la démo - Comme il y a plusieurs bobines de diaporamas, chacune avec leurs propres séquences, faire glisser des rangées de tables serait très déroutant. – mistaq

+0

Pour clarifier, je veux dire que l'utilisateur sélectionne les images pour des diaporamas spécifiques à partir d'une table qui montre toutes les images. – mistaq

0

J'ai l'habitude d'ajouter une colonne appelée sortable ou custom_sort dans la base de données.

Vous pouvez donner à l'utilisateur une entrée pour spécifier sa propre commande.

Votre requête ressemblerait à ceci.

// Notice I call Galleries. This may not be right for you, 
// but cake convention is plural table names 
// I also use where() instead of conditions. This is also a suggestion 
$images = $this->Galleries->find('all') 
    ->where(['status' => 'shown', 'type' => 'image']) 
    ->order(['custom_sort' => 'ASC']); 

Je voudrais aussi suggérer au lieu d'appeler toArray vous situé juste à la variable serialize

$this->set(['images' => $images]); 
$this->set('_serialize', 'images'); 

Et assurez-vous que votre demande attend JSON

$.ajax({dataType:'json'}); 

Présentation de l'Ordre Mise à jour

Lors de la mise à jour les images que vous pouvez faire une mise à jour de masse en supposant que vos données affichées ressemblent à ceci.

$requestData = [ 
    [ 
     'id' => 100, 
     'custom_sort' => 1, 
    ], 
    [ 
     'id' => 200, 
     'custom_sort' => 2, 
    ], 
    [ 
     'id' => 300, 
     'custom_sort' => 3, 
    ] 
]; 

Vous pouvez enregistrer les données rapidement comme ce

$galleries = $this->Galleries->newEntities($requestData); 
// This does not call callbacks (beforeSave, afterSave) 
$this->Galleries->updateAll($galleries); 

Modifier basé sur la Question

Mise à jour plusieurs enregistrements pourrait ressembler à quelque chose comme ça.

Dans votre boucle de sortie à travers vos images

<?php foreach($images as $image): ?> 
    <input data-image_id="<?= $image->id; ?>" class="image-custom-sort" value="<?= $image->custom_sort; ?>" /> 
<?php endforeach; ?> 
<button onClick="handleSubmit">Save Sort Order</button> 

Puis javascript. Cela fait un moment que j'ai écrit Jquery pour que certaines de ces pièces soient erronées mais cela devrait vous donner une idée. Ne copiez pas et ne collez pas ce code ci-dessous car je ne pense pas qu'il fonctionnera tel quel.

function handleSubmit(e){ 
    var inputs = $('input.image-custom-sort'); 
    var data = []; 
    $.each(inputs, function (input) { 
     data.push({ 
      id: input.dataset.image_id 
      custom_sort: $(input).val() 
     }) 
    }); 

    $.ajax({ 
     dataType: 'json', 
     data: data 
    }) 
} 
+0

À quoi ressemblerait le formulaire pour une mise à jour de données multiples? Aurais-je besoin d'utiliser une instruction foreach? Je n'ai jamais vraiment fait de mise à jour de données multiples auparavant, donc tout ceci est plutôt nouveau pour moi. De plus, j'ai une liste déroulante supplémentaire qui permet de basculer entre les enregistrements (par exemple, choisir Fruits dans la liste déroulante bascule toutes les images Fruit uniquement). Je pensais utiliser une fonction JS onchange, puis utiliser une requête AJAX pour extraire les données appropriées de la BD, mais encore une fois, je ne sais pas comment obtenir plusieurs enregistrements et leurs valeurs hors du rappel de succès (je peux en obtenir un). – mistaq

+0

@mistaq - J'ai mis à jour ma réponse avec une solution possible. – styks