2009-03-01 13 views
35

Mam formularz HTML z ponad 20 polami. Mam również kilka linków na stronie, które odciągną użytkownika od formularza ... potencjalnie, nie zapisując żadnych zmian.Jaki jest najłatwiejszy sposób na wykrycie, czy co najmniej jedno pole zostało zmienione w formularzu HTML?

Chcę ostrzec (JS potwierdzić) użytkownika o kliknięciu tych linków, jeśli którekolwiek z pól formularza uległy zmianie, ale nie chcę tworzyć ogromnego oświadczenia przełącznika, które będę musiał zachować, dodając nowe pola do formularza. Wiem, jak utworzyć długą listę instrukcji "if" w JavaScript, nazywając każde z pól i sprawdzając każdą wartość, ale nie chcę tego robić, jeśli uda mi się uciec.

Jaki jest najłatwiejszy sposób sprawdzenia, czy użytkownik zmienił co najmniej jedną wartość pola?

Odpowiedz

7

Korzystanie z jQuery jest bardzo proste. Powinieneś być w stanie użyć tej samej przesłanki, aby osiągnąć ten sam wynik w javascript wanilii.

var $inps = $('#myForm').find('input,select,textarea') 
    , formAltered = false 
; 
$inps.change(function() { 
    formAltered = true; 
    $inps.unbind('change'); // saves this function running every time. 
}); 

Jedyny problem z tym jest, jeśli zmieni się wartość, a następnie zmienić go z powrotem do oryginału, to będzie jeszcze zgłosić formę jako zmienione.

+0

+1, można opracować to, aby wyeliminować przypadek danych naprawdę nie zmienia - można zapisać stan początkowy i porównać do niego (zdarzenie użycie onfocus do tego), a dopiero potem ustawić formularz „brudne” – Dror

+0

Możesz poprawić pierwszą linię: 'var $ inps = $ ('# myForm: input'), formAltered = false;' – ANeves

68

Podejście

  1. serialize formularz (i wszystkie jej wartości) przed pokazaniem go (jQuery way, Prototype way)
  2. serialize to ponownie w przewodnika "onbeforeunload" zdarzeń

Jeżeli dwa nie pasują, a następnie musiały zmienić formularz, więc zwróć ciąg znaków (np. "Masz niezapisane dane") ze swojej obsługi onbeforeunload.

Ta metoda pozwala ewoluować pola formularzy, a logika "potwierdź lub zmień" pozostanie taka sama.

Przykład(mieszane JavaScript i jQuery)

var form_clean; 

// serialize clean form 
$(function() { 
    form_clean = $("form").serialize(); 
}); 

// compare clean and dirty form before leaving 
window.onbeforeunload = function (e) { 
    var form_dirty = $("form").serialize(); 
    if(form_clean != form_dirty) { 
     return 'There is unsaved form data.'; 
    } 
}; 
+0

Ooo, to naprawdę świetny pomysł. Miły. –

+10

Czy w 2014 r. Jest to nadal najlepsza praktyka? –

+0

Czy istnieje przyczyna, że ​​pierwsza linia to nie tylko 'var form_clean = $ (" form "). Serialize();'? – Edd

5

Oto jeden liner, które można dodać do formularzy:

$(':input',document.myForm).bind("change", function() { 
    enablePrompt(true); }); // Prevent accidental navigation away 

a następnie można dokonać enableUnloadPrompt () dla całej witryny:

function enablePrompt(enabled) { 
    window.onbeforeunload = enabled ? "Your changes are not saved!" : null; 
} 

I wreszcie, przed wysłaniem formularza prawidłowo, upewnij się, że:

enablePrompt(false); 

To nie będzie sprawdzić, czy forma jest różna w wartości, tylko wtedy, gdy forma została nigdy zmieniane przez użytkownika. Ale jest prosty i łatwy w użyciu.

3

Można to obsłużyć za pomocą tylko jednej zmiennej binarnej, nazywamy ją bitową obsługą bitów. Jeśli zaobserwowałeś, ogólnie na stronach internetowych, gdy użytkownik wykona jakąś czynność edycji na którymkolwiek z pól, formularz zostanie uznany za brudny (edytowany) (nawet jeśli po edycji pozostaną niezmienione). Gdy użytkownik próbuje odejść od strony, użytkownik jest monitowany, jeśli chce zapisać zmiany.

Zgodnie ze standardową praktyką, nie ma sprawdzenia, czy po edycji jakiegoś pola wartość rzeczywiście się zmieniła, czy nie. Na przykład: jeśli użytkownik edytuje i dodaje "xyz" do pola tekstowego, a następnie usuwa "xyz", dane formularza pozostają takie same jak przedtem, ale formularz jest nadal uznawany za "brudny", a użytkownik jest monitowany o komunikat ostrzegawczy, gdy próbuje odejść.

Tak więc, jeśli chcesz zaimplementować to, otrzymasz proste rozwiązanie. Trzeba by tylko dodać sterowniki zdarzeń onchange() do kontrolek i ustawić globalną zmienną boolean podobnie jak isDirty na true wewnątrz tych sterowników zdarzeń.

Gdy użytkownik chce odejść, może wyświetlić komunikat "Nie można zapisać niezapisanych zmian na bieżącej stronie. Czy chcesz je zapisać?". Użytkownik nie będzie zawiedziony, nawet jeśli zauważy, że jego zmiana nie zmieniła danych początkowych.

Powyższe odpowiedzi implementują to samo zachowanie. Napisałem to, ponieważ wydawało się, że masz pomysł, aby sprawdzić każde pole według jego wartości początkowej, aby sprawdzić, czy rzeczywiście zostało zmienione po edycji. Chciałem tylko powiedzieć, że sprawdzenie wszystkich pól w ogóle nie jest konieczne.

11

Jestem prawie pewien, że to zły pomysł, ale chciałem go tam wyrzucić.

Pola formularza umożliwiają uzyskanie "wartości domyślnej" (tj. Wartości, jaką pole miało podczas ładowania), i można porównać to z bieżącą wartością. Prosta pętla nad wszystkimi polami usuwa potrzebę konserwacji, jeśli dodasz pola do formularza.

Mogą występować lub nie różne błędy przeglądarki związane z właściwościami "domyślnej wartości", więc nie ufałbym tej metodzie bez obszernych testów. Poniższy kod jest dowodem koncepcji i nie jest używany (przeze mnie) w żadnej prawdziwej aplikacji.

function IsDirty(form) { 
    for (var i=0; i<form.elements.length; i++) { 
     var field = form.elements[i]; 
     switch (field.type) { 
      case "select-multiple": 
      case "select-one": 
       var options = field.options; 
       for (var j=0; j<options.length; j++) { 
        if(options[j].selected != options[j].defaultSelected) return true; 
       } 
       break; 
      case "text": 
      case "file": 
      case "password": 
       if (field.value != field.defaultValue) return true; 
       break; 
      case "checkbox": 
      case "radio": 
       if (field.checked != field.defaultChecked) return true; 
       break; 
     } 
    } 
    return false; 
} 
+0

O ile mi wiadomo, jest to jedyny sposób na zrobienie tego. Zapobiega to przebiegłości, na przykład w Firefoksie, zachowując nowe wartości formularzy po odświeżeniu. –

Powiązane problemy