Avertir l'utilisateur avant de quitter la page Web avec des modifications non enregistrées

342

J'ai quelques pages avec des formulaires dans ma candidature.

Comment puis-je sécuriser le formulaire de telle manière que si quelqu'un s'éloigne ou ferme l'onglet du navigateur, il doit être invité à confirmer qu'il souhaite vraiment laisser le formulaire avec des données non enregistrées?

Khan
la source
3
Cette question ici devrait avoir la réponse que vous recherchez: stackoverflow.com/questions/1244535/…
Nexerus
1
EN RELATION

Réponses:

557

Réponse courte et fausse:

Vous pouvez le faire en manipulation de l' beforeunloadévénement et en retournant une chaîne non nulle :

window.addEventListener("beforeunload", function (e) {
    var confirmationMessage = 'It looks like you have been editing something. '
                            + 'If you leave before saving, your changes will be lost.';

    (e || window.event).returnValue = confirmationMessage; //Gecko + IE
    return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});

Le problème avec cette approche est que l' envoi d'un formulaire déclenche également l'événement de déchargement . Ceci est résolu facilement en ajoutant le drapeau que vous soumettez un formulaire:

var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting) {
            return undefined;
        }

        var confirmationMessage = 'It looks like you have been editing something. '
                                + 'If you leave before saving, your changes will be lost.';

        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};

Puis appeler le passeur lors de la soumission:

<form method="post" onsubmit="setFormSubmitting()">     
    <input type="submit" />
</form>

Mais lisez la suite ...

Réponse longue et correcte:

Vous ne voulez pas non plus afficher ce message lorsque l'utilisateur n'a rien changé sur vos formulaires . Une solution consiste à utiliser l' beforeunloadévénement en combinaison avec un indicateur "sale", qui ne déclenche l'invite que s'il est vraiment pertinent.

var isDirty = function() { return false; }

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting || !isDirty()) {
            return undefined;
        }

        var confirmationMessage = 'It looks like you have been editing something. '
                                + 'If you leave before saving, your changes will be lost.';

        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};

Maintenant, pour mettre en œuvre la isDirtyméthode, il existe différentes approches.

