Partage

[jQuery] Exercice (n° 2) pour s'entraîner

Menu chargé dynamiquement

21 novembre 2011 à 13:39:11

Bonjour à tous,

Je vous propose aujourd'hui un deuxième exercice (voir le premier) sur jQuery, dans l'idée de faire progresser les membres mais aussi d'animer la section. ;)

Avant d'entrer dans le vif du sujet, il y aura un certain nombre de règles à respecter pour que tout se passe bien dans ce topic.

Règles


  1. Le troll et le flood ne sont pas tolérés. Inutile de balancer des "Pourquoi jQuery et pas Mootools ?", les messages non constructifs seront modérés.
  2. Je vous fournis le code HTML, vous n'aurez pas le droit de le modifier.
  3. Votre réponse contiendra uniquement du code jQuery avec la balise <secret> de manière à respecter ceux qui n'ont pas commencé l'exercice.
  4. Evidemment, le code que vous posterez devra être de vous, pas la peine de recopier un code externe, cela n'a pas d'intérêt. L'utilisation de plugins n'est pas nécessaire.


Objectif du script


Description


Nous allons créer un menu sous forme de liste à puces basique. Vous allez devoir charger et parcourir un fichier JSON qui contiendra les données de notre menu. Le chargement devra se faire en Ajax.
Au niveau du contenu je me suis inspiré du SdZ. :)

Voici les difficultés que vous pourrez rencontrer :
  • Faire en sorte que les accents s'affichent correctement (le JSON en contiendra).
  • Eventuellement le parsage du JSON.

HTML


<ul id="accueil"></ul>
<ul id="cours">
	<li>Cours</li>
</ul>
<ul id="forums"></ul>
<ul id="participez">
	<li>Participez</li>
</ul>



JSON


{ 
  "accueil": "Page d'accueil", 
  "cours": [ 
      {
          "titre": "Les cours phares" 
      }, 
      {
          "titre": "Tous les cours par catégories"
      } 
   ] ,
  "forums": "Accédez aux forums",
  "participez": [ 
      {
          "titre": "Cours" 
      }, 
      {
          "titre": "News" 
      } 
   ]
}

Rendu FINAL


Image utilisateur


Ressources




Bon code ! :pirate:

Il n'y a pas une seule solution, je donnerai plus tard ma version du script commentée, j'attends un peu pour ne pas vous inciter à la regarder. :)
23 novembre 2011 à 1:12:05

Salut, j'ai fait ton petit exercice mais je doit encore faire quelques modifications pour être en full jQuery.
Par contre je bloque sur les accents, est-ce que tu utilise un serveur. Car je suis en statique et du coup je ne trouve pas comment on decode facilement le retour json.
si tu avait un petit indice, car j'ai pas mal cherché et je trouve pas ce que je souhaite.
23 novembre 2011 à 8:19:22

@ninlock : Vérifie bien que tes fichiers sont enregistrés en utf-8.


Sinon, je comprends bien l'intérêt pédagogique qu'il y a dans cet exercice, mais charger un menu par Ajax... :euh: d'autres structures auraient pu être construite, donnant moins l'impression de faire caca sur l'accessibilité.

M'enfin ! Bonne chance aux participants !
23 novembre 2011 à 9:02:56

Citation : ninlock

Par contre je bloque sur les accents, est-ce que tu utilise un serveur. Car je suis en statique et du coup je ne trouve pas comment on decode facilement le retour json.


Non je n'ai pas utilisé de serveur, donc pas moyen d'utiliser header() en PHP pour forcer l'iso, par exemple. J'ai aussi pas mal cherché, une solution se trouve au niveau de l'appel ajax (je ne t'en dis pas plus).

Citation : Golmote

Sinon, je comprends bien l'intérêt pédagogique qu'il y a dans cet exercice, mais charger un menu par Ajax... :euh: d'autres structures auraient pu être construite, donnant moins l'impression de faire caca sur l'accessibilité.


Je vois, je suis ouvert à toutes idées. :)
J'avais envie d'évoquer le chargement et le parsage JSON et j'ai pas trouvé plus simple que ça (comme exemple). Il faut à la fois que l'exercice soit intéressant et pas long/trop complexe afin d'attirer au moins quelques personnes.
23 novembre 2011 à 9:33:25

En fait c'est bien sur la fonction ajax de jquery que j'ai concentré mes recherche, en passant par dataType, contentType et scriptCharset, que ce soit dans l'utilisation de cette methode ou dans la fonction ajaxSetup pour lui définir un comportement par défaut. Faut-il enregistrer sont fichier json en utf-8 comme le spécifie Golmote? Ce point concernant json m’intéresse, car je n'ai pas encore trop manipulé ce format de fichier en ajax.
23 novembre 2011 à 9:40:46

