[RESOLU] Fonction Drag and Drop pour gérer les photos d'une annonce

Eléphanteau du PHP | 38 Messages

24 févr. 2015, 17:18

Bonjour à tous,

Le site est terminé (ou presque) en frontal :D
Mais je souhaiterais améliorer un peu le fonctionnement de la gestion des photos d'une annonce en backend.

Je m'explique, voici ci-dessous comment ça se présente et le code associé.
gestion_photos.jpg
            <table cellpadding="4" cellspacing="1" border="0" width="100%" class="adminform form_14">
                <tr>
                    <td colspan="2"><h2><?php echo _REALESTATE_MANAGER_HEADER_PHOTO_MANAGE; ?></h2></td>
                </tr>
                <tr>
                    <td valign="top"><?php echo _REALESTATE_MANAGER_LABEL_PICTURE_URL_UPLOAD; ?>:</td>
                    <td align="left"><input class="inputbox" type="file" name="image_link" value="<?php echo $row->image_link; ?>" size="50" maxlength="250" /></td>
                </tr>
                <tr>
                    <?php if ($house_photo != '') {
                        ?>	<?php if(!$row->id_true): ?>
                        <td valign="bottom"><?php echo _REALESTATE_MANAGER_LABEL_SELECT_PHOTO_TO_REMOVE; ?>:</td>
                        <?php else:?>
                        <td>&nbsp</td>
                        <?php endif; ?>
                        <td> <?php if(!$row->id_true): ?>
                            <input type="checkbox" name="del_main_photo" value="<?php echo $house_photo[0]; ?>" />
                            <?php endif; ?>
                            <img alt="photo" src="<?php echo $mosConfig_live_site . "/components/com_realestatemanager/photos/" . $house_photo[1]; ?>"/>
                        </td>
                    <?php } else echo '<td>&nbsp</td>'; ?>				
                </tr>
                <tr>
                    <td valign="top"> <?php echo _REALESTATE_MANAGER_LABEL_OTHER_PICTURES_URL_UPLOAD; ?>:</td>
                    <td align="left">
                        <div ID="items">
                            <input class="inputbox" type="button" name="new_photo" 
                                   value="<?php echo 'Add new photo'; ?>" onClick="new_photos()" ID="add"/>
                        </div>
                    </td>
                </tr>

                <?php if (count($house_photos) != 0) {
                    ?>
                    <tr>
                        <td valign="center"><?php echo _REALESTATE_MANAGER_LABEL_SELECT_PHOTO_FROM_GALLERY; ?>:</td>
                        <td valign="top" align="right">
                            <?php
                            for ($i = 0; $i < count($house_photos); $i++) {
                                if (($i % 7) == 0) {
                                    echo "<br>";
                                }
                                ?>
                                <input type="checkbox" name="del_photos[]" value="<?php echo $house_photos[$i][0]; ?>" />
                                <img src="<?php echo $mosConfig_live_site . "/components/com_realestatemanager/photos/" . $house_photos[$i][1]; ?>" alt="no such file"/> &nbsp
                            <?php } ?>
                        </td>
                    </tr>
                <?php } ?>
Ma requête est toute simple, comment puis-je faire pour avoir une fonction type Drag and Drop sur les photos de la galerie, ce qui me permettrais de les déplacer entre elles au besoin. Car il nous arrive de reprendre des photos dans des conditions météo plus favorables, et donc une fonction D&D m'éviterais d'avoir à tout supprimer pour les remettre dans l'ordre souhaité.

Merci d'avance
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.

Mammouth du PHP | 688 Messages

24 févr. 2015, 17:40

si tu as une base de donnée avec le nom des photos dedans, tu ajoutes un champ de tri pour chaque photo, et tu permets de mettre à jour la valeur de tri.

Eléphanteau du PHP | 38 Messages

26 févr. 2015, 10:59

Bonjour, merci pour la réponse,
Effectivement en base, j'ai toutes mes photos, elle se présente ainsi :

Image

Image

Qu'entend tu par "tu ajoutes un champ de tri pour chaque photo, et tu permets de mettre à jour la valeur de tri" ?

ViPHP
ViPHP | 928 Messages

27 févr. 2015, 01:16

Pour déplacer des photos entre elles : http://jqueryui.com/sortable/

Eléphanteau du PHP | 38 Messages

