IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AJAX Discussion :

Sauvegarde automatique de formulaire


Sujet :

AJAX

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut Sauvegarde automatique de formulaire
    Bonjour à tous,

    Je voudrais enregistrer automatiquement un formulaire en quittant ma page.
    Je ne crois pas ou je n'ai pas trouvé d’événement qui détecte le déchargement de la page avant le chargement de la suivante.
    En alternative, j'ai trouvé des infos pour l'enregistrement de chaque champ en quittant le champ (blur) mais ces techniques utilisent Ajax. Là se pose deux problèmes: Je ne connais pas Ajax et d'après ce que j'ai lu, Ajax permet d'enregistrer en XML mais moi, je voudrais enregistrer directement en base de données.
    Suis-je assez clair?

  2. #2
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Par défaut
    Bonjour !
    Ta question est assez claire, je crois avoir compris. Un éclaircissement à propos d’ajax :
    Citation Envoyé par moimp Voir le message
    d'après ce que j'ai lu, Ajax permet d'enregistrer en XML mais moi, je voudrais enregistrer directement en base de données.
    Alors effectivement le X de ajax veut dire XML, mais c’est juste un nom et ça n’a plus tellement de sens aujourd’hui. Ce qu’il faut retenir de ajax c’est surtout qu’il permet de faire des requêtes HTTP depuis un script. XMLHttpRequest aurait pu s’appeler simplement HttpRequest, mais bon voilà c’est comme ça.

    Ton cas est d’ailleurs un des rares cas où il est légitime de faire une requête synchrone. D’habitude, les requêtes synchrones sont déconseillées car elles bloquent le fil d’exécution de la page et la rendent inerte le temps que la réponse arrive, ce qui peut donner l’impression que le navigateur a gelé.

    Mais dans ton cas, si tu agis sur l’évènement unload, ton script dit au navigateur « attends, ne ferme pas la page tout de suite, fais cette requête d’abord ». C’est un vieille technique, voici un article qui en parle et qui date de 2008 : Don’t Let the Door hit you onunload. C’est toujours d’actualité (et les bugs d’Opera ont été corrigés depuis).

    Voici un squelette de script :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    window.addEventListener("unload", function () {
      "use strict"; // voir https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Strict_mode
     
      const req = new XMLHttpRequest();
      req.open(
        "POST",  // en général, on préfère POST pour envoyer des données au serveur
        "...",   // l’URL du script serveur
        false    // il faut passer explicitement false pour que la requête soit synchrone
      );
     
      // le type MIME sous lequel tu vas envoyer les donnés
      // ex. "application/json" ou "application/x-www-form-urlencoded"
      req.setRequestHeader("Content-Type", "...");
     
      // préparation des données, par exemple avec JSON.stringify()
      const data = ... ;
     
      // envoi
      req.send(data);
    });
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  3. #3
    Expert confirmé
    Avatar de ProgElecT
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2004
    Messages
    6 130
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Décembre 2004
    Messages : 6 130
    Par défaut
    Salut
    je n'ai pas trouvé d’événement qui détecte le déchargement de la page avant le chargement de la suivante.
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    <body onbeforeunload="return verifmodif()">
    dans la procédure verifmodif tu y mets le code d'enregistrement automatiquement du formulaire.
    :whistle:pourquoi pas, pour remercier, un :plusser: pour celui/ceux qui vous ont dépannés.
    saut de ligne
    OOOOOOOOO👉 → → Ma page perso sur DVP ← ← 👈

  4. #4
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut
    Merci pour vos réponses.
    @ProgElecT: Oui mais je préfère mettre un écouteur et traiter les contrôles en PHP.
    @Watilin:
    Merci pour ces explications qui me permettent de mieux comprendre, mais malheureusement pas tout.
    1-Je place toujours un "use strict" en début de tous mes scripts php, ce qui m'évite bien des déboires, en particulier à la mise au point.
    2-Si c'est possible, je préférerais ne pas passer par Ajax mais simplement soumettre mon formulaire et accéder à mon script de contrôle en php. Malheureusement, la soumission du formulaire provoque une erreur 'non spécifiée' à la ligne 5 dans le débogueur de IE.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	window.addEventListener('unload', function(e)
    	{
    		alert('xxxxx');
    		console.log(cardForm.action);
    		cardForm.submit();
    	}, false );
    3-Dans ton code, je ne comprends pas tout:
    Ligne 7: de quel URL s'agit-il? Je suppose que c'est celui qui traite les contrôles et effectue l'enregistrement en base de données.
    Lignes 11 et suivante: Pourquoi faut-il préciser un type MIME et préparer (convertir?) les données. Je ne peux pas les transférer à l'état brut en texte comme elles sont codées en utf-8?

  5. #5
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Par défaut
    Citation Envoyé par moimp Voir le message
    1-Je place toujours un "use strict" en début de tous mes scripts php
    Tes scripts PHP ? Ce n’est pas clair. Le mode strict dont je parle concerne JavaScript. J’aimerais être certain qu’on parle de la même chose :/

    Citation Envoyé par moimp Voir le message
    2-Si c'est possible, je préférerais ne pas passer par Ajax mais simplement soumettre mon formulaire et accéder à mon script de contrôle en php.
    L’évènement unload survient lorsque le navigateur a déjà commencé la procédure de déchargement de la page. La page peut être déchargée de deux façons :
    • soit une nouvelle page va être chargée à la place,
    • soit la fenêtre ou l’onglet est en train d’être fermé.

    L’évènement n’est pas annulable et, dans le cas de la navigation vers une autre page, la destination ne peut pas être modifiée (c’est une mesure de sécurité). Ainsi, il n’est pas possible de demander la soumission du formulaire à ce moment-là, car ça changerait la destination.

    Tout ce processus se passe côté client et le serveur ne peut avoir aucune influence dessus. C’est pourquoi on a besoin de JavaScript, et avec JavaScript, la seule opération bloquante qui permet de retarder le déchargement de la page, c’est une requête « ajax » synchrone.

    Citation Envoyé par moimp Voir le message
    Malheureusement, la soumission du formulaire provoque une erreur 'non spécifiée' à la ligne 5 dans le débogueur de IE.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    	window.addEventListener('unload', function(e)
    	{
    		alert('xxxxx');
    		console.log(cardForm.action);
    		cardForm.submit();
    	}, false );
    Un débogueur qui fait des messages d’erreur aussi peu utiles ne mérite que notre dédain. Tu as quoi comme message d’erreur sous Firefox ou Chrome par exemple ?
    Note que, comme documenté sur la page MDN de unload, une partie des ressources de la page et des API du navigateur ne sont plus disponibles, notamment alert().

    Citation Envoyé par moimp Voir le message
    3-Dans ton code, je ne comprends pas tout:
    Ligne 7: de quel URL s'agit-il? Je suppose que c'est celui qui traite les contrôles et effectue l'enregistrement en base de données.
    Oui. C’est la même URL que l’attribut action de ton formulaire.
    Citation Envoyé par moimp Voir le message
    Lignes 11 et suivante: Pourquoi faut-il préciser un type MIME et préparer (convertir?) les données. Je ne peux pas les transférer à l'état brut en texte comme elles sont codées en utf-8?
    Tu n’as pas dit comment tu envoyais tes données donc je ne pouvais pas être plus précis. Bien sûr, tu peux envoyer du texte, dans ce cas tu peux utiliser le type MIME text/plain. Côté serveur, tu accèdes aux données via l’adresse spéciale 'php://input' que tu peux utiliser avec fopen(), file_get_contents() ou similaires. (Quelques petites infos en plus dans cette doc.)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      req.setRequestHeader("Content-Type", "text/plain; charset=utf-8"); // le charset est optionnel
     
      const data = "Lorem ipsum dolor machin truc";
     
      // envoi
      req.send(data);
    Si tu préfères utiliser des paires clé-valeur dans le tableau $_POST comme d’habitude, tu dois utiliser le type application/x-www-form-urlencoded et envoyer une chaîne clé1=valeur1&clé2=valeur2&... (comme avec la méthode GET). Il est conseillé d’encoder les clés et les valeurs avec encodeURIComponent.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
      req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
     
      const data = encodeURIComponent("clé1") + "=" + encodeURIComponent("valeur1") + "&" +
        encodeURIComponent("clé2") + "=" + encodeURIComponent("valeur2") + "&" +
        ... ;
     
      // envoi
      req.send(data);
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  6. #6
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut
    Pour le point 1, c'est un lapsus. Il s'agit bien des scripts JavaScript.

    Pour le reste, merci pour tes explications, je vais regarder ça de plus près. Je marque le sujet comme résolu, quitte à le réactiver si nécessaire.

  7. #7
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut
    Mon problème n'est toujours pas résolu, même si je comprends beaucoup mieux. Je n'arrive pas à préparer mes données pour les transmettre.
    Il me semble que le mieux serait de les transmettre soit:

    1. sous la forme que tu indique:
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
        req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");[*] [*]  const data = encodeURIComponent("clé1") + "=" + encodeURIComponent("valeur1") + "&" +[*]    encodeURIComponent("clé2") + "=" + encodeURIComponent("valeur2") + "&" +[*]    ... ;[*]
      mais je n'arrive pas à récupérer les clefs.
      .
    2. soit sérialiser mes données en php et transmettre la chaîne sérialisée mais je me demande si c'est bien recommandé.

    Voici mon code dans son état actuel:
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    <script>
    	const arrPost = <?= json_encode($_POST); ?>;
    </script>
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    window.addEventListener("unload", function () {
     
    	const req = new XMLHttpRequest();
    	console.log(arrPost);
    	console.log(max);
    	console.log(JSON.stringify(arrPost));
     
    	req.open(
    		"POST",
    		"<?= URL_SITE; ?>frontend/controllers/addressHandle.php",
    		false
    	);
     
    	req.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
     
    	// préparation des données, par exemple avec JSON.stringify()
    	//const data = ... ;
     
    	// envoi
    	//req.send(data);
    });
    J'ai aussi essayé de transmettre séparément les clefs et les valeurs du $_POST mais je n'y arrive pas. J'obtiens toujours une erreur de variables indéfinies. Pourtant la ligne 1 me renvoie bien mon tableau $_POST correct.
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    <?php print_r($_POST); ?>
    <script src="<?= URL_SITE; ?>common/js/cardFrame.js"></script>
    <script>
    	const arrPostKeys	= <?= json_encode(array_keys($_POST)); ?>;
    	const arrPostValues	= <?= json_encode(array_values($_POST)); ?>;
    </script>

  8. #8
    Membre éprouvé
    Homme Profil pro
    Ingénieur en électrotechnique retraité
    Inscrit en
    Décembre 2008
    Messages
    1 718
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 73
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur en électrotechnique retraité

    Informations forums :
    Inscription : Décembre 2008
    Messages : 1 718
    Par défaut Envoi auto de formulaire: déboguer
    Bonjour,
    J'ai aussi repris complètement un cours et travaillé les exemples de MDN. J'ai lu la FAQ de ce site, et notamment la rubrique sur l'asynchrone sans tout comprendre (En passant, je regrette que dans cette FAQ, les dates de mise à jour ne soit pas reportées sur chaque article).

    Malheureusement, je n'arrive toujours pas à comprendre pourquoi mon code ne fonctionne pas, ce qui est est d'ailleurs rendu difficile par l'impossibilité d'utiliser la console ou la fonction alert.

    Mon application comprend une page mère avec plusieurs onglets comportant chacun un ou plusieurs formulaires identiques mais avec des données différentes.
    Prenons déjà le cas le plus simple avec un formulaire par onglet. Le clic sur un onglet (lien) recharge la page avec le formulaire correspondant à cet onglet.

    Mon but est de soumettre le formulaire lorsque je clique sur un autre onglet. Dans ce cas, l'url (targetFile dans mon code) correspond au fichier php de traitement du formulaire. Le problème est que comme je quitte la page et que la page appelée ne contient que du code php, je ne vois rien et rien ne se passe.

    J'ai essayé le code donné par Watilin dans le lien ci-dessus et le code ci-dessous mais je ne m'en sors pas:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    "use strict";
     
    (function()
    {
     
    	window.addEventListener('unload', function()
    	{
    		const myForm = document.querySelector('form')
    			, myData = new FormData(myForm)
    			, req = new XMLHttpRequest()
    			, output = document.querySelector('div') // à préciser
    		;
     
    		req.open('POST', targetFile);
    		req.addEventListener('load', function(e)
    		{
    			if (req.status != 200)
    			{
    				output.innerHTML = "Problème !!";
    			}
    		}, false );
    		req.send(myData);
    	}, false );
     
    }) ();

  9. #9
    Expert confirmé
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 094
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 094
    Par défaut
    Tout comme alert(), le DOM n’est plus disponible quand la page est en cours de déchargement. Donc innerHTML ne marche pas non plus. En revanche, console.log() est toujours accessible, le seul obstacle étant le vidage des journaux lors d’un changement de page. Heureusement il y a une option « journaux persistants » dans la console.

    J’ai posté une réponse sur ton autre fil, à peu près au même moment où tu as ouvert celui-ci, va jeter un œil
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Débutant] sauvegarde automatique d'un formulaire sous format pdf
    Par ahmed_kh dans le forum VB.NET
    Réponses: 1
    Dernier message: 01/07/2012, 10h55
  2. Réponses: 1
    Dernier message: 10/04/2012, 16h57
  3. [Prototype] Sauvegarde automatique d'un formulaire
    Par Higestromm dans le forum Bibliothèques & Frameworks
    Réponses: 0
    Dernier message: 03/03/2009, 15h49
  4. [AJAX] sauvegarde automatique d'un champ d'un formulaire
    Par LuneArgentee dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 22/04/2008, 13h41
  5. sauvegarde automatique
    Par bourvil dans le forum MS SQL Server
    Réponses: 6
    Dernier message: 18/11/2003, 14h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo