Использование jQuery для хранения состояния сложной формы

У меня довольно сложная форма с множеством «шагов», которые заполняются пользователем. Некоторые шаги (воспринимайте их как сегменты формы) имеют параметры по умолчанию, но при нажатии кнопки «ввести пользовательские значения» они отображают скрытый набор полей, в которые пользователь может ввести информацию. Вот пример

<div id="#s1_normal">
<input type="radio" name="mode" value="a"> Mode A
<input type="radio" name="mode" value="b"> Mode B
Choose one of the above for applying average coefficient 
values of "a" or "b" to 100% of your product or
<a href="#" onclick="toggleCustom('s1');">enter custom values</a>
</div>

<div id="#s1_custom">
%a: <input type="text" name="perc_a"> coeff. a <input type="text" name="coeff_a">
%b: <input type="text" name="perc_b"> coeff. b <input type="text" name="coeff_b">
Enter custom values above or 
<a href="#" onclick="toggleCustom('s1');">choose average values</a>

Таких сегментов несколько, например, # s1 .. # s7. Вот моя задача. Я хочу разрешить пользователю сохранять состояние формы. Таким образом, после того, как пользователь заполнил всю форму, выбрав средние значения по умолчанию для одних сегментов и введя собственные значения для других, пользователь может нажать кнопку и сохранить все состояние для последующего размораживания. Я думаю, что если я могу сохранить состояние в объекте, который я могу сериализовать, я могу сохранить его в таблице db или другом постоянном хранилище.

Пользователь может вернуться позже и восстановить весь предыдущий сеанс.

Как мне это сделать? Есть плагин getAttributes http://plugins.jquery.com/project/getAttributes, а там - это метод сериализации jQuery, но я не могу, хоть убей, начать. Пожалуйста, подтолкните меня в правильном направлении.


person punkish    schedule 08.08.2010    source источник


Ответы (4)


Вот несколько функций, которые помогут в этом процессе. formToString сериализует форму как строку, а stringToForm делает обратное:

function formToString(filledForm) {
    formObject = new Object
    filledForm.find("input, select, textarea").each(function() {
        if (this.id) {
            elem = $(this);
            if (elem.attr("type") == 'checkbox' || elem.attr("type") == 'radio') {
                formObject[this.id] = elem.attr("checked");
            } else {
                formObject[this.id] = elem.val();
            }
        }
    });
    formString = JSON.stringify(formObject);
    return formString;
}
function stringToForm(formString, unfilledForm) {
    formObject = JSON.parse(formString);
    unfilledForm.find("input, select, textarea").each(function() {
        if (this.id) {
            id = this.id;
            elem = $(this); 
            if (elem.attr("type") == "checkbox" || elem.attr("type") == "radio" ) {
                elem.attr("checked", formObject[id]);
            } else {
                elem.val(formObject[id]);
            }
        }
    });
}

Использование:

// Convert form to string
var formString = formToString($("#myForm"));
// Save string somewhere, e.g. localStorage
// ...