27 févr. 2015, 12:35

Bonjour, merci pour le lien, j'ai testé plusieurs tuto mais sans succès, avec celui-ci je suis sur la bonne piste :D

Mais je rencontre un problème, car le code initial charge toutes les photos à la suite, j'ai donc un bloc <ul><li> par photo au lieu de un bloc <ul> pour l'ensemble et un <li> par photo.

Comment puis faire pour que toutes les photos se placent dans un même bloc <ul> et individuellement dans un <li>, sachant qu'en base, les champs id, fk_houseid sont attribués automatiquement, et un préfixe aléatoire est ajouté au nom de la photo puisque j'importe les photos nommées ainsi : réf_1, réf_2 ... (ex: 16050_1, 16050_3 ...)

Code php :
	
<ul id="sortable_perso">
       <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
              <input type="checkbox" name="del_photos[]" value="<?php echo $house_photos[$i][0]; ?>" />
              <img src="<?php echo $mosConfig_live_site . "/components/com_realestatemanager/photos/" . $house_photos[$i][1]; ?>" style="height:100px;" alt="no such file"/>
       </li>
</ul>
Aperçut :
Image

En examinant l'élément :
<ul id="sortable_perso">
       <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
              <input name="del_photos[]" value="6851E4F9-27F8-3117-521C-53EE472AFD28_16050_1.jpg" type="checkbox">
              <img src="/joomla_agence_2/components/com_realestatemanager/photos/6851E4F9-27F8-3117-521C-53EE472AFD28_16050_1.jpg" style="height:100px;" alt="no such file">
       </li>
</ul>
<ul id="sortable_perso">
       <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
              <input name="del_photos[]" value="D80C8829-539B-48A6-28B4-96EBAC271BBB_16050_3.jpg" type="checkbox">
              <img src="/joomla_agence_2/components/com_realestatemanager/photos/D80C8829-539B-48A6-28B4-96EBAC271BBB_16050_3.jpg" style="height:100px;" alt="no such file">
       </li>
</ul>

ViPHP
ViPHP | 928 Messages

27 févr. 2015, 15:32

Pas de soucis pour ton HTML, l'idée c'est qu'il te faut un conteneur, et que chaque enfant de ce conteneur HTML soit ce que tu veux bouger.

Donc en gros si tu as ce HTML :
<div id="mon-conteneur">
   <ul><li>...</li></ul>
   <ul><li>...</li></ul>
   <ul><li>...</li></ul>
</div>
Il suffit de faire ça pour le plugin :
[javascript]$('#mon-conteneur').sortable();[/javascript]

