11484 sujets

JavaScript, DOM et API Web HTML5

Pages :
Bonjour à tous
Habituellement, j'utilise AJAX en JSON, mais pas à partir d'un formulaire.
J'ai trouvé plein de choses sur Internet à ce sujet, mais je ne parviens pas à le faire fonctionner.
Mon formulaire à l'allure suivante (j'enlève les <label> et autres choses qui ne sont pas à transmettre)

<form>
  <input name="uploadedfile" type="file" >
  <input id="meeting" name="meeting" type="text">
  <input name="meetingDate" type="date">
</form>

Sur un clic, je lance un programme qui vérifie le contenu et lance la soumission en AJAX

function uploadStart() {
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if(this.readyState == 4 && this.status == 200) {
			uploadEnd(this.responseText);
			return;
		}
	}
	xhr.open('post', 'upload1.php');
	xhr.send(UPLOADFORM);
}

UPLOADFORM est une variable qui contient l'élément <form>
Le programme upload1.php est bien lancé mais ne reçoit rien: $_REQUEST est vide et ne contient même pas les cookies.
Modifié par PapyJP (20 Mar 2020 - 11:17)
Hello,

petit hors sujet: un form est prévu pour envoyer des données à un PHP au départ Smiley cligne
Sinon je ne vois pas l’intérêt de passer par un ajax quand tu as un form.
Ou l’intérêt de mettre un form si tu fais un ajax derrière.
Enfin c'est mon avis.

Sinon Jean-Pierre, très sympa ta méthode, à mon sens c'est une bonne solution pour mélanger les deux Smiley cligne
Merci JP
JQuery? C’est quoi ça? Smiley cligne
Bien avant que jQuery soit inventé j’avais constitué ma propre librairie de fonctions, et je continue à l’enrIchir.
J’ai fait quelques essais avec jQuery et décidé de ne pas me compliquer la vie en changeant mes habitudes de codage sans intérêt probant. Du temps où on devait jongler entre les incompatibilités entre IE et Netscape ça pouvait se comprendre mais plus maintenant, quoique les récentes versions de IE ne soient toujours pas compatibles avec le reste du monde. Je sais que ça peut poser des problèmes pour les gens qui voudraient consulter mes sites depuis un PC de société, mais ça n’a pas l’air d’être gênant.
Je vais essayer de m’inspirer de ton code.
stryk a écrit :

Sinon je ne vois pas l’intérêt de passer par un ajax quand tu as un form.
Ou l’intérêt de mettre un form si tu fais un ajax derrière.

Un <form> c’est une interface homme machine, AJAX c’est une interface client serveur. On peut bien entendu mettre des <input> en dehors d’un <form> mais si on veut utiliser AJAX on est amené à réutiliser les <input> donc à devoir faire des reset, etça ne peu se faire que sur un <frame>. Il
Modifié par PapyJP (20 Mar 2020 - 13:35)
@Jean-Pierre: Oui oui , enfin je parlais de récupérer le form vers le XMLHttpRequest Smiley cligne
Pour tout ce qui est SESSION, PHP permet nativement de gérer ça !

PapyJP a écrit :
Un form c’est une interface homme machine

