Comment organiser ses listes ? {HTML, PHP,(JS)}

Leyry Hynemonth

a découvert une nouvelle définition de l'ennui.
Club iGen
18 Décembre 2004
4 142
260
Nîmes
www.lyhn.fr
Bonjour à tous !

Voilà, je ne sais pas comment s'appelle ce que je cherche à faire, mais je sais ce que cela doit faire.

Merci de m'aider à en trouver le nom, et si quelque chose existe de déjà tout prêt, de me faire un jolis petit truc bleu souligné :rose: .

Ce que je cherche à avoir :
Je souhaite faire dans une interface d'administration, une page pour gérer des éléments d'un menu. Un peu à la façon de la colonne Ordre de Joomla!
capturedcran20110319110.png

Sauf que dans mon cas, j'ai besoin de pouvoir gérer l'organisation sur deux axes :
1 : L'ordre
2 : Le parent de l'élément.

Ensuite, je dois enregistrer ces informations en base de données, si bien qu'au final, avec une toute petite fonction récursive en PHP, j'obtiens le résultat final suivant (pardonnez la pertinence des exemples, et l'absence de style — cela viendra ;) ) :
capturedcran20110319111.png

Résultat de ma fonction récursive qui traite les attributs de idMenu, parentId, ordre de chaque tuple dans ma bdd


J'aurais aimé faire cela de sorte que cela implique le moins de rechargement possible sur la page de gestion de ce menu.

Mais cela implique du JavaScript/jQuery, dans lesquels je suis :sick:.

Donc, j'en suis au stade où soit je fais tout moi-même en PHP, et c'est insupportable à manipuler, soit il existe quelque chose de très approchant de mon besoin...

Mais comme je vous l'ai dit plus haut, je ne sais pas comment s'appelle ce genre de chose.


Avez-vous une solution à me proposer pour me sortir de ce dilemme ? :rose:


Merci. Beaucoup.
 
L'élément sortable de jquery te conviendrait pas ?
http://jqueryui.com/demos/sortable/

Bon il doit falloir quelques adaptations pour gérer l'aspect hiérarchique du menu, mais avec un peu de javascript additionnel ça doit pouvoir s'arranger.

Probablement, mais ce genre de chose fait appel à de la programmation orientée objet.

Je commence à peine ça en Java pendant les cours. Et quand je regarde le code de ces fonctions de jQuery, j'ai bien du mal à comprendre comment ça marche, et comment faire ma sauce.
Et étape cruciale qui n'est pas toujours bien énoncée : Comment récupérer le nouvel ordre ?!

De plus, je n'ai pas forcément besoin que ma liste soit réorganisable en déplaçant les éléments à la souris. Oui ,ça serais un plus, mais ça serait aussi une usine à gaz parmi des choses bien plus classiques :D


Bon, je regarderais quand même ce que tu m'as montré là. Des fois que cette source soit mieux que celles que j'ai déjà essayé d'exploiter.

Bon après midi, et merci pour ton truc bleu ;) :siffle:
 
L'intérêt de jquery, surtout avec ce genre de fonctionnalité de base, c'est que t'as des milliers d'exemples sur le net, par exemple :
http://blog.arnaud-k.fr/2010/develo...ne-liste-en-dragndrop-avec-jqueryui-sortable/

Je sais... mais pour le moment, tout ce que j'arrive à faire de mes propres mains en copiant collant ce que je trouve :)siffle::rateau:), c'est un truc conceptuellement moche qui consiste à avoir une liste vide avec chaque élément, des fois que l'utilisateur voudrait mettre quelque chose en enfant.

Après, reste encore le problème de l'enregistrement...

En plus, j'ai encore rien fait pour les styles... du coups... Brups !:p

capturedcran20110320200.png
 
