Pages :
Bonjour à tous...

Avant de remplir le formulaire complet d'un nouvel aliment et d'afficher
ensuite "Cet aliment existe déjà dans la bdd" j'aimerai qu'en quittant
le premier champ "désignation" (un input type texte) une fonction
JavaScript fasse un appel sur une page php qui vérifie si le produit
n'est pas déjà enregistré dans la table "aliments".

Si je post ici c'est que je ne sais pas quoi chercher pour trouver soit un
tuto soit un exemple fonctionnel, car je ne suis arrivé à rien avec ce que
j'ai essayé jusqu'à maintenant.

J'ai essayé avec onBlur="verifnom(this.value)" dans ma balise <input>.
J'affiche bien un message d'erreur si l'aliment ne fait que 2 caractères mais je ne sais
pas comment déclencher un appel vers ma page verifaliment.php et surtout
comment rapatrier l'info "existe" ou "n’existe pas" en retour....

Merci d'avance pour vos pistes ou votre aide !
Modifié par etienne69 (02 Dec 2014 - 14:11)
Merci Zelalsan de te pencher sur mon problème, mais ta réponse n'est pas
vraiment un scoop...je veux dire que je m'attendais à ce que l'on me réponde
ça.

Edit : en même temps, je n'avais pas vu le point n°2 dans ta signature ! Smiley biggrin

J'aurais plutôt aimé un bout de code ou mieux un tuto pour que je comprenne au lieu
de copier bêtement !

J'ai suivi des tutos pour des datepicker et des exemples pour des filtres sur base
de données à l'aide de jQuery qui fonctionnent parfaitement une fois adaptés à
mon application Web, mais en ce qui concerne un contrôle de saisie d'input, un truc
qui semble simple au départ, je ne trouve rien de fonctionnel... J'ai bien des pistes
sur d'autres forum mais les lignes de codes sont pleines d'erreurs et ne fonctionnent
pas (manque des ; dans le JavaScript, code pas indenté : pas facile pour débuter ou
comprendre !) ou mieux des gars qui remercie pour les tuyaux qu'on leur a donnés
sans balancer le code final qui fonctionne ou le pourquoi de leurs erreurs !
Modifié par etienne69 (03 Dec 2014 - 07:19)
Bonjour,

Plutôt que de demander un bout de code fonctionnel (cf aide), il faudrait commencer par poster d'abord un exemple de là où tu en est actuellement, même si cela ne fonctionne pas encore parfaitement.
Ah Smiley biggrin Pourtant j'étais sûr que ma réponse suffirait à résoudre ton problème.
Si tu savais déjà que c'est en Ajax que ça se fait, je pense que tu aurais pu faire ce que tu souhaites.
Il suffit de passer la valeur ton <input> après un évènement "change", via Ajax au fichier php qui effectuera la vérification. Puis de récupérer la réponse du fichier php (qui devra la renvoyer via un "echo", par exemple "existe") et d'appliquer une condition pour choisir l'action à faire.
Simple je dirais.

function check(){
	
	var xmlObj;
	
	(window.XMLHttpRequest) ? (xmlObj = new XMLHttpRequest()) : (window.ActiveXObject) && (xmlObj = new ActiveXObject("Microsoft.XMLHTTP" ));
	
	xmlObj.onreadystatechange = function(){
	
		if (xmlObj.readyState==4) return xmlObj.responseText;
		
	}
		
	xmlObj.open("POST", fichierTraitant, true);
	xmlObj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xmlObj.send(tonInput.value);
	
}

function verification(){
	
	if (check() == "existe") {
		// ...
	}else {
		// ...
	}
	
}

var fichierTraitant = "chemin/fichier.php",
	tonInput = document.getElementById("nom");

tonInput.addEventListener("change", verification, false);


Par contre ce code est très minimaliste et il pourrait y avoir des erreurs lors de la réponse, ce qui faussera la condition faite dans la fonction "verification".
J'ai fait ça de tête donc faut voir si ça correspond.
Bah, en fait, j'ai rien...! Smiley decu