Je dirais que les input sont des interfaces et que le form est un conteneur conçu pour envoyer tout ça au PHP Smiley cligne ( bien qu'on puisse envoyer où on le souhaite )
pardonnez moi, je n.ai pas encore eu le temps de m’y mettre.
Je vous fait des réponses plus circonstanciées dans l’apr
Ce que je comprends c'est que tu prends les variables qui sont dans le <form> et que tu les envoies en AJAX, (mode get) ce que j'ai bien sûr essayé de faire en premier (mai en mode post, je ne crois pas que ça change grand chose).
Ce qui me préoccupe, c'est que ma première input est une input de type "file", et je ne comprends pas très bien comment traiter ces données.
Je vais essayer autrement pour comprendre comment ça fonctionne.
A ma connaissance ajax renvoi un chemin de fichier faux !
Seul le PHP permet d'avoir un chemin de fichier valide.

Donc pas trop le choix il faut passer par un form -> PHP
( enfin je n'ai jamais réussi à faire ça en full front JS )
Je comprends tout à fait comment ça fonctionne Smiley smile
Juste je me pose la question de l’intérêt d'un form ...
Par exemple ceci ne donnerai pas le même résultat ?


<!DOCTYPE html>
<html>

	<head>
		
		<script>
		
			const MonSuperAjax = function () {
	
				const dataToSend = document.getElementById(getDate).value;
				
				let MonAjax = new XMLHttpRequest();
				MonAjax.open('POST',"a_ajax.php",true);
				MonAjax.addEventListener('readystatechange', function() {

					if ( MonAjax.readyState === XMLHttpRequest.DONE && MonAjax.status === 200 ) {

						document.getElementById('Ldate').innerHTML = MonAjax.responseText;

					}

				});

				MonAjax.setRequestHeader('Content-type','application/x-www-form-urlencoded');
				MonAjax.send(dataToSend);
				
			};
			
		</script>

	</head>

	<body>
	
		<div class='blogsaisie' id="Ldate">
			<h2>Lancez la question au serveur en tapant date et validez</h2>
		</div>
		
		<input id="getDate" type="text">
		<button onclick="MonSuperAjax();"><button>
		
	</body>
	
</html>
La solution que j'ai trouvée

form id="uploadForm" onsubmit="return false">
	<input type="file">
	<input type="text" name="meetingType" value="CA">
	<input type="date" name="meetingDate" value="2020-03-20">
	<button onclick="uploadFile('uploadForm')">Upload</button>
</form>


function uploadFile(formID) {
	var form = document.getElementById(formID);
	var filenode = form.querySelector('[type="file"]');
	var fileObject = filenode.files[0];
	var meetingType = form.querySelector('[name="meetingType"]');
	var meetingDate = form.querySelector('[name="meetingDate"]');
	var formData = new FormData();
	formData.append('file', fileObject);
	formData.append('meetingType', meetingType.value);
	formData.append('date', meetingDate.value);
	console.log(formData);
	var xhr = new XMLHttpRequest();
	xhr.onreadystatechange = function() {
		if(this.readyState == 4 && this.status == 200) {
			alert(this.responseText);
			return;
		}
	}
	xhr.open('post', 'upload1.php');
	xhr.send(formData);
}

La méthode: construire un FormData contenant les paramètre à transférer, le paramètre "file" étant particulier.
Le résultat affiché par "alert" montre que
$_REQUEST = [
[meetingType] => CA
Smiley date => 2020-03-20
]
et
$_FILES = [
[ name] => CA-2020-01-13.pdf
[ type] => application/pdf
[ tmp_name] => /tmp/phpzIV0kj
[ error] => 0
[ size] => 80859
]

C'est cette façon de traiter les <input type="file"> qui est la clé du problème.
S'il n'y a pas de <input type="file"> dans les données, il est beaucoup plus simple d'envoyer au serveur un objet codé JSON. C'est ce que je fais d'habitude.
Modifié par PapyJP (20 Mar 2020 - 16:19)
Jean-Pierre: non je ne refuse pas du tout.
Je connais très bien ajax (jquery) et encore mieux XMLHttpRequest.
Je l'utilise quotidiennement pour créer des appli, ce n'est pas la question.

En fait ma vrai question, et c'en est une que je me pose:
On peut appeler un PHP avec, soit
1/ un form + appel direct du PHP par le form
2/ un simple bouton + un ajax ( peu importe le type )

Pourquoi utiliser un form + un ajax ?
Quel est la plus valus ?

Ce qui peut aussi répondre à PapyJP pour le souci du passage du pathFile dans un ajax ( je pense que ce n'est pas possible )
PapyJP a écrit :
La solution que j'ai trouvée


Du coup tu peux récupérer le chemin réel du fichier et le télécharger sur le serveur avec cette méthode ?
stryk a écrit :


Du coup tu peux récupérer le chemin réel du fichier et le télécharger sur le serveur avec cette méthode ?

On ne peut pas récupérer le chemin réel du fichier, c'est une contrainte que tous les navigateurs imposent pour des raisons de confidentialité.
Ce qui se passe avec un <input type="file">
1) quand on clique dessus, le navigateur ouvre une fenêtre système qui permet de trouver le fichier que l'on veut chercher
2) il note l'adresse complète quelque part en interne, mais on ne peut pas adresser cette adresse en javascript

Dans un "form avec submit" en mode POST
1) le navigateur envoie des requêtes HTTP qui donnent le contenu des <input>, pour <input type="file"> il envoie le nom du fichier, mais pas le chemin complet
2) Il envoie également, dans une requête HTTP distincte, le contenu du fichier, qu le serveur met dans un répertoire temporaire avec un nom temporaire
3) côté serveur, le programme récupère dans $_REQUEST les valeurs des <input> et dans $_FILES les informations permettant de retrouver le fichier
4) c'est le programme PHP qui fait ce qu'il veut du fichier, généralement le renommer et le mettre dans un répertoire dépendant du design de l'application