Vous pouvez utiliser jQuery et sérialiser un formulaire , mais cette approche présente quelques défauts. Vous devez d'abord modifier le code pour travailler sur n'importe quelle forme ( $("form").each()fera l'affaire), mais le plus gros problème est que jQuery serialize()ne fonctionnera que sur les éléments nommés et non désactivés, donc la modification de tout élément désactivé ou non nommé ne déclenchera pas le drapeau sale. Il existe des solutions pour cela , comme rendre les contrôles en lecture seule au lieu d'activer, de sérialiser puis de désactiver à nouveau les contrôles.

Les événements semblent donc la voie à suivre. Vous pouvez essayer d' écouter les touches . Cet événement a quelques problèmes:

  • Ne se déclenche pas sur les cases à cocher, les boutons radio ou d'autres éléments modifiés par la souris.
  • Se déclenchera pour les touches non pertinentes comme la Ctrltouche.
  • Ne se déclenche pas sur les valeurs définies via le code JavaScript.
  • Ne se déclenche pas lors de la coupe ou du collage de texte via les menus contextuels.
  • Ne fonctionnera pas pour les entrées virtuelles comme les sélecteurs de date ou les embellisseurs de case à cocher / radiobutton qui enregistrent leur valeur dans une entrée cachée via JavaScript.

L' changeévénement a également ne déclenche pas sur les valeurs définies à partir du code JavaScript , donc cela ne fonctionnera pas pour les entrées virtuelles.

La liaison de l' inputévénement à tous les inputs (et textareas et selects) de votre page ne fonctionnera pas sur les anciens navigateurs et, comme toutes les solutions de gestion d'événements mentionnées ci-dessus, ne prend pas en charge l'annulation. Lorsqu'un utilisateur modifie une zone de texte, puis l'annule, ou vérifie et décoche une case à cocher, le formulaire est toujours considéré comme sale.

Et lorsque vous souhaitez implémenter plus de comportements, comme ignorer certains éléments, vous aurez encore plus de travail à faire.

Ne réinventez pas la roue:

Donc, avant de penser à mettre en œuvre ces solutions et toutes les solutions de contournement nécessaires, réalisez que vous réinventez la roue et que vous êtes enclin à rencontrer des problèmes que d'autres ont déjà résolus pour vous.

Si votre application utilise déjà jQuery, vous pouvez également utiliser du code testé et maintenu au lieu de lancer le vôtre, et utiliser une bibliothèque tierce pour tout cela. Êtes-vous sûr de jQuery? plugin fonctionne très bien, voir leur page de démonstration . C'est aussi simple que ça:

<script src="jquery.are-you-sure.js"></script>

<script>
  $(function() {
    $('#myForm').areYouSure(
      {
        message: 'It looks like you have been editing something. '
               + 'If you leave before saving, your changes will be lost.'
      }
    );
  });

</script>

Messages personnalisés non pris en charge partout

Notez que Firefox 4 ne prend pas en charge les messages personnalisés dans cette boîte de dialogue. Depuis avril 2016, Chrome 51 est déployé dans lequel les messages personnalisés sont également supprimés .

Certaines alternatives existent ailleurs sur ce site, mais je pense qu'un dialogue comme celui-ci est assez clair:

Voulez-vous quitter ce site?

Les modifications que vous avez apportées peuvent ne pas être enregistrées.

Leave Stay

CodeCaster
la source
6
Notez que l'utilisation de chaînes personnalisées ne fonctionne plus dans Chrome; chromestatus.com/feature/5349061406228480
amann
5
Oui, c'est décrit dans la dernière section de ma réponse.
CodeCaster
2
@Chris ce sera parce que Angular manipule le DOM pour changer la page, sans s'éloigner du document actuel.
CodeCaster
15
Soyez averti que jQuery areYouSure a été abandonné depuis 2014 (57 problèmes ouverts sur Github ), il est plein de bugs de mon expérience, il peut sembler que cela fonctionne au début, mais après quelques tests rapides, j'ai réalisé que cela ne fonctionne pas toujours. Je ne le recommanderais pas du tout
Mark
4
@JacopoStanchi Je n'en ai malheureusement pas trouvé. Et je veux dire que je regardais beaucoup - mais c'était en janvier 10 donc quelqu'un peut avoir écrit quelque chose mais j'en doute. Votre meilleur pari est de le mettre en œuvre vous-même - ce n'est pas ce que vous voulez entendre, désolé. (Mais au moins, vous n'aurez pas de surprises comme je l'ai fait avec jQuery areYouSure.) De plus, qui sait peut-être que vous pourriez même le rendre open source et que votre implémentation serait partagée avec d'autres;)
Mark
75

Découvrez l' événement JavaScript onbeforeunload . Il s'agit de JavaScript non standard introduit par Microsoft, mais il fonctionne dans la plupart des navigateurs et leur documentation onbeforeunload contient plus d'informations et d'exemples.

Paul Annesley
la source
3
Je pense que c'est devenu une norme maintenant. >> L'événement a été initialement introduit par Microsoft dans Internet Explorer 4 et standardisé dans la spécification HTML5.
vee
34

via jquery

$('#form').data('serialize',$('#form').serialize()); // On load save form current state

$(window).bind('beforeunload', function(e){
    if($('#form').serialize()!=$('#form').data('serialize'))return true;
    else e=null; // i.e; if form state change show warning box, else don't show it.
});

Vous pouvez utiliser la fonction de sérialisation du formulaire Google JQuery, cela collectera toutes les entrées du formulaire et l'enregistrera dans le tableau. Je suppose que cela explique assez :)

