Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Listes liées en Ajax avec URL Rewriting

Le , par CinePhil

0PARTAGES

Je viens d'être confronté à un souci pour programmer en Ajax deux listes liées (la sélection dans l'une remplit les options de la seconde) alors que j'ai mis en oeuvre la réécriture d'URL dans mon application PHP.

1. Le déroulement des programmes PHP à l'appel d'une URL
Toutes les URL sont parsées par .htaccess et doivent être de la forme suivante : mon.site.fr/langue/Module/action avec éventuellement derrière ça un à plusieurs paramètres supplémentaires.

Mon .htaccess ressemblait à ça :
Code Apache : Sélectionner tout
1
2
RewriteRule ^([a-zA-Z]+)\/([a-zA-Z]+)\/([a-zA-Z_]+)\/(.+)$ index.php?langue=$1&module=$2&action=$3&param=$4 [L] 
RewriteRule ^([a-zA-Z]+)\/([a-zA-Z]+)\/([a-zA-Z_]+)$ index.php?langue=$1&module=$2&action=$3 [L]

Apache appelle donc systématiquement le index.php de la racine de l'application.
Ce dernier récupère de $_REQUEST les paramètres standard $langue, $module et $action. Il vérifie que le module existe dans la liste des modules de l'application et lance le contrôleur du module appelé :
Code PHP : Sélectionner tout
1
2
// Renvoi vers le contrôleur du module demandé 
require RACINE.'application/module/'.$module.'/Controller/index.php';

Le contrôleur du module vérifie l'existence de l'action et appelle le programme de l'action :
Code PHP : Sélectionner tout
1
2
// Recours au contrôleur de l'action 
require RACINE.'application/module/'.$module.'/Controller/'.$action.'.php';

Jusque là, tout va bien...

2. La programmation des listes liées
J'ai donc deux listes que j'appellerai ici liste_mère et liste_fille. Lorsque l'utilisateur sélectionne un élément de la liste mère, un appel Ajax est fait pour restreindre la liste fille aux éléments associés à la sélection.

Dans la page HTML, la liste mère est de cette forme :
Code HTML : Sélectionner tout
1
2
3
4
5
6
<label for="listeMere">Mère : </label> 
		<select name="listeMere" onchange="restreindreFilles(this.value);"> // La propriété onchange appelle la fonction Ajax, partie Javascript. 
			<option value="0" selected >--Sélectionner--</option> 
			<option value="1">Maman</option> 
			<option value="2">Mother</option> 
		</select>
Code Javascript : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function restreindreFilles(mere) 
{ 
	$.ajax({ 
		type: 'POST', 
		url: 'http://localhost/monappli/fr/monmodule/aj_restreindre_filles', 
		data: 'mere='+mere, 
		dataType: 'text', 
		cache: 'false', 
		success: function(filles) 
		{ 
			$("#listeFille").html(filles); 
		} 
	}); 
}
=> Nota : Vous aurez remarqué que j'utilise la syntaxe JQuery, tellement plus pratique !

Le programme aj_restreindre_filles est de ce genre, interrogeant la BDD afin de trouver les filles de la mère sélectionnée :
Code PHP : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Récupération de la mère sélectionnée par l'utilisateur (vient de la fct javascript restreindreFilles(mere) 
$idMere = intval($_POST['mere']);  
  
// Accès à la BDD et récupération de la liste des filles de cette mère 
require_once RACINE.'application/include/bddMysql.php'; 
require_once RACINE.'application/Model/fille.php'; 
$obj_fille = new fille(); 
  
$liste_filles = $obj_fille->getListeFilless($idMere); 
  
$html = ''; 
  
if(count($liste_filles) == 0) 
{ 
	// Il n'y a pas de fille pour cette mère 
	$html = '<option value="0">'."-- Pas de fille --".'</option>'; 
} 
else  
{ 
	// Construction de la liste de sélection des filles correspondant à la mère choisie 
	$html.= '<option value="0" >-- Sélectionner --</option>'."\n"; 
  
	foreach($liste_filles as $fille) 
	{ 
		$html.= '<option value="'.$fille['filleId'].'" >'.$fille['filleNom'].' '.$fille['fillePrenom'].'</option>'."\n"; 
	} 
} 
  
// Envoi de la liste des filles au programme javascript 
echo $html;

3. Le problème posé par l'URL Rewriting
L'URL appelée par le programme Javascript est interprété par le .htaccess comme s'il s'agissait d'une URL d'une page complète de l'application.
Du coup, le programme aj_restreindre_filles.php n'est pas appelé directement mais via le index.php principal de l'application puis via celui du contrôleur du module.
Une fois le programme aj_restreindre_filles.php exécuté, la main est repassée au contrôleur du module puis à index.php général... qui regénère la page HTML en entier en y incluant au début le echo $html;... et c'est l'ensemble qui est renvoyé au programme Javascript. Le code HTML de la page se retrouve donc en double dans la zone de sélection des filles... c'est la pagaille !

4. La solution
Il m'a suffi d'ajouter une règle au .htaccess pour interpréter différemment les URL contenant la chaîne 'aj_' afin qu'Apache appelle directement le programme aj_restreindre_filles.php, ce qui est la logique de la programmation en Ajax.
J'en ai profité pour ranger mes programmes Ajax/PHP dans un dossier ajax spécifique de l'arborescence de mon appli, au lieu de les répartir dans les contrôleurs des modules, ce qui, à mon avis, n'est pas vraiment leur place.

Le nouveau .htaccess avec la nouvelle règle en premier :
Code Apache : Sélectionner tout
1
2
3
RewriteRule ^([a-zA-Z\/]+)\/(aj_)([a-zA-Z_]+)$ application/ajax/aj_$3.php [L] 
RewriteRule ^([a-zA-Z]+)\/([a-zA-Z]+)\/([a-zA-Z_]+)\/(.+)$ index.php?langue=$1&module=$2&action=$3&param=$4 [L] 
RewriteRule ^([a-zA-Z]+)\/([a-zA-Z]+)\/([a-zA-Z_]+)$ index.php?langue=$1&module=$2&action=$3 [L]

Une erreur dans cette actualité ? Signalez-le nous !