Si on fait ça en AJAX, peu importe que ce soit dans une balise <form> ou autre, on effectue les fonctions suivantes
1) créer un objet FormData
2) pour les <input> autres que type="file" on ajoute à l'objet FormData le couple nom/valeur correspondant
3) pour les <input type="file"> on fait la chose suivante:
a) retrouver le nœud correspondant
b) en extraire l'objet files[0] (je ne sais pas si il se peut qu'il y en ait plusieurs, mais c'est un array, il faut donc prendre le 1er)
c) le mettre dans FormData: la gestion de cet objet sait traiter ce cas particulier, car on lui fournit un objet et non un string
4) une fois cela fait on envoie l'objet FormData par AJAX
Voir mon code ci-dessus.

A noter que l'on ne peut pas envoyer des <input type="file"> en mode GET.
stryk a écrit :

Je connais très bien ajax (jquery) et encore mieux XMLHttpRequest.

Problème de vocabulaire
Ajax est l'acronyme d'asynchronous JavaScript and XML : JavaScript et XML asynchrones.
Ce n'est pas une chose qui dépend de jquery, simplement jquery fournit une interface pour l'utiliser, c'est à dire une interface qui, par derrière, utilise XMLHttpRequest.
Comme AJAX uns plus facile à écrire que XMLHttpRequest, on utilise souvent AJAX plutôt que XMLHttpRequest, mais quand on parle de techno, les deux mots veulent dire la même chose.
PapyJP a écrit :
on utilise souvent AJAX plutôt que XMLHttpRequest, mais quand on parle de techno, les deux mots veulent dire la même chose.