Wasim A.
la source
6
n'utilisez pas #form comme identifiant de formulaire car la fenêtre créera et objet nommé form :)
mdikici
1
Vérifiez ici si cela ne fonctionne pas pour vous: stackoverflow.com/questions/7080269/…
Leniel Maccaferri
16

Solution universelle ne nécessitant aucune configuration qui détecte automatiquement toutes les modifications d'entrée, y compris les éléments modifiables par le contenu:

"use strict";
(() => {
const modified_inputs = new Set;
const defaultValue = "defaultValue";
// store default values
addEventListener("beforeinput", (evt) => {
    const target = evt.target;
    if (!(defaultValue in target || defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ("" + (target.value || target.textContent)).trim();
    }
});
// detect input modifications
addEventListener("input", (evt) => {
    const target = evt.target;
    let original;
    if (defaultValue in target) {
        original = target[defaultValue];
    } else {
        original = target.dataset[defaultValue];
    }
    if (original !== ("" + (target.value || target.textContent)).trim()) {
        if (!modified_inputs.has(target)) {
            modified_inputs.add(target);
        }
    } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
    }
});
// clear modified inputs upon form submission
addEventListener("submit", () => {
    modified_inputs.clear();
    // to prevent the warning from happening, it is advisable
    // that you clear your form controls back to their default
    // state after submission
});
// warn before closing if any inputs are modified
addEventListener("beforeunload", (evt) => {
    if (modified_inputs.size) {
        const unsaved_changes_warning = "Changes you made may not be saved.";
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
    }
});
})();
Eli Grey
la source
1
Fèves fraîches. Copiez simplement collez ce code dans votre page de test, apportez une modification et cliquez sur Actualiser. Il affichera une alerte de navigateur natif vous avertissant que vous avez des modifications non enregistrées.
TheLegendaryCopyCoder
1
Cela a fonctionné pour moi sur Chrome 71.0.3578.98 (version officielle) (64 bits)
JacobRossDev
2
Cela fonctionne très bien, mais si vous l'utilisez avec un formulaire de soumission, vous devrez d'abord effacer le set modified_inputs avant, sinon vous recevrez une alerte de confirmation des modifications. J'ai ajouté un écouteur d'événements à mon formulaire pour appeler la soumission, et j'ai simplement exécuté la fonction set clear, de cette façon, le modified_inputs est clair lorsque beforeunload l'écouteur d'événements s'exécute et permet à post de continuer.
stepquick
1
Cool copier et coller. merci d'avoir économisé mon temps. Travaillez pour moi dans Firfox 75.0
Connectify_user
1
J'adore cet extrait
Rawburner
10

Construit sur l' excellente idée de Wasim A. d'utiliser la sérialisation. Le problème était que l'avertissement était également affiché lors de la soumission du formulaire. Cela a été corrigé ici.

var isSubmitting = false

$(document).ready(function () {
    $('form').submit(function(){
        isSubmitting = true
    })

    $('form').data('initial-state', $('form').serialize());

    $(window).on('beforeunload', function() {
        if (!isSubmitting && $('form').serialize() != $('form').data('initial-state')){
            return 'You have unsaved changes which will not be saved.'
        }
    });
})

Il a été testé dans Chrome et IE 11.

Eerik Sven Puudist
la source
Wasim A et Eerik Sven Puudist - Merci, j'ai utilisé id pour le formulaire et l'identifiant pour mon bouton d'enregistrement car tous mes boutons étaient de type soumettre <form action = "" id = "marksform" method = "POST"> <td> <input type = "submit" name = "submit_button" id = "save" value = "Save"> </td> <td> <input type = "submit" name = "submit_button" value = "Next"> </td> et quelques-uns plus tous les types soumettent donc remplacé .Submit (par un clic spécifique $ ('# save'). click (function () {isSubmitting = true}) Utilisez '#marksform' au lieu de 'form'
Jayanta
7

