Задняя кнопка обрабатывает динамическую форму - PullRequest
17 голосов
/ 12 ноября 2009

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

  • Поместите данные формы в файл cookie (это не работает отлично для пары причины, но самый главный убийца для меня является то, что куки ограничены 4K в размер)
  • Поместить данные формы в сеанс
  • Отправьте форму через AJAX и затем управляйте историей

Спасибо за помощь. Я разместил тестовую форму на своем веб-сайте по адресу http://fishtale.org/formtest/f1.php. Также здесь приведена простая форма, демонстрирующая упомянутое мной поведение:

<form action="f2.php" method="post">
<input type="text" name="text[]" id="text1"/>
<input type="submit" name="saveaction" value="submit form" />
</form>

<a href="f2.php" id="add_element">Add Form Element</a>

<script type="text/javascript" 
        src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.1/jquery.min.js" ></script>

<script type="text/javascript" >
    $('#add_element').click(function (event) {
        event.preventDefault();
        $('#text1').after('<input type="text" name="text[]" />');
    });
</script>

Это похоже на вопрос, который я опубликовал некоторое время назад, Лучший способ для кнопки «Назад» оставить данные формы , однако элементы этой формы изменяются пользователем.

Ответы [ 6 ]

13 голосов
/ 16 ноября 2009

Как насчет создания <input type="hidden"> (без name или вне формы, чтобы оно не отправлялось), в котором вы храните закодированный список дополнительных полей для добавления и их значений? Хотя браузер не будет помнить вновь добавленные поля в «назад», он будет запоминать значения скрытых полей, которые были в форме с самого начала.

Вот пример, который сохраняет дополнительные поля при выгрузке документа и извлекает их при готовности:

<input type="hidden" id="remembertexts" />

<form action="http://www.google.com/" method="get">
    <div id="texts">
        <input type="text" name="text[]" value="" />
    </div>
    <div>
        <input type="submit" />
        <input type="button" id="addtext" value="+" />
    </div>
</form>

<script type="text/javascript">

    // Add new field on button press
    //
    $('#addtext').click(function() {
        addInput('');
    });

    function addInput(text) {
        $('#texts input').eq(0).clone().val(text).appendTo('#texts');
    };

    // Store dynamic values in hidden field on leaving
    //
    $(window).bind('beforeunload', function() {
        var vals= [];
        $('#texts input').each(function() {
            vals.push(encodeURIComponent(this.value));
        });
        $('#remembertexts').val(vals.join(';'));
    });

    // Retrieve dynamic values on returning to page
    //
    $(function() {
        var extratexts= $('#remembertexts').val().split(';').slice(1);
        $.each(extratexts, function() {
            addInput(decodeURIComponent(this));
        });
    });
</script>

Примечания:

  • Вы можете использовать form.onsubmit вместо window.onbeforeunload, если вам нужно только запомнить значения во время отправки. onunload не работает, так как некоторые браузеры уже сохранили старые значения формы до того, как произойдет это событие.

  • В Firefox важна позиция скрытого ввода. По какой-то причине, если вы поместите его ниже динамически добавляемых полей, Firefox запутается в том, какой это ввод, и не запомнит значение.

  • Этот пример не работает в Opera. Это может быть сделано для работы в Опере, но это боль. Вызов Opera для событий загрузки и выгрузки является непоследовательным, поэтому вы должны вместо этого использовать onsubmit, или установить скрытое поле на интервал опроса, или что-то еще. Хуже того, когда Opera запоминает предыдущие значения полей формы, она фактически не заполняет их до тех пор, пока после срабатывания *1026* не сработает! Это уже вызывает много проблем со скриптами форм. Вы можете обойти это, установив небольшой тайм-аут в своей загрузке, чтобы дождаться, пока значения формы не будут введены, если вам нужна совместимость с Opera.

11 голосов
/ 12 ноября 2009

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

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

  2. После завершения тела onLoad используйте метод AJAX, чтобы запросить у сеанса сервера очередь команд для страницы, на которой находится пользователь. Если он получен, просто eval каждый член очереди перестраивает пользовательский интерфейс страницы в том же порядке, в котором это сделал пользователь.

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

7 голосов
/ 20 ноября 2009

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

Firefox 1.5 использует кэширование в памяти для целых веб-страниц, включая их состояния JavaScript, для одного сеанса браузера. Переход назад и вперед между посещенными страницами не требует загрузки страницы, и состояния JavaScript сохраняются. источник

Это поддерживается также в Opera и WebKit . Однако кеш DOM возможен только при соблюдении правил:

  1. Не используйте onunload, onbeforeunload.
  2. Не используйте Cache-control: no-store или must-revalidate.
    В PHP вы должны изменить session.cache_limiter с patently_ridiculous (я думаю, они пишут это nocache) на none.

    session_cache_limiter('none');
    
  3. К сожалению, HTTPS также отсутствует.

Если вы не заставите браузеры перезагружать страницу, они не будут. Они сохранят DOM и его значения без изменений, точно так же, как RFC 2616 предлагает .


Однако , если вы ищете место для хранения данных, есть невероятно умный взлом - window.name может хранить мегабайты данных . Он не отправляется на сервер и не используется в Windows.

Существуют также Flash-куки, и HTML 5 localStorage реализован в IE8 и Safari 4.

0 голосов
/ 23 ноября 2009

Шаг 2. Сценарий, обрабатывающий форму, помещает значения, введенные в массив, и сохраняет этот массив в переменной сеанса (или в тексте / db / как вам удобно).

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

0 голосов
/ 19 ноября 2009

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

В вашем конкретном случае использования вам просто нужно отобразить страницу со всеми видимыми полями и заполненными значениями, которые были отправлены.

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

Чтобы сделать это совершенно ясным, я предлагаю вам использовать этот совет по захвату события onUnload для запуска отправки формы (чтобы вы получили введенные значения) и для повторного отображения предыдущей страницы, которая "отобразил бы (без значений). Единственная альтернатива - использовать Ajax для отправки введенных значений каждый раз, когда пользователь покидает поле, а затем каждый раз проверять страницу с сервером через AJAX для получения дополнительных значений для отображения.

Вот несколько дополнительных страниц, на которых обсуждается контроль над функцией кнопки «Назад» и использование события unload для сохранения данных форм:

0 голосов
/ 12 ноября 2009

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...