Oui enfin pas tout à fait, quand on parle d'Ajax c'est sous entendu en Jquery.
Hein ... y'a pas de méthode nommée Ajax en js natif !
On est du métier on devrait quand même s'entendre sur les termes Smiley cligne
Si mon boss me demande un XHR et que je lui fais un Ajax il va péter un plomb ...
Oui Jquery c'est du Js, oui il utilise XHR derrière pour faire un Ajax, mais bon, c'est deux syntaxes différentes et donc deux choses quand même un peu différentes, je pense par exemple au fait que tu vas avoir du mal à faire du synchrone en XHR alors qu'avec Ajax c'est très simple.
( il ne faut pas faire d'appel synchrone dans un fil asynchrone hein c'est pour l'exemple )

Même si c'est pour vous taquiner, j’essaie de vous tirer les vers du nez et c'est pas facile Smiley lol

Bon l'important c'est que tu ai trouvé ce que tu recherche !!!

Pour en revenir au form, je le répète au risque de vous facher ( alors que y'a pas de raison je suis sympa ^ et c'est pour échanger sur un sujet qu'on aime bien à priori ) :
Un form sert juste à envoyer des valeurs d'inputs dans un PHP !
C'est vieillot et ça servait aaaaaavant pour rediriger vers une autre page PHP.
Maintenant qu'on travaille en front pour éviter de recharger toute la page, on utilise les requêtes asynchrones ( ajax ou perlimpimpin ou ce que tu veux Smiley langue ).
_ Et donc utiliser un form + Ajax n'a aucune utilité !

C'est sur ce dernier point que vous ne m'avez pas répondu Smiley cligne

Voili voulou ...
Bonne nuit messieurs
Amicalement
Concernant AJAX, voir https://fr.wikipedia.org/wiki/Ajax_(informatique)
Il n'y est pas question de jQuery
Ce n'est pas parce que ton équipe de travail semble avoir adopté un vocabulaire que tout le monde utilise le même. La première chose quand on change d'entreprise, ou même d'équipe au sein d'une entreprise, c'est d'acquérir le vocabulaire local.

En ce qui concerne l'utilisation d'un <form> dans ma question initiale, c'est simplement parce que mon code initial, écrit il y a une dizaine d'années travaillait par soumission de formulaire et que je voulais rendre ce code asynchrone sans tout chambouler.
Il est vrai qu'un <form> n'est pas indispensable, mais je ne vois pas l'intérêt que ça présenterait de le remplacer. Remplacer par quoi? Si c'est pour quelque chose comme <div class="formulaire"> ça ne vaut pas vraiment la peine.
La façon dont j'aurais dû intituler ce lien c'est plutôt "Comment soumettre de façon asynchrone un ensemble de champs de données contenant un fichier à télécharger vers un serveur"
Un peu long... Smiley cligne
Modifié par PapyJP (21 Mar 2020 - 10:29)
Bonjour a tous,

Merci PapyJP de m'avoir orienté par ici.

J'ai essayé de lire toute la discussion mais je ne comprend pas tout, oui je suis un développeur en herbe qui débute Smiley confused .
J'ai essayé le code de PapyJP, J'ai une erreur sur "var nomstage..." (TypeError: Cannot read property 'querySelector' of null), lorsque que j'exécute le code que j'ai essayé d'adapter:

Voici le code de PapyJP que j'ai essayé d'adapter a mes besoins encore merci et plus bas mon code de base.

Pour les autres je vous explique mes besoins et mes problèmes.
Je recherche une solution a mon problème qui est le suivant:

Je doit envoyer un fichier pdf (binaire)(pour info html2canvas fait une image d'une div et jsPDF met l'image dans un fichier pdf) et des données qui ne sont pas en formulaire vers un fichier de traitement en php pour ensuite les envoyer dans la base de donnée mysql:

J'essaye de faire cet envoie avec ajax jquery via un seul bouton, mais je ne parviens pas a récupérer les données envoyées, par contre je récupère bien le fichier pdf via la methode:
move_uploaded_file($_FILES....

Pour info, je n'est pas de formulaire dans mon code html, les données viennent de (select option value), (td) et (textarea) via un autre script js.
exemple:

<select name="numstage" id="numstage" style="font-size: 1.5em;border: none; border-color: transparent;">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>

ou 

<textarea style="border: none; border-color: transparent;" name="Descriptn" id="Descriptn" cols="60" rows="4">Exemple: Engage targets as they become visible.</textarea>

ou

<input style="text-align: center; border-color: transparent;" form-control id="nomstage" name="nomstage" type="text" placeholder="Enter stage name">

ou encore

<td name="MaxPoints" class="bord MaxPoints" id="point"></td>



JS :de PapyJP adapté:

function uploadFile(formID) {
	window.scrollTo(0, 0); //scroll page entiere du haut en bas 
				html2canvas(document.getElementById("main"),{scale: 2}).then(function(canvas){ //creation image avec scale: 2-> qualité X2
					var doc = new jsPDF();
					// doc.setFontSize(40); //taille titre
							// doc.text(40, 25, "TSV STAGE MAKER") // titre
							doc.addImage(canvas.toDataURL("image/jpeg", 0.9), 'JPEG', 15, 10, 180, 280); //'JPEG', 15(Gauche), 10 (Haut), 180 (Droite), 280 (Bas)
							var blob = doc.output('blob');
							var form = document.getElementById(formID);							
							var nomstage = form.querySelector('[name="nomstage"]');
							var numstage = form.querySelector('[name="numstage"]');
							var FirearmId = form.querySelector('[name="FirearmId"]');
							var TrgtTypeId = form.querySelector('[name="TrgtTypeId"]');
							var ScoringId = form.querySelector('[name="ScoringId"]');
							var StartOn = form.querySelector('[name="StartOn"]');
							var StartPos = form.querySelector('[name="StartPos"]');
							var Descriptn = form.querySelector('[name="Descriptn"]');
							var CourseId = form.querySelector('[name="CourseId"]');
							var matchsid = form.querySelector('[name="matchsid"]');							
							var formData = new FormData();
							formData.append('pdf', blob);
							formData.append('file', fileObject);
							formData.append('nomstage', nomstage.value);
							formData.append('numstage', numstage.value);
							formData.append('FirearmId', FirearmId.value);
							formData.append('TrgtTypeId', TrgtTypeId.value);
							formData.append('ScoringId', ScoringId.value);
							formData.append('StartOn', StartOn.value);
							formData.append('StartPos', StartPos.value);
							formData.append('Descriptn', Descriptn.value);
							formData.append('CourseId', CourseId.value);
							formData.append('matchsid', matchsid.value);							
							console.log(formData);
							var xhr = new XMLHttpRequest();
							xhr.onreadystatechange = function() {
								if(this.readyState == 4 && this.status == 200) {
									alert(this.responseText);
									return;
								}
							}
							xhr.open('post', 'save-capture.php');
							xhr.send(formData);
						});
			}


Voici mon code js de base :

function GenPDF(){
				window.scrollTo(0, 0); //scroll page entiere du haut en bas 
				html2canvas(document.getElementById("main"),{scale: 2}).then(function(canvas){ //creation image avec scale: 2-> qualité X2
					var doc = new jsPDF();
					// doc.setFontSize(40); //taille titre
							// doc.text(40, 25, "test") // titre
							doc.addImage(canvas.toDataURL("image/jpeg", 0.9), 'JPEG', 15, 10, 180, 280); //'JPEG', 15(Gauche), 10 (Haut), 180 (Droite), 280 (Bas)
							var blob = doc.output('blob');
							var nomstage = $('#nomstage') . val();
							var numstage = $('#numstage') . val();							
							var FirearmId = $('#FirearmId') . val();						 
							var TrgtTypeId = $('#TrgtTypeId') . val(); 
							var ScoringId = $('#ScoringId') . val(); 
							var StartOn = $('#StartOn') . val(); 
							var StartPos = $('#StartPos') . val(); 
							var Descriptn = $('#Descriptn') . val();
							var CourseId = $('#CourseId') . val(); 
							var matchsid = $('#matchsid') . val();
							var formData = new FormData();
							formData.append('pdf', blob);

							var objArr = [];
							objArr.push({								
								formData, 
								"nomstage": nomstage, 
								"numstage": numstage, 
								"FirearmId": FirearmId,
								"TrgtTypeId": TrgtTypeId,
								"ScoringId": ScoringId,
								"StartOn": StartOn,
								"StartPos": StartPos,
								"Descriptn": Descriptn,
								"CourseId": CourseId,
								"matchsid": matchsid								
							});
				//JSON obj
				formData.append('objArr', JSON.stringify( objArr ));


				$.ajax({
					url: '/save-capture.php',
					type:"POST",
					processData:false,
					contentType: false,
					data: formData,
					// complete: function(data){alert("success");}
					success: function(response){console.log(response)},
					error: function(err){console.log(err)}
				});
			});
			}



Et voici les tentative coté php:

<?php

    $var = json_decode(file_get_contents("php://input"),true);
    echo "Data recieved by PHP file.\n";
    if ($var["nomstage"]=="John"){
        echo "ok";
    }
    else{
        echo "nok";
    }
  
    echo "\nSent";
die();



j'obtiens nok comme repose Smiley decu

mais je voit bien mes données dans le navigateur lorsque je fait un print_r($_POST) ou ($_REQUEST)

echo '<pre>';
    print_r($_REQUEST);
  echo '</pre>';
  die();
ou
echo '<pre>';
    print_r($_POST);
  echo '</pre>';
  die();



Meme Résultat du print_r de post ou REQUEST

<pre>Array
(
[objArr] => [{"formData":{},"nomstage":"John","numstage":"1","FirearmId":"1","TrgtTypeId":"2","ScoringId":"1","StartOn":"00","StartPos":"Exemple: Standing erect, facing downrange with hanging naturally by the sides.","Descriptn":"Exemple: Engage as they become visible.","CourseId":"1","matchsid":"24"}]
)
</pre>

Merci d'avance pour votre aide
Jean-Pierre-Bruneau a écrit :
Tout les vrais programmeurs font un code qu'ils maîtrisent totalement et non pas en employant un monstre crypté dont tu ne sait même pas la signification.


Pardon mais je peux pas laisser passer ça.

Les "vrais" programmeurs, pour reprendre ton expression, sont bien obligés d'utiliser des librairies et des frameworks dont ils ne maîtrisent pas forcément tous les concepts et le contenu. Je développe principalement en Java et j'utilise Spring Boot pour créer mes API REST. Pourtant je connais pas le framework de fond en comble, et cela, comme la majorité des développeurs dans le domaine. Même s'il est possible de créer un site internet from scratch, c'est pas du tout recommandé si tu créer une application web robuste, scalable et évolutive. Pour ça il existe Angular, React, Vue et j'en passe.

Jean-Pierre-Bruneau a écrit :
Sans prétention


Raté, c'est blindé de prétention je trouve. Au risque de paraître méchant, tu représente bien le développeur old school enfermé dans des vieux concepts, incapable de comprendre la programmation actuelle. Car oui, la programmation web c'est hyper basique (je parle pas de l'intégration HTML, de l'accessibilité, du design, etc) et le javascript c'est tout sauf un langage de qualité. Donc merci de ne pas parler au nom des "vrais" développeurs quand on se contente de faire du javascript dans le domaine du web. Il existe des paradigmes de programmation bien plus compliqués et des langages nécessitant bien plus de compétences.

C'était mon coup de gueule. Merci. Au revoir.
Modifié par Anymah (23 Mar 2020 - 13:56)
Je pense que l'on devrait chacun essayer d'apprendre les uns des autres.
Après si on ne se comprends pas ce n'est pas la mort non plus.
L'important c'est d'échanger avec respect, autant qu'on le peut, et c'est vrai parfois aussi selon l'humeur du jour ...
Comme je le répète je suis prêt à tout entendre, ouvert à toute information dans le but d'apprendre et de partager.
Certaines phrases sont dures à entendre, on ne se sent pas écouté, dès fois on a même l'impression qu'on nous prend pour un jeune diplômé sans expérience avec lequel il suffit de donner une bribe d'information comme vérité divine ( comme quoi je suis pas le seul Smiley cligne quoique comme toi j’essaie d'expliquer quand cela est nécessaire ).
@Pour taquiner Jean-Pierre:
je viens de tester un envoi d'image avec et sans <form>, j'ai exactement les mêmes données disponibles dans mon PHP Smiley lol
Et oui tu as raison, AJAX n'est pas propre à jquery, je te le concède !
Par contre de ton coté tu peux imaginer qu'en 2020, quand on parle d'ajax, la plupart des développeurs "comprennent" -> requête asynchrone en utilisant jquery.
Travaillant avec des jeunes dev ( dans plusieurs société, ce n'est pas propre à une équipe mais plutôt à une époque ) c'est le constat que j'ai fait, et ce n'est pas en leur rabâchant qu'à l'origine ceci cela etc ... qu'ils vont changer. C'est comme ça je n'y peut rien.
Je trouve donc dommage qu'on se dissipe en chamaillerie, c'est valable pour moi aussi bien entendu ^
En souhaitant à tous une agréable journée.
Modifié par stryk (23 Mar 2020 - 14:44)
Pages :