Et il utilisera les <ul> (les enfants directs de #mon-conteneur) pour les trier entre eux.

Eléphanteau du PHP | 38 Messages

22 mai 2015, 18:33

Bonjour Genova, je viens seulement de me repencher sur mon problème de Drag and Drop. J'ai été affairé à terminer la partie frontend pour le mettre en ligne sur son domaine définitif.

Maintenant que c'est fait je me me remets à améliorer le backoffice :)

Merci de ta réponse. Du coup j'obtiens code suivant :
<div class="adminform form_14">
	<?php echo _REALESTATE_MANAGER_LABEL_SELECT_PHOTO_FROM_GALLERY; ?>:
</div>

<div id="sortable_galerie">
   <?php
      for ($i = 0; $i < count($house_photos); $i++) {
      if (($i % 7) == 0) {
      echo "<br>";
    } ?>
							
     <ul id="sortable_perso">
        <li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
           <input type="checkbox" name="del_photos[]" value="<?php echo $house_photos[$i][0]; ?>" />
           <img src="<?php echo $mosConfig_live_site . "/components/com_realestatemanager/photos/" . $house_photos[$i][1]; ?>" style="height:100px;" alt="no such file"/>
        </li>
     </ul>
   <?php } ?>
</div>
Et ça fonctionne, je peux glisser mes photos. Mais quand j'enregistre, il me remet les photos dans l'ordre initial .... il doit y avoir quelque part un tri automatique, je ne l'ai pas encore trouvé.

Avatar du membre
Mammouth du PHP | 1609 Messages

22 mai 2015, 18:55

Bonjour Magalux, quand tu modifies l'ordre des photos en drag'n drop dans la page, à aucun moment ça n'enregistre cet ordre (où serait-il mémorisé ?). C'est à toi de le faire.

C'est pourquoi il faut, comme le suggérait tof73 que tu ajoutes une colonne d'ordre à ta table. Tu pourras ainsi ajouter un order by sur la requête de sélection des images afin qu'elles soient triées dans l'ordre mémorisé.

Pour mémoriser cet ordre, il faut que tu utilises par exemple l'event change de jquery sortable afin d'appeler un script php auquel tu soumettras l'ordre des images afin de mettre à jour leur colonne d'ordre.
http://api.jqueryui.com/sortable/#event-change
Développeur web depuis + de 20 ans

Eléphanteau du PHP | 38 Messages

23 mai 2015, 11:29

Bonjour Saian, comment dois-je paramétrer ma colonne d'ordre ? (ex : Name : "Position", Type : "int(11)", ...)

Pour mémoriser l'ordre, il suffirait juste d'ajouter ce bout de code :
$( ".selector" ).sortable({
  change: function( event, ui ) {}
});
Je dois le personnaliser de la façon suivante ?
$( "#sortable_galerie" ).sortable({
  change: function( change, position ) {}
});
Merci de ton aide

Avatar du membre
Mammouth du PHP | 1609 Messages

23 mai 2015, 13:09

Pour la colonne position c'est bien. Un tinyint unsigned suffirait je pense (0 à 255).

Sinon avec ce code pour l'event change oui ça va bien appeler la fonction mais cette dernière ne fait rien :
change: function( change, position ) { // il faudrait faire quelque chose ici non ? }

Comme par exemple appeler un script php en lui soumettant la liste des images réordonnées pour sauvegarder leur ordre en base de données.
http://stackoverflow.com/questions/1563 ... a-database
Développeur web depuis + de 20 ans

Eléphanteau du PHP | 38 Messages

04 juin 2015, 10:50

Bonjour Saian,

Je patauge .... :lol:

Alors voici le code que j'ai mis en suivant le lien que tu m'as donné, ainsi que le lien contenu vers l'Edit fiddle.

Mais j'ai du mal à saisir le sens. On ne parle nulle par de la colonne "position" sur laquelle le tri doit s'effectuer ?
Je ne vois pas à quoi doit correspondre le foreach $_POST ['item'].
J'ai remplacé l'id de l'ul par le nom de la photo, comme ça chaque ul à un id unique.
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
#sortable_galerie { list-style-type: none; margin: 0; padding: 0; width: 25%; }
#sortable_galerie ul { list-style-type: none; }
#sortable_galerie li { margin: 0 3px 3px 3px; padding: 0.4em; padding-left: 1.5em; font-size: 1.4em; height: auto; }
#sortable_galerie li span { position: absolute; margin-left: -1.3em; }
</style>
<script>
$(function() {
$( "#sortable_galerie" ).sortable();
$( "#sortable_galerie" ).disableSelection();
});
$(document).ready(function () {
    $('#sortable_galerie').sortable({
        axis: 'y',
        stop: function (change, position) {
	        var data = $(this).sortable('serialize');
            $('ui-state-default').text(data);
            $.ajax({
                    data: oData,
                type: 'POST',
                url: 'que dois-je mettre ici ?'
            });
	}
    });
});
</script>

<div class="adminform form_14">
	<?php echo _REALESTATE_MANAGER_LABEL_SELECT_PHOTO_FROM_GALLERY; ?>:
</div>

<div id="sortable_galerie">
	<?php
		$i = 0;
		foreach ($_POST['item'] as $value) {
		$i++;
	} ?>
							
        <?php
               for ($i = 0; $i < count($house_photos); $i++) {
                if (($i % 7) == 0) {
                echo "<br>";
        } ?>
							
	<ul id="<?php echo $house_photos[$i][1]; ?>">
		<li class="ui-state-default"><span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
		      <input type="checkbox" name="del_photos[]" value="<?php echo $house_photos[$i][0]; ?>" />
		      <img src="<?php echo $mosConfig_live_site . "/components/com_realestatemanager/photos/" . $house_photos[$i][1]; ?>" style="height:100px;" alt="no such file"/>
		</li>
	</ul>
       <?php } ?>
</div>
Merci de ton aide

Eléphanteau du PHP | 38 Messages

22 janv. 2016, 17:37

Bonjour à tous,

Juste un petit message avec la solution à ma problématique, en attendant de pouvoir faire mieux, j'avais pris comme solution de placer un input à côté de chaque image, et on pouvait saisir un num de position qui s'enregistrait en base.

Ces derniers temps j'ai eu du temps au boulot et je me suis donc remise à parcourir tuto, forum etc pour mettre en place mon drag and drop dont la position s’enregistrerait automatiquement en base (mon problème se situai précisément là), et j'ai fini par tomber sur ce tuto très utile : http://www.wakdev.com/more/wiki/javascr ... mique.html

J'ai donc quelque peu modifié sa structure et voici le résultat qui correspond à mes besoins et fonctionne enfin :P :

Ma page :
<!-- Styles drag -->
<style type="text/css">
     .sortable_item {
        cursor : move;
        width : 100%;
        list-style : none;
		margin: 5px;
		border: 1px solid #D8D8D8;
		padding: 5px;
		max-width: 200px;
		text-align: center;
    } 
    .ul_style {
          list-style-type : none;
          margin : 0;
          padding : 0;
    }
</style>

<!-- Scripts drag -->
<script src="http://code.jquery.com/jquery-1.8.2.js"></script>
<script src="http://code.jquery.com/ui/1.9.1/jquery-ui.js"></script>
<script type="text/javascript" src="....../interface.js"></script> /** fichier chargé à partir du lien fourni dans le tuto **/
<script type="text/javascript">
 
    $(document).ready (
        function () {
            $( "#sortlist" ).Sortable ( {
            accept : 'sortable_item',
            axis : 'vertically',
            opacity : 0.6,
            onchange : function ( sorted ) {
            serial = $.SortSerialize ( 'sortlist' ); 
            // requète Ajax pour l'enregistrement des positions
            $.ajax ( {
                url : "....../set_position.php",
                type : "post",
                data : serial.hash,
                });
            }
 
        });
    });
</script>
	
 <?php if (count($house_photos) != 0) { ?>
    <tr>
		<td valign="top"><?php echo 'Faire glisser les photos pour modifier l\'ordre d\'affichage'; ?><br/></td>

		<td valign="top" align="left">
			<ul id="sortlist" class="ul_style">
				<?php for ($i = 0; $i < count($house_photos); $i++) { ?>
					<li id="<?php echo  /**var id_photo 1**/; ?>" class="sortable_item">
						<input type="checkbox" name="del_photos[]" value="<?php echo $house_photos[$i][0]; ?>" />
						<img src="/**emplacement image 1**/" style="height:100px" alt="no such file"/> &nbsp
					</li>
					<li id="<?php echo  /**var id_photo 2**/; ?>" class="sortable_item">
						<input type="checkbox" name="del_photos[]" value="<?php echo $house_photos[$i][0]; ?>" />
						<img src="/**emplacement image 2**/" style="height:100px" alt="no such file"/> &nbsp
					</li>	
					<li id="<?php echo  /**var id_photo 3**/; ?>" class="sortable_item">
						<input type="checkbox" name="del_photos[]" value="<?php echo $house_photos[$i][0]; ?>" />
						<img src="/**emplacement image 3**/" style="height:100px" alt="no such file"/> &nbsp
					</li>	
					etc ...
				<?php } ?>
			</ul>				
		 </td>
	</tr>
						
<?php } ?>
Et mon fichier set_position.php pour enregistrer en base (j'ai dû le modifier un peu pour qu'il fonctionne, en ajoutant la requête SELECT) :
<?
	$mysqli = new mysqli($serveur, $user, $pass, $base);
	$db = mysql_connect('serveur', 'user', 'pass');

	mysql_select_db('/** ma base de données** /',$db) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());
		
	$sql = "SELECT `id`, `position` FROM /** ma table **/ ";
	$req = mysql_query($sql) or die('Erreur SQL !<br>'.$sql.'<br>'.mysql_error());

	while($data = mysql_fetch_assoc($req))
	{
		$sortlist = $_POST['sortlist'];

		for ($i = 0; $i < count($sortlist); $i++) {
	
				$query = ("UPDATE /** ma table **/ SET position ='".($i + 1)."' WHERE id=$sortlist[$i]");
				$ajout = mysql_query($query) or die(mysql_error());
		}
	}
?>
Et enfin tout est OK, sujet clos :D