Bon, après moultes tentatives et formes de tentatives, j'ai réussis à obtenir quelque chose : En expédition de formulaire, j'ai quelque chose du genre [5-sortable0][6-sortable5][7-sorta... qui signifit que le menu ayant pour id 5 est enfant de l'élément 0, le menu ayant pour id 6 est enfant de l'élément 5 .... et le tout arrivant dans l'ordre commandé.

Reste plus qu'à en faire quelque chose d'exploitable en PHP, pour ensuite en faire une grosse requête SQL.
C'est pas fini, mais j'ai passé la partie la plus dure pour moi : Le JavaScriptIptIpt !
perdu-cherche-carte.gif
 
Bon, ben c'était juste pour dire que ça marche. jQuery Sortable, et méthode perso pour la génération du nouvel ordre. Ensuite, PHP interprète l'ordre généré en javascript, et sequele en conséquence.

(sequele, du verbe séqueler : exécuter une requête sql. :p )
 
Bonjour,

je souhaite faire la même chose, c'est à dire que j'ai des questions qui peuvent elle même avoir des sous questions etc.. ce qui donnerait la même chose que Leyry Hynemonth : http://img38.imageshack.us/img38/4903/capturedcran20110319111.png

Dans ma base de données mes entrer se font correctement , chaque question a un id, un id_pere, et la position . Concernant la position si on prend les questions principales c'est à dire avec un id_pere = null , les positions vont de 1 à N , si l'une de ces question a plusieurs autre sous question les positions dans celle ci recommence de 1 à N etc..

Je n'arrive pas à faire la boucle récursif , pour info j'utilise Zend je vous montre le code il reste compréhensible si on n'a pas utilisé Zend :

Ma fonction qui fait le listage de la liste.

Bloc de code:
 public function listage($id_liste ,$id_question=null ,$pos ,$data ,$checkpoint){
         
         $res = new Application_Model_QUESTION();
         $checkpoint = array();
         
         if($id_question!=null){
             //$pos = "<ul>".$pos;
         }
         else{
             $pos="";
         }
         
         foreach($tab=$res->getLinkedQuestions($id_liste, $id_question) as $subquestion){
             
             $state = $res->test($id_liste, $subquestion['id_question']);
             //if($checkpoint != $subquestion['position_liste']){
                 if($state ){
                     
                     $pos .= $subquestion['position_liste'];
                     $data .= $pos." ".$subquestion["question"]."<br>";                 
                     
                     $pos.="-";
                     self::listage($id_liste, $subquestion['id_question'], $pos, $data, $subquestion['position_liste'] );
                 }else{
                     echo "<pre>";
                     //print_r($tab);
                     echo "</pre>";
                     //$pos .= $subquestion['position_liste'];
                     $data .= $subquestion['position_liste']." ".$subquestion["question"]."<br>";
                 }
             //}
         }
         echo $data;
     }

Mes fonctions SQL
Bloc de code:
   public function test($id_liste, $id_question){       
    
                                    
            $select = $db->select()
            ->from($this->_name)
               ->where('id_pere =?', $id_question);
                    
                
            $res=$db->fetchOne($select);
            if($res==""){
                return FALSE;
            }
            else{
                return TRUE;
            }        
    }
    
    public function getLinkedQuestions($id_liste, $id_question=null){
 
                                    
            $select = $db->select()
            ->from($this->_name);
               if (is_null($id_question)) {
                $select->where('`id_pere` IS NULL');
            }else {
                $select->where('`id_pere` = ?', (int)$id_question);
            }
                $select->where('`id_liste` = ?', (int)$id_liste)
                ->order('position_liste ASC');            
                    
            //$stmt= $db->query($select);    
            $res= $db->fetchAll($select); //retourne toutes les questions dans l'ordre croissant relatifs à celle reçu en paramètre    
        
            return $res;        
    }


Voilà l'objectif est le même pour moi pouvoir changer les positions , rajouter des sous questions etc..
Je me pencherais sur la partie ajax/jquery quand j'aurais la base ^^ c'est à dire une fonction récursive qui fonctionne.

Je vous remercie d'avance pour votre réponse.
 
Voilà ma fonction, qui est appelée avec getPublicMenu(0,0);
Malheureusement pour toi, ce n'est pas de l'objet :(

Bloc de code:
function getPublicMenu($parentId,$niveau)
		{
		$sql = "select * from menu where parent_id = '$parentId' and est_actif = '1' order by position";
		$sql = mysql_query($sql);
		for($i=1;$i<=$niveau;$i++) {$tab = $tab."	";}
		if (mysql_num_rows($sql) > 0)
			{
			$retour = "$tab<ul>\n";
			while ($ligne = mysql_fetch_array($sql))
				{
					//$MaPetiteLigne = stripslashes($ligne["libelle"]);
					//echo "$tab<li class=\"menuLevel$niveau\">$MaPetiteLigne</li>\n";
					$retour = $retour."$tab".genererLien($ligne,$niveau)."</li>\n";
					
					$retour = $retour.getPublicMenu($ligne["id_menu"],$niveau+1);
				}
			$retour = $retour."$tab</ul>\n";
			}
			
			else
			{
			
			}
		
		return $retour;
		}
 
si ça peut aider, j'avais programmé un truc pour afficher un menu multi niveau en php, avec des contraintes supplémentaire liées à l'utilisation d'un template Smarty, à voir si en le modifiant ça peut faire ce que tu veux

ici, ça affiche, une image devant la catégorie mère
des espaces devant les catégories filles qui se décalent plus on avance dans l'arborescence

Bloc de code:
$query = "SELECT id, name, id_prev, pic FROM categories ORDER BY name ASC";
$db_cat =& MDB2::factory($dsn_cat);
$res =& $db_cat->query("$query");
 
$categories = array();
 
while($row = $res->fetchRow(MDB2_FETCHMODE_ASSOC)){
	$categories[] = array(
	'parent_id' => $row['id_prev'],
	'categorie_id' => $row['id'],
	'nom_categorie' => $row['name'],
	'pic' => $row['pic']
	);
}


function afficher_menu($parent, $niveau, $array) {
 
$html = "";
 
foreach ($array AS $noeud) {
 
	if ($parent == $noeud['parent_id']) {
	if ($noeud['parent_id'] == "0")
	{
	$html .= "<tr style='background-color:#dfe1e1;'><td><br /><center>" .$noeud['categorie_id']. "</center></td>";
	$html .= "<td><br /><center><img src=/img/Templates/Cat/" .$noeud['pic']. "></center></td><td class='td_result' style='font-size:16px;'>";
	}

	for ($i = 0; $i < $niveau; $i++) 
	{
	
	
$html .= "&nbsp; &nbsp;";
	if($niveau == "1")
	{
	$html .= "<br /><strong>";
	}
	if($niveau == "2")
	{
	$html .= "&nbsp;&nbsp;• &nbsp;";
	}	
	
	if($niveau == "3")
	{
	$html .= "&nbsp;&nbsp;• &nbsp;";
	}
	if($niveau == "4")
	{
	$html .= "&nbsp;&nbsp;• &nbsp;";
	}
	if($niveau == "5")
	{
	$html .= "&nbsp;&nbsp;• &nbsp;";
	}
	}
	
	
	if ($noeud['parent_id'] == "0")
	{
	$html .= "<a name=" .$noeud['categorie_id']. "></a><span class=rouge style='font-size:20px'>" . $noeud['nom_categorie'] . "</span><br />";
 	}
 	else
 	{
 	if($niveau=="1")
 	{
 	 	$html .= "<a name=" .$noeud['categorie_id']. "></a><span class=blu16  style='font-size:16px'>" . $noeud['nom_categorie'] . "</span><br />";
 	}
 	elseif($niveau=="2")
 	{
 	 	$html .= "<a name=" .$noeud['categorie_id']. "></a><span style='font-size:16px; font-weight:bold;'>" . $noeud['nom_categorie'] . "</span><br />";
 	}
 	else
 	{
 	$html .= "<a name=" .$noeud['categorie_id']. "></a>" . $noeud['nom_categorie'] . "<br />";
 	}
 	}
 	
	if($niveau == "1")
	{
	$html .= "</strong>";
	}
 	
	$html .= afficher_menu($noeud['categorie_id'], ($niveau + 1), $array);

 	if ($noeud['parent_id'] == "0")
	{
	$html .= "</td></tr>";
	}		
	}
 
}
	
return $html;
 
}


$affiche_cat = afficher_menu(0, 0, $categories);


// AFFICHAGE EN HTML

<table>
<?php echo "$affiche_cat"; ?>
</table>

surement un peu bancale, mais ça marchait bien et surtout fonctionne en une seule requete
 
Dernière édition par un modérateur:
Re,

Mercy à Leyvry mais en objet ça n'a pas marché alors je me suis dirigé vers: http://www.siteduzero.com/tutoriel-3-36703-la-recursivite.html et adapté en Zend/PHPO

Enfin ça marche ^^ Zend est dur à maîtrisé enfin bref : ça me donne ça :



Chaque ligne est déplaçable aux endroit ou il y a un éléments ça marche, j'ai utilisé SORTABLE de JQUERY.

Ma question c'est lorsque je déplace une élément comme celui sur le screen en bas , comment faire en Javascript ou autre pour savoir où il a était intégrer.
Chacun de mes li a un span avec un id_question de la BDD , pas visible sur le screen mais que je passerait en non visible après.
Je veux que quand je rajoute un élément je puisse me repéré par rapport aux autres id des éléments ou je vais rajouté mon élément.
J'ai surement pas était clair mais je n'arrive vraiment a mieux expliquer ce problème , puisqu'il s'agit d'un truc pas encore réaliser d'après mes recherches sur le net donc j'ai pas de mots à mettre pour expliquer ^^.

Merci de m'aider je suis sur que cela sera utile à d'autres , je peux pas encore mettre de code , puisque c'est un projet pour une entreprise dans laquelle je suis en stage :)
 
Dernière édition:
Pour ma part, c'est du maison maison :

Tous les li sont de la classe "bienParticulière".

En bas de la page, un bouton qui déclenche une fonction javaScript.

Dans un tableau, j'attrape tous les éléments de classe "bienParticulière"
Pour tous les éléments de se tableau, je prends l'ID, je l'ajoute à une chaine de caractère ordreFinal, j'y ajoute ensuite un "-" puis j'y rajoute l'id du parentNode, et je termine ce couple avec un "|".

Quand j'ai fait ça pour tous les li qui étaient dans mon tableau, j'écris la chaine ordreFinal dans un input hidden, et j'indique en JavaScript qu'il faut envoyer le formulaire.

Et en PHP, je décode le truc.
Et voilà !
 
l'id de chaque élément est stocké ou ? Et si tu déplace un élément avec une flèche ou autre le numéro de la question par exempe 1-2-1 se met pas à jour avec ta méthode non ? puisque la personne trie les éléments et seulement après il y a un traitement ?

Ce que j'ai du mal à faire parce que je n'ai pas d'expérience JS , c'est sachant que chaque <li> je lui met un id="id_question_bdd" c'est comment savoir ( je pars sur la méthode de traitement de toute la liste à la fin !) que tel question est a tel endroit et quel id_parent elle appartient.
Et un autre point aussi, lorsqu'il déplace une question qui contient des fils comment déplacé tout ces fils.

je ne voit pas comment faire ça en JS, je sais crée un élément html et le placer derrière ou avant un autre élément dont je connais l'ID mais bon ça vol pas très haut :)
 
Hello !

Chez moi, les ID des LI sont simplement l'id de mon élément dans ma table menu, en BDD.

Ça, c'est ce qui récupère les LI d'une certainneclasse:
>> var listes = document.getElementsByClassName("ui-state-default");

Normalement, l'odre dans lequel l'utilisateur a disposé les éléments est respeté.

Ça, c'est ce qui place dans une chaine de caractères l'ID du LI puis l'ID du parent
>> stringFinal += listes.id+"-"+listes.parentNode.id+"|";


Bloc de code:
function saveOrder(niveau)
			{
			var stringFinal = "";
			//Récupérer la liste des éléments dont la classe est xxx
			var listes = document.getElementsByClassName("ui-state-default");
			
			
			//Pour chauque élément, noter dans un String sont id, et l'ID de son parant avec this.parentNode.id
			
			for(var i = 0; i < listes.length; i++)
				{ 
			   	stringFinal += listes[i].id+"-"+listes[i].parentNode.id+"|";
			   	}
			//alert(stringFinal);			
			//Envoyer le formulaire
			document.form1.myString.value = stringFinal;
			document.form1.submit();
			}