Voila la structure de mon formulaire :

Le champ input du formulaire :
J'aimerai déclencher la vérification à la sortie du champ "nom" avec onBlur
La <div id="namebox"> devra afficher un message d'erreur précisant que l'aliment "nom"
est déjà présent dans la base de donnée...
<input type="text" name="nom" id="nom" size="60" maxlength="60" value="" onBlur="verifnom(this.value)" required /><br /><div id="namebox">


Ma table où sont stockés les aliments s'appelle "aliments" et le champs à vérifier
s'appelle "aliment_nom".

Je sais "simplement" qu'il me faut un appel en sortie de champ input sur une instruction Javascript
qui récupère la valeur du champ et appelle une page php qui va interroger la base de donnée
à la recherche de l'existence de l'aliment. Cette même page php retournera au code Javascript
un drapeau '1' existe déjà ou '0' pas trouvé dans la base affichant un message dans la <div id="namebox">.

La page suivante qui enregistre l'aliment (ou pas si déjà présent) fonctionne très bien. Ma demande est juste "un plus" pour éviter à l'utilisateur d'avoir à remplir le formulaire en entier et se retrouver avec un message d'erreur indiquant "désolé, vous avez perdu du temps pour rien, car cet aliment existe déjà !"
Nickel Zelalsan pour ce bout de code....

J'va le décortiquer, l'essayer et te dire en retour ce que ça
donne

(ce soir car je file au taf)

Merci en attendant !
@audrasjb
J'ai posté sur cette partie du forum car je n'ai jamais fait de Javascript de
ma vie et encore moins d'Ajax... Je trouve ça pas mal et ça me change du
PHP et css... Mais tu as raison, un code tout fait ne me permettra pas d'apprendre.
Il faut toutefois reconnaître que ce que j'ai trouvé sur Internet pouvant correspondre
à mon problème était extrêmement compliqué !
Je vais donc y aller tout doucement pour comprendre !


A l'aide de ta réponse Zelalsan et du correcteur JS de la console de Firefox
j'ai écris ce petit bout de code qui semble fonctionner car j'ai une fenêtre alerte
qui apparaît à la fin de mon traitement :

HTML :
<input type="text" name="nom" id="nom" size="60" maxlength="60" value="" onChange="check (this.value)" required /><br /><div id="namebox"></div> <br /><br />


