11550 sujets

JavaScript, DOM et API Web HTML5

bonjour,

j'essaye d'afficher dynamiquement la disponibilité d'un pseudo lors de l'inscription d'un utilisateur.

Je possède une page form.php contenant entre autre

<p>
	<label>Nom d'utilisateur : </label>
	<input type="text" id="username" name="username" maxlength="50" value="<?php print $_POST["username"];?>" />
	<span id="username_alert"><?php print $message["username"];?></span>
</p>


à la validation du formulaire, on passe par un validForm.php et vers une fonction

function verifDispoUsername($username) {
	$dispo = false;
	if($connection){
		echo "connecteBBD, ";
		
		if(mysql_select_db(BDD)){
			$result = mysql_query("SELECT pseudo FROM inscrit WHERE pseudo='".$username."'");
			if(mysql_num_rows($result)==0)
				$dispo = true;
			return $dispo;
		}
		mysql_close($connection);
	}
	return $dispo;
}


Le javascript contient deux fonctions visant à vérifier la disponibilité ou non du pseudo. Celles si sont déclanchées par
username.setAttribute('onKeyUp', 'verifUsername(username)');

Voici les deux fonctions

function verifUsername(username) {
	var XHR = new XHRConnection();
	XHR.appendData("username", username.value);
	XHR.sendAndLoad("verifUsername.php", "POST", afficheDispo);
}



function afficheDispo(obj) {
	username_alert = document.getElementById('username_alert');
	// suppression du texte existant
	while(username_alert.firstChild != null) {
		username_alert.removeChild(username_alert.firstChild);
	}
	
	// Construction des noeuds
	var tabResult = obj.responseXML.getElementsByTagName('resultat');
	var resultat = tabResult.item(0);
	var dispo = resultat.getAttribute('dispo');
	
	// creation du message suivant le cas
	if (dispo == "dispo") {
		var texte = document.createTextNode("Le nom d'utilisateur est disponible");
		username_alert.appendChild(texte);
	} else {
		if (dispo == "indispo") {
			var texte = document.createTextNode("Le nom d'utilisateur n'est pas disponible");
			username_alert.appendChild(texte);
		}
	}
}


et enfin, voici verifUsername.php


<?php
include("function.php");

// recupération du username
$username = $_POST["username"];
// on verifie que le username est dispo
if($username != "" && verifDispoUsername($username)) {
	$dispoUsername = "dispo";
} else {
	$dispoUsername = "indispo";
}
if($username == '')
	$dispoUsername = "vide";
// on cree une feuille xml
header('Content-type: text/xml');
// on retourne le resultat sous format xml
$xml = '<resultats>';
$xml .= '<resultat dispo="'.$dispoUsername.'" />';
$xml .= '</resultats>';
print $xml;
?>



tout ça pour dire que mon javascript pose problème car
- les autres champs vérifiés par celui-ci s'affichent dynamiquement et correctement
- lorsque je valide le formulaire avec un pseudo déjà utilisé, il m'affiche bien que le pseudo est déjà utilisé
- mais lorsque je saisie un pseudo, aucun message ne s'affiche...

Pour ceux qui voudrait voir la bête en action :
http://musemessenger.com/Sylvain/form.php

Je sais que ça fait beaucoup de code pour quelqu'un qui ne baigne pas dedans, mais vraiment là je vois pas d'où vient l'erreur
Voici la réponse à ta requête :

connecteBBD, connecteTable, <br />
<b>Warning</b>:  Cannot modify header information - headers already sent by (output started at /homez.53/musemess/www/Sylvain/function.php:31) in <b>/homez.53/musemess/www/Sylvain/verifUsername.php</b> on line <b>15</b><br />
<resultats><resultat dispo="dispo" /></resultats>
ha Smiley lol il y a donc bien une erreur quelque part.

comment as-tu obtenu ce message ?

une idée de comment passer outre ?
Ce message t'indique que tu as déjà envoyé des informations (ouputs) au client et que du coup la modification du header c'est impossible.

header('Content-type: text/xml');

Vérifie qu'il n'y a pas d'outputs avant ce header (notamment dans function.php puisque ça vient de là, ligne 15)

Le message plus haut a été obtenu avec Firebug sous FireFox
Modifié par Ze Nenex (07 Aug 2009 - 13:59)
pourtant dans function.php, ligne 15 je renvois la validation de l'adresse mail... pas du pseudo ! Hors la validation de celle-ci fonctionne Smiley sweatdrop .... Smiley bawling
Tout le problème est là.

Au risque de me répéter, tu ne peux pas modifier le header de ta réponse si tu as déjà effectué un output (print, print_r, echo, ...) auparavant. Donc, et comme te l'a clairement précisé le message, le problème vient de la ligne 15 de function.php.
Et puis honnêtement faire une réponse XML pour "dispo"/"indispo" c'est prendre un tank pour tuer une mouche. Fais un simple die($dispoUsername) et ne touche pas au header. Suffit de récupérer ta réponse avec obj.responseText et non obj.responseXML
étant du genre gros newbie je ne connaissais tout simplement pas obj.responseText... en effet, c'est vachement plus adapté à mon besoin Smiley confused Je viens aussi de découvrir que die pouvait être paramétré (il me semblait que c'était juste l'arrêt du script... point barre...)