Sur la base des réponses précédentes, et bricolé à partir de divers endroits dans le débordement de pile, voici la solution que j'ai trouvée qui gère le cas lorsque vous souhaitez réellement soumettre vos modifications:

window.thisPage = window.thisPage || {};
window.thisPage.isDirty = false;

window.thisPage.closeEditorWarning = function (event) {
    if (window.thisPage.isDirty)
        return 'It looks like you have been editing something' +
               ' - if you leave before saving, then your changes will be lost.'
    else
        return undefined;
};

$("form").on('keyup', 'textarea', // You can use input[type=text] here as well.
             function () { 
                 window.thisPage.isDirty = true; 
             });

$("form").submit(function () {
    QC.thisPage.isDirty = false;
});
window.onbeforeunload = window.thisPage.closeEditorWarning;

Il convient de noter que IE11 semble exiger que la closeEditorWarningfonction retourne undefinedpour ne pas afficher d'alerte.

Jonathan
la source
Cette solution ne vérifie pas que les valeurs sont modifiées par rapport à leur état d'origine, ce qui invalide le cas où l'utilisateur entre du texte et supprime ce texte entré avant d'essayer de s'éloigner.
Brett Weber
Bon point, @BrettWeber. Vous pouvez modifier closeEditorWarning dans ce cas et avoir "if (window.thisPage.isDirty && uiHasChanged ())", où uiHasChanged est une fonction qui connaît l'état d'origine du serveur et vérifie toutes les différences, mais cette solution était pour un cas où je ne voulais pas particulièrement faire tout ce travail supplémentaire, et cela n'a de faux positifs que lorsque de vraies pressions sur les touches ont été effectuées dans les zones de texte, ce qui, à mon avis, était un compromis raisonnable. :)
Jonathan
Ne devrait pas l' QC.thisPage.isDirty = false;être window.thisPage.isDirty = false;? De cette façon, il vérifiera si vous soumettez le formulaire et n'affichera pas d'avertissement. Semblait travailler pour mes tests. De plus, la plupart des formulaires ont un inputplutôt qu'un textarea. J'ai utilisé ce qui suit qui fonctionne plutôt bien:$("form").on('keyup', 'textarea,input,select', function () {
Mike
7

Le one-liner suivant a fonctionné pour moi.

window.onbeforeunload = s => modified ? "" : null;

Il suffit de définir modifiedà vrai ou faux en fonction de l'état de votre application.

spencer.sm
la source
2
Quelques suggestions: renvoyer un message personnalisé plutôt qu'une chaîne vide car certains navigateurs l'afficheront (par exemple Edge), et retourner undefinedplutôt nullqu'IE affichera «null» s'il modifiedest faux.
Kevin Lee
1
que diriez-vous des appareils mobiles? ma compréhension est que les appareils IOS n'honorent pas à la décharge.
jaybro
4

Le code suivant fonctionne très bien. Vous devez atteindre les modifications d'entrée de vos éléments de formulaire via l'attribut id:

var somethingChanged=false;
            $('#managerForm input').change(function() { 
                somethingChanged = true; 
           }); 
            $(window).bind('beforeunload', function(e){
                if(somethingChanged)
                    return "You made some changes and it's not saved?";
                else 
                    e=null; // i.e; if form state change show warning box, else don't show it.
            });
        });
metzelder
la source
3
var unsaved = false;
$(":input").change(function () {         
    unsaved = true;
});

function unloadPage() {         
    if (unsaved) {             
        alert("You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?");
    }
} 
window.onbeforeunload = unloadPage;
Ankit
la source
Je l'ai inséré dans un fichier séparé et je l'ai inclus avec <script src = "warnOnChange.js"> </script> mais rien ne se produit lorsque je modifie un champ de texte puis j'exécute une commande d'en-tête.
Fabrizio Bartolomucci
2

