Page 1 sur 2

Ajax : simuler soumission de formulaire...

Publié : 23 mai 2007, 14:08
par calimo
Bonjour,

Eh oui, je suis en train de me mettre à Ajax (c'est surtout mon bureau qui devrait être décapé à l'ajax, mais voilà, ça viendra plus tard :lol: )

Je m'explique.
J'ai une base de données (mysql) avec des données dedans.
Je suis en train de construire un formulaire pour permettre aux utilisateurs (il se trouve par hasard que l'utilisateur principal, d'ici quelques mois, ce sera moi) d'exporter ces données (ou une partie de ces données selon les options choisies).
Donc voilà, on coche les champs, on soumets, on a les données qu'on veut.

Le truc, c'est qu'on sait jamais à l'avance combien d'enregistrements on va sortir. Donc j'aimerais que les utilisateurs (moi) aient un petit aperçu de ce que leur requête va retourner (un nombre de 0 à quelques centaines d'enregistrements). C'est là qu'Ajax entre en jeu (si vous voyez autre chose, n'hésitez pas !). À chaque fois que l'utilisateur change sa sélection, ce serait super-cool de pouvoir afficher combien d'enregistrements vont être retournés.

Comme j'ai déjà le script qui génère la requête sql et tout, le plus simple pour moi serait de pouvoir soumettre le formulaire via XMLHttpRequest, donc passer tous les paramètres dans un GET... est-ce possible en javascript ? Évidemment il ne faut pas soumettre la page (pas de form.submit qui redirigerait l'utilisateur directement sur ses résultats...)

Des idées ?
Merci d'avance :-)

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

PS : je pourrais construire l'url manuellement, mais il y a des <select multiple>, des boutons radio, des champs texte, prochainement des checkboxes, donc c'est un peu le bordel... si c'était possible de tout exporter d'un coup ça m'arrangerait 8-)

Publié : 23 mai 2007, 17:30
par arisss
Ah Calimo,
Je pourrai me venger de toutes tes réponses très agressives sur l'utilisation du Javascript mais je ne le ferai pas.
Bon courage.

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 24 mai 2007, 09:03
par calimo
Bon, déjà je crois que je n'ai jamais été agressif :wink:

Ensuite, si je critique souvent le javascript, c'est sa mauvaise utilisation (qui rend un site inaccessible ou difficilement accessible), et non pas javascript lui-même :wink: Si tu pense qu'il s'agit d'une mauvaise utilisation de javascript, vas-y, ne te gène pas pour argumenter, je suis très ouvert :wink:

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 24 mai 2007, 11:21
par calimo
Bon bon, vu que ça ne saute aux yeux de personne, je me suis fait une petite fonction pour construire l'URL :

Code : Tout sélectionner

function makeURL() {
	var url = "export.cgi?format=ajax";
	url += "&sexe=" + getValRadio(document.getElementsByName('sexe'));
	url += "&categorie=" + getValRadio(document.getElementsByName('categorie'));
	url += "&stroke=" + getValRadio(document.getElementsByName('stroke'));
	if (document.getElementById('age_de').value) {
		url += "&age_de=" + document.getElementById('age_de').value;
	}
	if (document.getElementById('age_a').value) {
		url += "&age_a=" + document.getElementById('age_a').value;
	}
	var exclude_diseaseBox = document.getElementsByName('exclude_disease')[0];
	for (var i=0; i<exclude_diseaseBox.options.length; i++) {
		if (exclude_diseaseBox.options[i].selected) {
			url += "&exclude_disease=" + exclude_diseaseBox.options[i].value;
		}
	}
	var include_diseaseBox = document.getElementsByName('include_disease')[0];
	for (var i=0; i<include_diseaseBox.options.length; i++) {
		if (include_diseaseBox.options[i].selected) {
			url += "&include_disease=" + include_diseaseBox.options[i].value;
		}
	}
	return url;
}

function getValRadio(radio) {
	for (var i=0;i<radio.length;i++)
		if (radio[i].checked) return radio[i].value;
	return false;
}
Notez la fonction getValRadio (c'était le plus compliqué) qui demande une liste des éléments <input> du groupe, obtenu par document.getElementsByName('nameRadioGroup') :)

Pour le reste, je réutilise plus ou moins ce qu'on trouve dans la doc de Mozilla...

Code : Tout sélectionner

function makeRequest(url) {
	//alert (url);
	var httpRequest;

	if (window.XMLHttpRequest) { // Mozilla, Safari, ...
		httpRequest = new XMLHttpRequest();
		//if (httpRequest.overrideMimeType) {
		//	httpRequest.overrideMimeType('text/xml');
			// See note below about this line
		//}
	} 
	else if (window.ActiveXObject) { // IE
		try {
			httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
		} 
		catch (e) {
			try {
				httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
			} 
			catch (e) {}
		}
	}

	if (!httpRequest) {
		alert('Giving up :( Cannot create an XMLHTTP instance');
		return false;
	}
	httpRequest.onreadystatechange = function() { alertContents(httpRequest); };
	httpRequest.open('GET', url, true);
	httpRequest.send(null);
	return true;
}

function alertContents(httpRequest) {
	if (httpRequest.readyState == 4) {
		if (httpRequest.status == 200) {
			var MyResponse = httpRequest.responseXML;

			var rowsTag = MyResponse.getElementsByTagName('rows')[0];
			var sqlTag = MyResponse.getElementsByTagName('sql')[0];
			if (rowsTag.textContent) { // pour les navigateurs récents (DOM niveau 3 ?)
				var rows = rowsTag.textContent;
				var sql = sqlTag.textContent;
			}
			else { // pour les autres, on prend la valeur du noeud du premier enfant (devrait être équivalent)...
				var rows = rowsTag.firstChild.nodeValue;
				var sql = sqlTag.firstChild.nodeValue;
			}
			var InsertBlock = document.getElementById('numpatients');
			InsertBlock.innerHTML = 'Patients : ' + rows + '<br>Requête : <code>' + sql + '</code>';
			//alert('done');
		}
	}
}

window.onload = function() {
	var inputs = document.getElementById('formExport').elements;
	makeRequest(makeURL());
	for (var i = 0; i < inputs.length; i++) {
		inputs[i].setAttribute('onchange', "makeRequest(makeURL())");
	}
}
Cela dit, lorsque je rajouterai un champs, il faudra modifier la fonction, donc si quelqu'un a la soluce pour simuler une soumission et récupérer l'url générée, ça m'intéresse toujours :wink:

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 24 mai 2007, 12:26
par Ariss
oui j'ai bien dit "sur l'utilisation du Javascript"...

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 24 mai 2007, 12:33
par guilhem_mdg
Bonjour Calimo,
Je n'ai pas lu tout ton code. Mais tu devrais générer un fichier XML via PHP et ensuite le parser grâce au bout de code suivant :

Code : Tout sélectionner

var doc = xhr_object.responseXML;
for(var i=0;i<doc.getElementsByTagName('nomDuNoeud').length;i++)
var=doc.getElementsByTagName('nomDuNoeud').item(i).firstChild.data;
Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 24 mai 2007, 13:18
par calimo
Mon problème n'est pas au niveau du traitement sur le serveur (j'ai déjà un script qui génère la requête à partir des paramètres passés et produit un fichier xml), ni du traitement de ce fichier XML (j'affiche sans problème les données), mais avant, au niveau de la génération de l'url à appeler :wink:

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 24 mai 2007, 14:08
par guilhem_mdg
Bon je ne suis pas sur d'avoir bien compris ton problème mais je te conseille d'utiliser le traitement en POST plutôt qu'en GET, tu ne seras pas ennuyé avec l'encodage, ni la longueur des urls.
Voici un code que tu peux utiliser :

Code : Tout sélectionner

<script>
function makeRequestPostXML(url,parametres){
	var xhr_object = null;
	if(window.XMLHttpRequest)
		xhr_object = new XMLHttpRequest();
	else
		if(window.ActiveXObject)
			xhr_object = new ActiveXObject("Microsoft.XMLHTTP");
		else{
			alert("Votre navigateur ne supporte pas les objets XMLHTTPRequest...");
			return;
		}

	var method = "POST";
	var filename = url;
	var data = parametres;
	xhr_object.open(method, filename, true);

	xhr_object.onreadystatechange = function(){
		if(xhr_object.readyState == 4){
			var doc = xhr_object.responseXML;
			for(var i=0;i<doc.getElementsByTagName('noeud').length;i++)
				maVariable=doc.getElementsByTagName('noeud').item(i).firstChild.data;
		}
	}

	xhr_object.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	xhr_object.send(data);
}
</script>
url = l'url est celle de ton script PHP avec un header XML... et parametres tes variables d'url (ex. &var1=toto&var2=tata,...)
Mais peut-être as-tu du mal à générer cette url ?

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 24 mai 2007, 14:14
par martin
Construis ton url dynamiquement, en parcourant tous les éléments du formulaire.

quelque chose du genre :

Code : Tout sélectionner

var myForm = document.forms["myFormName"];
// ou myForm = document.getElementById("myFormId");

var myUrl = "";
for (var i = 0; i < myForm.elements.length ; i++) {
    myUrl += (myUrl == "") ? "" : "&";
    myUrl += myForm.elements[i].name + "=";
    myUrl += encodeURIComponent(myForm.elements[i].value);
}
myUrl = "www.example.org/mypage.php?" + myUrl;
Sinon la bibliothèque ie7-xml-extras.js de Dean Edwards est bien pratique pour pouvoir n'utiliser que la formulation de mozilla de XMLHttpRequest tout en restant compatible avec IE ;) .

Publié : 24 mai 2007, 15:18
par calimo
martin a écrit :Construis ton url dynamiquement, en parcourant tous les éléments du formulaire.

quelque chose du genre :

Code : Tout sélectionner

var myForm = document.forms["myFormName"];
// ou myForm = document.getElementById("myFormId");

var myUrl = "";
for (var i = 0; i < myForm.elements.length ; i++) {
    myUrl += (myUrl == "") ? "" : "&";
    myUrl += myForm.elements[i].name + "=";
    myUrl += encodeURIComponent(myForm.elements[i].value);
}
myUrl = "www.example.org/mypage.php?" + myUrl;
Sinon la bibliothèque ie7-xml-extras.js de Dean Edwards est bien pratique pour pouvoir n'utiliser que la formulation de mozilla de XMLHttpRequest tout en restant compatible avec IE ;) .
Sauf que ça ne marche pas s'il y a des boutons (checkbox, radio), des select, des champs texte vides... bref, c'est justement cette étape là que j'aimerais éviter :-)
(En plus form.elements sort aussi les fieldset, legend et cie.. :? :roll: )

Mais merci quand-même pour votre aide :D

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 24 mai 2007, 15:31
par guilhem_mdg
Bah tu peux personnaliser la fonction en mettant des conditions (uniquement les inputs et select par ex. ou bien les champs dont name="form_..."), non ?


Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Code : Tout sélectionner

document.forms[0].elements[i].type
ou

Code : Tout sélectionner

document.forms[0].elements[i].name

Publié : 24 mai 2007, 16:44
par calimo
guilhem_mdg a écrit :Bah tu peux personnaliser la fonction en mettant des conditions (uniquement les inputs et select par ex. ou bien les champs dont name="form_..."), non ?
Bien sur, c'est d'ailleurs ce que je fais ! :wink:

Mais en gros, je dois reprendre chaque champ un a un manuellement, ce n'est pas évolutif (quand j'ajoute un champ, je dois rajouter du code, quand je le renomme, changer le code), pas très propre (beaucoup de code), bref, ça a tous les désavantages, d'où ma volonté de savoir si on pouvait faire ça en une seule ligne :P

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 24 mai 2007, 17:21
par martin
je plussoie guilhem_mdg, genre dans la boucle for que je t'ai proposée, rajoute un test pour ne traiter que les champs portant un début de nom spécifique :

Code : Tout sélectionner

if (myForm.elements[i].name.substr(0, 5) == "form_") {
    //... compléter l'url
}

Publié : 25 mai 2007, 09:44
par calimo
Ok, donc il n'y a pas vraiment de "bonne solution" :(

Merci quand-même pour votre aide :wink:

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3

Publié : 25 mai 2007, 11:01
par guilhem_mdg
Euh Calimo, j'ai l'impression que tu voudrais un code qui devine ce que tu veux faire. Ca n'existe pas encore !

Il faut bien à un moment donné ennoncer une règle :
Ex. lister tous les champs (champs + valeurs) d'un formulaire afin de construire une url. Sauf, les champs label, fieldset, form et ceux dont le nom commencent par xxx_

Tu ne crois pas ?

Ou bien, tu n'as pas été assez explicite... :wink:

Message envoyé avec : Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3