AJAX : (Je pense avoir compris chaque ligne, c'est après que ça ce complique...)
<script type="text/javascript">
function check(){
	var xhr = new XMLHttpRequest ();

	xhr.onreadystatechange = function(){
		if (xhr.readyState ==4){
		alert('TERMINE');
		}
	}
		var value = encodeURIComponent(nom.value);
		xhr.open ('POST','verifaliment.php', true);
		xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
		xhr.send(value);
}

</script>
 

[Edit : Je n'ai pas fait de partie concernant IE car c'est pour une appli locale et je suis en Linux]

Je vais donc m'attaquer à ma page verifaliment.php, mais petite question : comment
s'appelle la variable que je récupère dans le $_POST ?

[Edit n° 2 : $_POST['nom'] ? ]
Modifié par etienne69 (04 Dec 2014 - 22:54)
Bin c'est bien vu qu'apparemment tu t'es donné la peine de comprendre le code et de l'adapter Smiley biggrin .
Comme j'avais fait ça de tête, j'ai écris trop vite. Il faut bien sûr spécifier le nom de ta variable "post" lors de l'envoi :

xhr.send("NomDeVariable="+value);

Si tu veux en envoyer plusieurs, tu dois les séparer par "&".

PS : Par contre tu devras aussi gérer les autres types de réponses pour "readyState" afin de bien maîtriser ce que tu fais.
Merci...

J'ai trouvé ce bout de code dans mon bouquin :

xhr.onreadystatechange = function(){
     if (xhr.readyState ==4){
          alert('TERMINE');
     }

     else if (xhr.readyState == 4 && xhr.status != 200) {
          alert('Une erreur est survenue !\n\nCode :' + xhr.status + '\nTexte : ' + xhr.statusText);
     }
}

//et corrigé comme ça :

xhr.send("nom="+value);





Je suppose que cela ne doit gérer que les erreurs JavaScript car j'ai viré ma page
"verifaliment.php" et il m'affiche rien à part mon alerte "TERMINE"... Je ne
peux donc pas le tester apparemment...


D'autre part, comment vérifier que la page "verifaliment.php" est bien appelée car j'ai mis
un alert('OK') dessus qui ne s'affiche pas.
Je vois pleins de codes sans accolades pour des if / else/ else if...

Ce code est il faux ?
if (xhr.readyState ==4) {
     return xhr.responseText;
}

Ou dois-je utiliser le tien ?
if (xhr.readyState==4) return xhr.responseText;

Modifié par etienne69 (05 Dec 2014 - 08:33)
Je n'ai pas trop compris ce que tu veux dire mais la page à appeler ne devra contenir que du PHP et la réponse renvoyée se fera avec un "echo".
La réponse dans cet exemple(xhr.responseText) n'est autre que le contenu de la page appelée. Si tu veux afficher ce contenu, tu dois "écrire" cette réponse dans ton document actuel avec un ".innerHTML". Tu comprendras par la même occasion que dans ce cas, ce contenu ne devras pas avoir la structure normal d'un document HTML (avec les balises <html> <head>...) car si non, le tout sera inséré tel quel et tu te retrouveras avec une page HTML insérée dans une autre.

etienne69 a écrit :
Je vois pleins de codes sans accolades pour des if / else/ else if...

Ce code est il faux ?
if (xhr.readyState ==4) {
     return xhr.responseText;
}

Ou dois-je utiliser le tien ?
if (xhr.readyState==4) return xhr.responseText;

Les deux sont justes. Lorsqu'il n'y a qu'une seule ligne d'instruction, on peut se passer des accolades.
Modifié par Zelalsan (05 Dec 2014 - 09:23)
Zelalsan a écrit :
Je n'ai pas trop compris ce que tu veux dire...

Tu m'as dit de gérer les autres types de réponses et j'ai pensé que ça ferait
l'affaire :
else if (xhr.readyState == 4 && xhr.status != 200) {
     alert('Une erreur est survenue !\n\nCode :' + xhr.status + '\nTexte : ' + xhr.statusText);
}

Sauf que je ne sais pas si c'est fonctionnel... Alors j'ai voulu créer une erreur en supprimant
l'accès à "verifaliment.php" (en renommant le fichier en "verifaliment.old") mais aucun message
n'est apparu, d'où ma remarque sur le
fait que cette fonction Javascript (=!200) ne concerne qu'une vérification de Javascript...J'espère
qu'elle est correcte, en tout cas, le correcteur de Firefox ne m'affiche rien !

J'ai voulu aussi vérifier si mon code JavaScript accédait à ma page verifaliment.php avec un
alert, mais effectivement, si cette page ne doit contenir que du PHP, cette fonction JavaScript n'est
pas prise en compte et je ne sais pas si la recherche dans la table est bien déclenchée !


Maintenant ma page PHP... (je sais, c'est pas PDO, mais je suis en train de tout refaire en PDO...)

<?php
     if (isset($_POST['nom'])){
         // Connexion à la base de données :
          include("connexion.php");
 
         // Sécurisation & formatage du nom de l'aliment :
	 $nom = mysql_real_escape_string(htmlspecialchars($_POST['nom']));
	 $nom = mb_strtoupper($aliment_nom,'UTF-8');

         // Vérification de la présence ou non du nouvel aliment dans la base
	 $requete = "SELECT count(*) as nb FROM menu_aliments WHERE aliment_nom = '".$nom."'";
	 $req_exec = mysql_query($requete) or die(mysql_error());
	 $resultat = mysql_fetch_assoc($req_exec);
	 if (isset($resultat['nb']) && $resultat['nb'] >=1){
	      echo "1";
	 }
	 else {
	      echo "2";
	 }

         // Fermeture connexion 
	 mysql_close();
     }
?> 


J'ai bon ? Smiley rolleyes
Modifié par etienne69 (05 Dec 2014 - 14:22)
Au fait, je lis que .innerHTML est pour éditer ou ajouter du contenu HTML...
Dans la mesure où je souhaite récupérer un "1" ou un "2" en provenance de
mon "verifaliment.php", ne devrais-je pas plutôt utiliser .innerText ?
(ou dans mon cas Linux/Firefox : textContent)
etienne69 a écrit :

Tu m'as dit de gérer les autres types de réponses et j'ai pensé que ça ferait
l'affaire :

else if (xhr.readyState == 4 && xhr.status != 200) {
     alert('Une erreur est survenue !\n\nCode :' + xhr.status + '\nTexte : ' + xhr.statusText);
}

Je pense que c'est ta condition qui est mal faite :

if (xhr.readyState == 4 && xhr.status == 200) {
	// ...Bon
}else {
	// ...Mauvais
}

etienne69 a écrit :

J'ai voulu aussi vérifier si mon code JavaScript accédait à ma page verifaliment.php avec un
alert, mais effectivement, si cette page ne doit contenir que du PHP, cette fonction JavaScript n'est
pas prise en compte

En fait ce n'est pas qu'elle ne doit contenir que du PHP car si non ça ne marcherait pas, c'est juste pour cet exemple. Tu peux très bien afficher une alerte JS en mettant dans ta page appelée

<script>alert("Ok !")</script>

Puis d'écrire la réponse dans ton document :

document.body.innerHTML += xhr.responseText;

Mais dans ton cas précis, tu n'auras besoin que de PHP.
Normalement avec le script que tu as fait, tu auras donc comme réponse soit "1" soit "2".
Et au passage, oui tu devrais revoir ta partie BDD. Passe aussi par les requêtes préparées au lieu d'insérer comme ça directement ta valeur.
etienne69 a écrit :
Au fait, je lis que .innerHTML est pour éditer ou ajouter du contenu HTML...
Dans la mesure où je souhaite récupérer un &quot;1&quot; ou un &quot;2&quot; en provenance de
mon &quot;verifaliment.php&quot;, ne devrais-je pas plutôt utiliser .innerText ?
(ou dans mon cas Linux/Firefox : textContent)

Tu n'as besoin ni de l'un, ni de l'autre. Ta valeur est directement celle renvoyée par la fonction "check".
@Zelalsan
Je pense que le code que tu as posté ne fonctionne pas car au moment où tu vas appeler la fonction check le résultat de la requête sera bien loin d'être arrivé, la fonction check retournera donc systématiquement void si je ne m'abuse (peut-être qu'il y a quelque chose que je n'ai pas saisi dans ton exemple).

De plus: la valeur de retour de ton xmlObj.onreadystatechange ne sera jamais exploitable le return n'a pas la bonne portée. Il faudra nécessairement passer par un système de callback (encapsulé ou pas dans un objet), exemple en partant de ton code :

function check( callback ) {
	[...]
	xmlObj.onreadystatechange = function(){

		if ( xmlObj.readyState==4 && xhr.status == 200 ) {
                      callback( "succes", xmlObj.responseText  );
                } else {
                       callback( "error", null );
                }
		
	}
    	[...]
}

function verification(){
	
	check( function( etatReponse, donneesServeur ){
                if ( etatReponse === 'succes' ) {
                     // super ça a marché je peux utiliser les données récupérées
                     console.log(donneesServeur);
                } else {
                     // Une erreur est survenue durant l'appel au serveur
                     alert('FAIL');
                }
        } );
	
}


Au niveau événementiel ça risque de mieux marcher Smiley cligne
@Freez> Super bien vu ! Bien sûr que ce que tu dis est vrai. J'ai été trop négligeant en écrivant ce code (j'ai fait rapidement de tête au passage). En revoyant, j'ai été trop facile.
Pages :