Vous pouvez utiliser serialize () pour créer une chaîne de texte codée URL en sérialisant les valeurs du formulaire et vérifier si le formulaire a changé avant le déchargement

$(document).ready(function(){
    var form = $('#some-form'),
        original = form.serialize()

    form.submit(function(){
        window.onbeforeunload = null
    })

    window.onbeforeunload = function(){
        if (form.serialize() != original)
            return 'Are you sure you want to leave?'
    }
})

Référez-vous à ce lien https://coderwall.com/p/gny70a/alert-when-leaving-page-with-unsaved-form Écrit par Vladimir Sidorenko

Vennila M
la source
1
Cela a fonctionné, mais comme l'a répondu le lanceur de code, il y a quelques défauts avec cette méthode, reportez-vous à cette explication stackoverflow.com/a/7317311/10555981
Pradeep
Il existe déjà quelques réponses en utilisant serialize(), et en effet, il a ses inconvénients.
CodeCaster
Cela devrait être la bonne réponse, très simple à utiliser et fonctionne comme prévu.
Jodyshop
1

En ajoutant à l'idée de @codecaster, vous pouvez l'ajouter à chaque page avec un formulaire (dans mon cas, je l'utilise de manière globale, donc seuls les formulaires auraient cet avertissement) changer sa fonction en

if ( formSubmitting || document.getElementsByTagName('form').length == 0) 

Mettez également sur les formulaires soumettre, y compris la connexion et dans les liens des boutons d'annulation, donc lorsque la personne appuie sur annuler ou soumettre le formulaire ne déclenchera pas l'avertissement également dans chaque page avec un formulaire ...

<a class="btn btn-danger btn-md" href="back/url" onclick="setFormSubmitting()">Cancel</a>
Esteban Fuentealba
la source
1

Vous pouvez vérifier une explication détaillée ici: http://techinvestigations.redexp.in/comparison-of-form-values-on-load-and-before-close/ comparaison-de-form-values-on-load-et -avant-fermer

Le code principal:

function formCompare(defaultValues, valuesOnClose) {

    // Create arrays of property names
    var aPropsFormLoad = Object.keys(defaultValues);
    var aPropsFormClose = Object.keys(valuesOnClose);

    // If number of properties is different,
    // objects are not equivalent
    if (aPropsFormLoad.length != aPropsFormClose.length) {
        return false;
    }

    for (var i = 0; i < aPropsFormLoad.length; i++) {
        var propName = aPropsFormLoad[i];

        // If values of same property are not equal,
        // objects are not equivalent
        if (defaultValues[aPropsFormLoad]+"" !== valuesOnClose[aPropsFormLoad]+"") {
            return false;
        }
    }

    // If we made it this far, objects
    // are considered equivalent
    return true;

}

//add polyfill for older browsers, as explained on the link above

//use the block below on load
    for(i=0; i < document.forms[0].elements.length; i++){
    console.log("The field name is: " + document.forms[0].elements[i].name +
        " and it’s value is: " + document.forms[0].elements[i].value );
    aPropsFormLoad[i] = document.forms[0].elements[i].value;
    }

//create a similar array on window unload event.

//and call the utility function
    if (!formCompare(aPropsOnLoad, aPropsOnClose))
    {
    //perform action: 
    //ask user for confirmation or
    //display message about changes made
    }
Kanika Sud
la source
1

Réponse courte:

let pageModified = true

window.addEventListener("beforeunload", 
  () => pageModified ? 'Close page without saving data?' : null
)
Daniel Garmoshka
la source
1

La solution d'Eerik Sven Puudist ...

var isSubmitting = false;

$(document).ready(function () {
    $('form').submit(function(){
        isSubmitting = true
    })

    $('form').data('initial-state', $('form').serialize());

    $(window).on('beforeunload', function() {
        if (!isSubmitting && $('form').serialize() != $('form').data('initial-state')){
            return 'You have unsaved changes which will not be saved.'
        }
    });
})

... a spontanément fait le travail pour moi dans un cadre complexe orienté objet sans aucun changement nécessaire.

Le seul changement que j'ai appliqué était de faire référence à la forme concrète (une seule forme par fichier) appelée "formForm" ('form' -> '#formForm'):

<form ... id="formForm" name="formForm" ...>

Le fait que le bouton d'envoi soit «laissé seul» est particulièrement bien fait.

De plus, cela fonctionne pour moi également avec la dernière version de Firefox (en date du 7 février 2019).

mtjmohr
la source
1

Testé la solution universelle d'Eli Grey, n'a fonctionné qu'après avoir simplifié le code pour

  'use strict';
  (() => {
    const modified_inputs = new Set();
    const defaultValue = 'defaultValue';
    // store default values
    addEventListener('beforeinput', evt => {
      const target = evt.target;
      if (!(defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ('' + (target.value || target.textContent)).trim();
      }
    });

    // detect input modifications
    addEventListener('input', evt => {
      const target = evt.target;
      let original = target.dataset[defaultValue];

      let current = ('' + (target.value || target.textContent)).trim();

      if (original !== current) {
        if (!modified_inputs.has(target)) {
          modified_inputs.add(target);
        }
      } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
      }
    });

    addEventListener(
      'saved',
      function(e) {
        modified_inputs.clear()
      },
      false
    );

    addEventListener('beforeunload', evt => {
      if (modified_inputs.size) {
        const unsaved_changes_warning = 'Changes you made may not be saved.';
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
      }
    });

  })();

Les modifications apportées à la sienne sont supprimées target[defaultValue]et ne servent target.dataset[defaultValue]qu'à stocker la valeur par défaut réelle.

Et j'ai ajouté un écouteur d'événement «enregistré» où l'événement «enregistré» sera déclenché par vous-même lorsque votre action d'enregistrement aura réussi.

Mais cette solution «universelle» ne fonctionne que dans les navigateurs, pas dans la vue Web de l'application, par exemple, les navigateurs wechat.

Pour le faire fonctionner également (partiellement) dans les navigateurs wechat, une autre amélioration à nouveau:

  'use strict';
  (() => {
    const modified_inputs = new Set();
    const defaultValue = 'defaultValue';
    // store default values
    addEventListener('beforeinput', evt => {
      const target = evt.target;
      if (!(defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ('' + (target.value || target.textContent)).trim();
      }
    });

    // detect input modifications
    addEventListener('input', evt => {
      const target = evt.target;
      let original = target.dataset[defaultValue];

      let current = ('' + (target.value || target.textContent)).trim();

      if (original !== current) {
        if (!modified_inputs.has(target)) {
          modified_inputs.add(target);
        }
      } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
      }

      if(modified_inputs.size){
        const event = new Event('needSave')
        window.dispatchEvent(event);
      }
    });

    addEventListener(
      'saved',
      function(e) {
        modified_inputs.clear()
      },
      false
    );

    addEventListener('beforeunload', evt => {
      if (modified_inputs.size) {
        const unsaved_changes_warning = 'Changes you made may not be saved.';
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
      }
    });

    const ua = navigator.userAgent.toLowerCase();

    if(/MicroMessenger/i.test(ua)) {
      let pushed = false

      addEventListener('needSave', evt => {
        if(!pushed) {
          pushHistory();

          window.addEventListener("popstate", function(e) {
            if(modified_inputs.size) {
              var cfi = confirm('确定要离开当前页面嘛?' + JSON.stringify(e));
              if (cfi) {
                modified_inputs.clear()
                history.go(-1)
              }else{
                e.preventDefault();
                e.stopPropagation();
              }
            }
          }, false);
        }

        pushed = true
      });
    }

    function pushHistory() {
      var state = {
        title: document.title,
        url: "#flag"
      };
      window.history.pushState(state, document.title, "#flag");
    }
  })();
Jeff Tian
la source
0

Je l'ai fait différemment, en partageant ici afin que quelqu'un puisse obtenir de l'aide, testé uniquement avec Chrome.

Je voulais avertir l'utilisateur avant de fermer l'onglet uniquement s'il y a des changements.

<input type="text" name="field" value="" class="onchange" />

var ischanged = false;

$('.onchange').change(function () {
    ischanged = true;
});

window.onbeforeunload = function (e) {
    if (ischanged) {
        return "Make sure to save all changes.";
    }        
};

Fonctionne bien, mais j'ai un autre problème, lorsque je soumets le formulaire, j'obtiens l'avertissement indésirable, j'ai vu beaucoup de solutions de contournement, c'est parce que onbeforeunload se déclenche avant onsubmit, c'est pourquoi nous ne pouvons pas le gérer dans un événement onsubmit comme onbeforeunload = null, mais événement onclick de bouton d'envoi se déclenche avant ces deux événements, j'ai donc mis à jour le code

var isChanged = false;
var isSubmit = false;

window.onbeforeunload = function (e) {
    if (isChanged && (!isSubmit)) {
        return "Make sure to save all changes.";
    }        
};

$('#submitbutton').click(function () {
    isSubmit = true;
});

$('.onchange').change(function () {
    isChanged = true;
});
sairfan
la source
-5

Tout d'abord, la plupart des navigateurs ont cette fonction par défaut. Et pourquoi en avez-vous besoin? Pourquoi ne pas garder le formulaire synchronisé? Je veux dire, enregistrez-le sur toute modification sans attendre la soumission de l'utilisateur. Comme le font les contacts Google. Bien sûr, si seuls tous les champs du formulaire sont obligatoires. Les utilisateurs n'aiment pas quand ils forcent à remplir quelque chose sans avoir la possibilité de penser s'ils en ont besoin. :)

