Каков самый простой способ определить, было ли изменено хотя бы одно поле в форме HTML?

У меня есть HTML-форма с более чем 20 полями. У меня также есть несколько ссылок на странице, которые приведут пользователя от формы... потенциально без сохранения каких-либо изменений.

Я хочу предупредить (JS подтвердить) пользователя onClick этих ссылок, если какое-либо из полей формы изменилось, но я не хочу создавать огромный оператор switch, который мне тогда нужно поддерживать, когда я добавляю новые поля в форма. Я знаю, как создать длинный список инструкций "if" в Javascript, называть каждое из полей и проверять каждое значение, но я не хочу этого делать, если мне это удастся.

Какой самый простой способ проверить, изменилось ли пользователь хотя бы одно из значений поля?

Ответ 1

Подход

Если они не совпадают, они должны изменить форму, поэтому верните строку (например, "У вас есть несохраненные данные" ) из вашего обработчика onbeforeunload.

Этот метод позволяет изменять поля формы, пока логика "подтвердить, если изменена" остается прежней.

Пример (смешанный javascript и 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.';
    }
};

Ответ 2

Я уверен, что это плохая идея, но я хотел ее выбросить.

Поля формы имеют способ получить "значение по умолчанию" (т.е. значение, которое было у поля при его загрузке), и вы можете сравнить его с текущим значением. Простой цикл по всем полям устраняет необходимость в обслуживании, если вы добавляете поля в форму.

Там могут быть или не быть различные ошибки браузера, связанные со свойствами по умолчанию, поэтому я не буду доверять этому методу без тщательного тестирования. Код ниже является доказательством концепции и не используется (мной) в любом реальном приложении.

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;
}

Ответ 3

Использование jQuery очень просто. Вы должны использовать одну и ту же предпосылку для достижения того же результата в javascript ванили.

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

Единственная проблема с этим - изменить значение, а затем изменить его на оригинал, оно все равно сообщит об изменении формы.

Ответ 4

Вот один вкладыш, который вы можете добавить в свои формы:

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

И затем вы можете сделать функцию enableUnloadPrompt() для всего сайта:

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

И, наконец, перед тем, как отправить форму правильно, убедитесь, что:

enablePrompt(false);

Это не проверяет, отличается ли форма в значениях, только если форма была изменена пользователем. Но он прост и удобен в использовании.

Ответ 5

Это может быть обработано только с одной логической переменной, мы называем ее грязной обработкой бит. Если вы наблюдали, как правило, на веб-страницах, как только пользователь выполняет какое-либо действие редактирования в любом из полей, форма считается грязной (отредактированной) (даже если данные остаются неизменными после редактирования). Когда пользователь попытается перейти от страницы, пользователю будет предложено, если он хочет сохранить изменения.

В соответствии со стандартной практикой, нет проверки, если после редактирования какого-либо поля, если значение действительно изменилось или нет. Например, если пользователь редактирует и добавляет "xyz" в текстовое поле, а затем удаляет "xyz", по существу данные формы остаются такими же, как и раньше, но форма по-прежнему считается "грязной", и пользователю предлагается предупредить сообщение, когда он пытается уйти.

Итак, если вы хотите реализовать это, все будет довольно просто. Вам просто нужно будет добавить обработчики событий onchange() к элементам управления и установить глобальную логическую переменную, например, isDirty to true внутри этих обработчиков событий.

Как только пользователь хочет уйти, вы можете прошивать сообщение "На текущей странице могут быть несохраненные изменения. Вы хотите их сохранить?". Пользователь не будет разочарован, даже если он заметит, что его редактирование не изменило исходные данные.

Ответы, приведенные выше, реализуют это поведение. И я написал это, потому что у вас, казалось, была идея проверить каждое поле по его начальному значению, чтобы увидеть, действительно ли оно было изменено после редактирования. Просто хотел сказать вам, что проверка каждого поля вообще не требуется.

Ответ 6

В моем случае я объединил ответы @Crescent Fresh и @nickf и получил такой:

var formBefore;

var $inps = $('form').find('input,select,textarea');

$(function() {
    formBefore = $("form").serialize();
});

$inps.change(function () {
    var changedForm = $("form").serialize();
    if (formBefore != changedForm) {
        $("#btnSave").css('background-color', 'green');
    } else {
        $("#btnSave").css('background-color', '');
    }
});