j'ai donc suivi ton conseil

verifUsername.php
<?php
include("function.php");

// recupération du username
$username = $_POST["username"];
// on verifie que le username est dispo
if($username != "" && verifDispoUsername($username)) {
	$dispoUsername = "dispo";
} else {
	$dispoUsername = "indispo";
}
if($username == '')
	$dispoUsername = "vide";

die($dispoUsername);
?>


function.js
function afficheDispo(obj) {
	username_alert = document.getElementById('username_alert');
	// suppression du texte existant
	while(username_alert.firstChild != null) {
		username_alert.removeChild(username_alert.firstChild);
	}
	
	// Construction des noeuds
	var tabResult = obj.responseText.getElementsByTagName('resultat');
	var resultat = tabResult.item(0);
	var dispo = resultat.getAttribute('dispo');
	
	// creation du message suivant le cas
	if (dispo == "dispo") {
		var texte = document.createTextNode("Le nom d'utilisateur est disponible");
		username_alert.appendChild(texte);
	} else {
		if (dispo == "indispo") {
			var texte = document.createTextNode("Le nom d'utilisateur n'est pas disponible");
			username_alert.appendChild(texte);
		}
	}
}


cela-dit, je n'ai toujours pas trouvé où était le problème dans function.php ... ligne 15 il y a ceci

if (preg_match($regex, $email)) {
	[b]return true;[/b]
}
else {
	return false;
}


D'ailleurs je viens de voir que c'était vraiment pas optimisé comme code ^_^' Je vais résumer ça sur le champ
Modifié par SylvainVV (07 Aug 2009 - 14:41)
Voici ta réponse pour un username dispo:
a écrit :
connecteBBD, connecteTable, dispo


Le problème précédent venait déjà de "connecteBBD, connecteTable, " qui sont output bien avant ton $dispoUsername. Toi seul sait où et pourquoi, mais le warning sur ton header XML vient de là.

Bon courage.
en effet, j'affichais des "connecteBBD, connecteTable, " y'a pas mal de temps... et j'avais oublié de ré-uploadé la version de function.php om ils n'apparaissaient plus.

la bonne version est de nouveau en ligne, mais le problème est toujours là Smiley confused

c'est pas facile facile ce genre de programmation mine de rien... c'est un métier...
Tu peux faire plus court
// recupération du username
if(isset($_POST['username'])) {
  $username = $_POST['username'];
  die(!$username ? 'vide': verifDispoUsername($username) ? 'dispo': 'indispo');
}
Aussi, en PHP, inutile d'employer des double quote si tu n'y inclue pas de variables, ça réduit le boulot du parseur.
merci pour la simplification et le conseil, mais j'arrive toujours pas à trouver pourquoi seul la vérification du pseudo ne fonctionne pas alors que tout le reste fonctionne.
Personnellement j'aurais plutôt envoyé une réponse brute type 1, -1 ou 0. Ça te permet de réutiliser le script dans un tout autre contexte et de séparer la vue ("dispo", "pas dispo", "vide") de la réponse métier (1, -1, 0). C'est au contrôleur de savoir quoi faire de cette réponse, incarné par ta fonction afficheDispo.

Bon courage pour la suite.

[Edit] Parce que ta fonction afficheDispo est fausse:
function afficheDispo(obj) {
	var username_alert = document.getElementById('username_alert');
	// suppression du texte existant
	// C'est là qu'un -1: 1 est mieux puisque tu peux parseInt la réponse.
	if(username_alert) {
		username_alert.innerHTML = obj.responseText == "dispo" ? 
			"Le nom d'utilisateur est disponible":
			"Le nom d'utilisateur n'est pas disponible";
	}
}

Modifié par Ze Nenex (07 Aug 2009 - 15:55)
en effet, bon petit conseil toujours bon à prendre Smiley cligne Je mets ça en place dès que j'ai trouvé d'où vient le bug.

D'ailleurs si quelqu'un à une idée...
responseText n'est pas un document XML
Dans la plupart des cas c'est du "text/html" voire du "text/plain" que tu récupères tel quel. Voir l'édition de mon précédent message.
Wow... impécable ! Ca marche nickel !

Vraiment un gros merci à vous tous pour cette aide.

Une dernière question. Je suis pas vraiment habitué à ces écritures "raccourcies"... et du coup je ne vois pas avec cette écriture de afficheDispo comment tester si verifUserName retourne la valeur "vide" pour afficher "Vous devez saisir un nom d'utilisateur".
Modifié par SylvainVV (07 Aug 2009 - 16:48)
Il s'agit de l'opérateur ternaire.
Dans sa forme basique: condition ? if true: if false;

Exemple en javascript
var num = 3;
alert(num > 0 ? "yes": "no"); // yes

Comme l'opérateur renvoie une valeur, tu peux l'utiliser comme le résultat d'une opération (l'assigner à une variable, retour d'une fonction, en paramètre à une fonction, ...). Il est également possible de "concaténer" des opérations ternaires
var num = 3;
alert(num > 3 ? "superieur": num < 3 ? "inferieur": "egal"); // egal

Je te laisse tester et l'adapter à ton code, rien de bien difficile Smiley cligne