YuS
la source
aurez-vous raison mais mes formulaires sont générés dynamiquement et les champs ne sont pas sous mon contrôle donc pour moi il n'est pas possible de tracer tous les champs et d'envoyer la demande via ajax, si vous avez quelque chose en tête, partagez-le avec moi.
Khan
D'accord, cela peut ne pas être nécessaire pour vos besoins, mais il peut toujours être mis en œuvre. Si les éléments du formulaire sont à l'écran, vous pouvez attacher vos propres gestionnaires d'événements et obtenir les données que vous souhaitez. Utilisez ensuite AJAX pour enregistrer les données où vous le souhaitez. Même si les formulaires ont des ID ou des noms de classe générés de manière aléatoire, vous pouvez utiliser XPaths si vous pouvez anticiper la structure du formulaire. C'est du XML / HTML non? Ainsi, vous pourriez même avoir un JAD avec les personnes responsables du formulaire généré dynamiquement et parler des avantages que XSTL pourrait vous apporter à ce projet. Juste une pensée ...
SimonDever
1
save it on any change without waiting any submitting from userVous ne voulez pas toujours faire ça. Parfois, l'utilisateur souhaite apporter de nombreuses modifications, puis vérifier et confirmer qu'il souhaite l'enregistrer.
BadHorsie
1
Je n'ai pas suggéré de soumettre le formulaire. Les données peuvent être enregistrées dans localStorage, dans un cache ou même être soumises avec un brouillon de drapeau. Il existe de nombreuses méthodes pour ce comportement. C'est beaucoup mieux que d'avertir l'utilisateur qu'il n'a pas terminé le formulaire et s'il ne le fera pas et fermera la fenêtre, il devra le remplir à nouveau la prochaine fois. "Allez, mec, ne sois pas paresseux, ton train / bus / avion / etc n'a pas d'importance aussi bien que nous ne nous soucions pas que vous ayez oublié un chargeur de votre ordinateur portable, remplissez simplement ce foutu formulaire!"
YuS