Personnellement, j'ai enregistré le JSON dans le format (encodage) par défaut de Notepad++.
Tu as cherché au bon endroit au niveau de l'ajax. :)
Je n'ai pas ma correction sur moi, je l'aurai demain donc je ne peux pas t'en dire davantage.
23 novembre 2011 à 9:46:58

En fait j'ai testé avec la remarque de Golmote et en effet c'était bien cela. Peut-être que ton n++ a enregistré au bon format directement, Essaye de changer le format de ton json(autre que utf-8) afin de vérifier que c'est bien cela qui poser problème.

Merci Golmote pour la remarque, cela fonctionne maintenant.

EDIT : voici ma réponse a l'exercice :

<html>
<head>
<script type="text/javascript" src="../javascript/jquery.js"></script>
<script type="text/javascript">
	$(document).ready(function(){
			loadMenuJson("menuDeroulant.json", $("#menu"));
	});

	function loadMenuJson(sUrl,parentMenu) {
			$.ajax({
				url : sUrl,
				contentType: "application/json; charset=utf-8",
				dataType : "json",
				success :  function(json){
					$.each(json, function(key, val) {
			   	  createMenu(parentMenu, key, val);
			 		});
				},
				error : function (){alert("erreur de chargement Json!")}
			})
  }

  function createMenu(parent, key, values){
  	var ul = createRoot(key);
  	if(typeof values == 'string'){
  		ul.append(createSSMenu(values));
  	}else{
  		ul.append(createSSMenu(key));
  		var ssmenu = createRoot("ss_"+key);
  		$.each(values, function() {
			  ssmenu.append(createSSMenu(this.titre));
			});
  		ul.append(ssmenu);
  	}
  	parent.append(ul);
  }

  function createRoot(idMenu){
  	return $("<ul>", {id:idMenu});
  }

  function createSSMenu(value){
  	return $("<li>"+ value +"</li>");
  }
</script>
</head>
<body>
	<div id="menu">

	</div>
</body>
</html>

23 novembre 2011 à 16:12:17

Merci ninlock. J'aurais préféré, comme demandé, d'utiliser le HTML que j'ai donné même si cela ne te paraît pas intelligent.

Du coup c'est moins évident de comparer les scripts si chacun change le code de départ... :(

C'est pas grave. ;)
23 novembre 2011 à 16:18:31

Désolé, je me suis permi de faire comme cela car le faite de charger un menu dynamique avec une base statique ne me parait pas cohérente. Mais la différence ne devrait pas être très importante.
23 novembre 2011 à 19:28:57

Citation : Desolation

Citation : Golmote

Sinon, je comprends bien l'intérêt pédagogique qu'il y a dans cet exercice, mais charger un menu par Ajax... :euh: d'autres structures auraient pu être construite, donnant moins l'impression de faire caca sur l'accessibilité.


Je vois, je suis ouvert à toutes idées. :)
J'avais envie d'évoquer le chargement et le parsage JSON et j'ai pas trouvé plus simple que ça (comme exemple). Il faut à la fois que l'exercice soit intéressant et pas long/trop complexe afin d'attirer au moins quelques personnes.



Bien entendu. Comme je l'ai dit, je vois bien l'intérêt pédagogique. C'est juste le fait que ce soit un menu qui m'embête. C'aurait pu être n'importe quoi d'autre...

Des faux messages FB ou twitter (avec une photo, un texte, une date, des commentaires ... ?), des actualités, ...

Juste pas un menu quoi...
23 novembre 2011 à 21:44:30

Salut !

Ayant pour habitude d'écrire mes codes la plupart du temps en m'aidant pas mal de documentation, me suis dit que j'allais essayer de voir ce que je peux faire de tête. Un exercice intéressant, je n'ai pas testé le code mais je suis confiant. :lol:
Par contre, je n'ai pas compris où était la difficulté pour l'ouverture du fichier JSON et le parsage. :euh:
function majuscule (texte) {
	return texte.charAt(0).toUpperCase() + texte.slice(1);
}
$.getJSON('menu.json', function(data) {
	for (var ul in data) {
		if ($.isArray(data[ul])) {
			$('#' + ul).html('<li>' + majuscule(ul));
			for (var i = 0, c = data[ul].length, html = '<ul>'; i < c; i++) {
				html += '<li>' + data[ul][i].titre + '</li>'; 
			}
			$('#' + ul).append(html + '</ul></li>');
		} else {
			$('#' + ul).html('<li>' + data[ul] + '</li>');
		}
	}
});