// Restore form from string
stringToForm(formString, $("#myForm"));
person Reese    schedule 08.02.2011
comment
Это так полезно! Просто примечание для тех, кто не знает, как вызвать функцию, я использовал ее так: sessionStorage.setItem("formdata",formToString(jQuery("#form")));, а затем это, чтобы вызвать ее: var storedform = sessionStorage.getItem("formdata"); stringToForm(storedform,jQuery("#form")); - person Julian K; 15.06.2014
comment
Выражение $j(this) - опечатка? Я получаю ошибки JavaScript при использовании этого сценария и предполагаю, что это должно быть $(this), верно? - person Matt; 12.11.2015
comment
Это не было опечаткой, но я удалил ее из ответа, поскольку просто $ является способом доступа по умолчанию к jquery. См. learn.jquery.com/using-jquery-core/ для получения дополнительной информации - person Reese; 12.11.2015
comment
Вы забыли textarea - person H Dog; 08.04.2016
comment
@HDog добавил textarea, как это? - person Reese; 09.04.2016
comment
в stringToForm вы делаете stringForm.find() и перебираете результаты. внутри цикла вы также делаете stringForm.find() для идентификатора найденного элемента. это всегда будет находить текущий элемент, поэтому нет необходимости находить один и тот же элемент дважды. var input = $(this) проще - person H Dog; 11.04.2016
comment
@JulianK привет, сэр и спасибо - не могли бы вы подробнее рассказать о sessionStorage. В моем конкретном случае пользователя перенаправляют от формы, а затем возвращают к ней, очевидно, когда я возвращаюсь, я не хочу, чтобы пользователь каждый раз щелкал одно и то же раскрывающееся меню - что было бы неприятно, чтобы пройти . любые идеи очень ценятся. - person BKSpurgeon; 01.08.2016
comment
если отмечено = отмечено в HTML, и вы щелкните поле, затем attr (проверено) по-прежнему == проверено - person Artistan; 04.08.2016
comment
следует использовать formObject [this.id] = elem.prop (проверено); чтобы заставить его работать. (jQuery 2.2.0) - person Artistan; 04.08.2016
comment
@JulianK - для каких событий браузера вы устанавливаетеItem и getItem ()? Я понимаю, что setItem (), вероятно, выполняется в form.onsubmit (), но getItem () - я пытался поместить его в BodeyOnload (), но это кажется неправильным, потому что это выполняется как на кнопке возврата, так и на странице поступает с сервера. Цель состоит в том, чтобы восстановить форму только по действию кнопки "Назад" - person Dmitry z; 02.07.2020

Я бы начал с использования подключаемого модуля jQuery dumbFormState.

Этот плагин фактически автоматически сохраняет данные, пока вы печатаете и т. Д., Поэтому, когда они возвращаются, он уже снова заполнен, и для этого вам не нужна серверная сторона.

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

person King Friday    schedule 09.06.2011

Я думаю, вы ищете .serialize (), который сериализует form data. Для этого ваши input элементы должны находиться в пределах form tag плюс, все они должны иметь name атрибуты.

var form1data = $('#form1').serialize();

alert(form1data);
person jAndy    schedule 08.08.2010
comment
Спасибо за предложение. Как я отметил в своем вопросе, я знаю о методе сериализации, однако, мне кажется, что это только часть решения. Чтобы восстановить форму, я должен прочитать сохраненные сериализованные данные, а затем восстановить форму обратно в состояние, включая все ее пользовательские записи ... то есть, если скрытый сегмент был отображен для ввода пользовательских значений, я хочу вернуть это назад. Как мне это сделать? - person punkish; 08.08.2010
comment
@punkish: мне неизвестен какой-нибудь deserialize() метод в ядре jQuery. Поэтому вам нужно либо написать собственный парсер, либо искать плагин. - person jAndy; 08.08.2010
comment
@punkish вот мой плагин formstate - альтернатива serialize () и отсутствующей unserialize (), которая работает предметами, а не струнами; Мне нужен легкий плагин, который имеет дело только с состоянием формы, а не со строковыми представлениями или методами хранения. Он разумно обрабатывает радио, флажки и т. Д. - person mindplay.dk; 08.08.2012

Вы можете просто поместить данные, которые не являются данными по умолчанию, в json, а затем отправить их через почтовый запрос на сервер для сохранения.

Итак, как только человек возвращается на страницу, вы автоматически смотрите, есть ли у него что-то сохраненное, и вы можете либо спросить, хотят ли они это использовать, либо заполнить форму из сохраненных данных.

Сохранение значений по умолчанию - это пустая трата полосы пропускания, поскольку вы все равно не измените ее с той формы, которая была на момент загрузки.

ОБНОВЛЕНИЕ:

Чтобы сохранить его как JSON, я думаю, было бы достаточно просто построить его в длинную строку, поскольку формат прост, поэтому вы просто отправите все как одну строку.

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

person James Black    schedule 08.08.2010