Merci !
23 novembre 2011 à 21:52:38

Insérer le <li> en deux fois (début ligne 7 et fin ligne 11) n'est sans doute pas une bonne idée. Je doute que tu obtiennes le résultat escompté.

Tu peux résoudre cela très simplement et de plus optimiser ce code en utilisant .html() une seule et unique fois dans le if(), et non pas deux ;)
23 novembre 2011 à 21:53:11

Bien Claros, ça fonctionne ! Dommage pour les accents. :)

A côté de vous, mon code est bien crade (je posterai demain).
23 novembre 2011 à 21:57:11

Citation : Golmote

Insérer le <li> en deux fois (début ligne 7 et fin ligne 11) n'est sans doute pas une bonne idée. Je doute que tu obtiennes le résultat escompté.

Tu peux résoudre cela très simplement et de plus optimiser ce code en utilisant .html() une seule et unique fois dans le if(), et non pas deux ;)


Oups, j'ai pourtant pour habitude d'insérer le code html en une seule fois.
function majuscule (texte) {
	return texte.charAt(0).toUpperCase() + texte.slice(1);
}
$.getJSON('menu.json', function(data) {
	for (var ul in data) {
		if ($.isArray(data[ul])) {
			var html = '<li>' + majuscule(ul) + '<ul>';
			for (var i = 0, c = data[ul].length; i < c; i++) {
				html += '<li>' + data[ul][i].titre + '</li>'; 
			}
			$('#' + ul).html(html + '</ul></li>');
		} else {
			$('#' + ul).html('<li>' + data[ul] + '</li>');
		}
	}
});



Citation : Desolation

Bien Claros, ça fonctionne ! Dommage pour les accents. :)


Comment ça dommage ? Si l'encodage de la page où est lancé le script est le même que celui du fichier .json, normalement les accents passent nickel. ^^
24 novembre 2011 à 10:56:12

J'ai honte :
$(document).ready(function() {
	$.ajax({
		url: 'menu.json',
		dataType: 'json',
		beforeSend : function(xhr) {
			xhr.overrideMimeType('text/html; charset=ISO-8859-1');
		},
		success: function(json) {
							
			$('#accueil').append('<li>'+ json.accueil +'</li>');
			
			$.each(json.cours, function(i, texte) {
				if(i == 0) $('#cours > li').append('<ul>');
				$('#cours > li > ul').append('<li>'+ texte.titre +'</li>');
			});
			
			$('#forums').append('<li>'+ json.forums +'</li>');

			$.each(json.participez, function(i, texte) {
				if(i == 0) $('#participez > li').append('<ul>');
				$('#participez > li > ul').append('<li>'+ texte.titre +'</li>');
			});
		}
	});	
});


Claros : mes pages sont encodées en ANSI dans Notepad++.
24 novembre 2011 à 12:14:00

Ok je comprends. Travaillant sous Linux, j'encode tout en UTF-8.
24 novembre 2011 à 19:13:41

@Desolation : Et quand est-ce que tu te mets à l'utf-8 ? o_O
24 novembre 2011 à 20:19:58

Les accents m'ont tellement emmerdés, j'ai jamais réussi à les afficher en utf-8. :(
24 novembre 2011 à 20:32:14

C'est pourtant là que c'est le plus simple.

Si tu mets tout en UTF-8 (bases, fichiers, etc.), tu n'as strictement rien à faire.
31 décembre 2011 à 16:34:27

Execice


L'exercice est intéressant et enrichissant.


Chargement Ajax


Il démontre que l'utilisation de la fonction Ajax si redouté par les jeunes usagés, n'est pas si compliqué si on se documente un peu. Il est très pratique de ne pas avoir à recharger une page entière pour la mise à jour d'un seul élément.

Encodage


Tu illustre aussi un problème majeur qui est l'encodage et sa gestion. C'est une chose très importante qui est nécessaire d'assimilé au plus tôt.

Avis


J'ai moi-même recourt au fonctionnement Ajax pour de nombreuses utilisation, liens de menu chargeant le conteneur principal, mise à jour de la base de donnée, extraction de donnée.

Je trouve donc que certain piège qui peuvent prendre du temps lorsque l'on ne sait pas où cherché sont bien expliqué ici.

En revanche, je suis du même avis Golmote pour ce qui est du menu. Un chargement Ajax est fait pour évité le reload d'une page, hors un menu doit être présent dès l'ouverture du site pour facilité la navigation.

[jQuery] Exercice (n° 2) pour s'entraîner

× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
  • Editeur
  • Markdown