18

我有一个带有文本字段数组的表单。用户(通过 javascript)可以向表单添加任意数量的文本字段。提交表单并按下后退按钮后,表单仅显示第一次呈现时原始表单上的字段(任何添加的文本字段都将丢失)。允许后退按钮以用户提交表单时的状态呈现表单的最佳方法是什么?欢迎任何想法,我尝试过的一些事情是:

  • 将表单数据放入 cookie 中(由于几个原因,这不太好用,但对我来说最大的杀手是 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>

这类似于我前段时间发布的一个问题,Best Way For Back Button To Leave Form Data,但是,此表单的元素是由用户修改的。

4

6 回答 6

15

如何创建一个<input type="hidden">(没有name或在表单之外,因此不提交),在其中存储要添加的额外字段的编码列表及其值?虽然浏览器不会记住“back”上新添加的字段,但它记住从一开始就在表单中的隐藏字段的值。

这是一个在文档卸载时保存额外字段并在准备好时检索它们的示例:

<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.onbeforeunloadonunload

  • 在 Firefox 中,隐藏输入的位置很重要。出于某种原因,如果您将其放在动态添加的字段下方,Firefox 会混淆它是哪个输入并且无法记住该值。

  • 此示例在 Opera 中不起作用。它可以在 Opera 中工作,但它很痛苦。Opera 对加载和卸载事件的调用不一致,因此您必须使用 onsubmit 代替,或者在轮询间隔上设置隐藏字段等。更糟糕的是,当 Opera 记住以前的表单字段值时,它实际上直到onload 触发后才填写它们!这已经导致了很多很多表单脚本问题。如果您需要 Opera 兼容性,您可以通过在 onload 中设置一个小超时来等待表单值输入来解决这个问题。

于 2009-11-16T12:12:38.753 回答
11

我找不到为此预先编写的库,但我确信它之前已经解决了。如果我不得不自己这样做,我会采取这种方法:

  1. 使用命令模式,以便通过添加控件来修改页面 UI 的每个方法也调用 AJAX 方法以将调用的方法(文本 Javascript 表示)推送到存储在服务器会话中的队列中。

  2. body onLoad 完成后,使用 AJAX 方法查询服务器会话以获取用户所在页面的命令队列。如果检索到一个,则仅eval队列中的每个成员以用户执行此操作的相同顺序重建页面的 UI。

请记住,使用这种方法,您不仅记录了控件的添加,还记录了删除。您将需要单独的状态持有者用于用户输入控件,例如文本框(您可能还需要具有 AJAX 方法访问权限的服务器端会话)。

于 2009-11-12T19:37:15.890 回答
7

在好的浏览器中,您只需不破坏它就可以让它完美地工作。

Firefox 1.5 对整个网页使用内存缓存,包括它们的 JavaScript 状态,用于单个浏览器会话。在访问的页面之间来回移动不需要加载页面,并且保留 JavaScript 状态。资源

OperaWebKit也支持这一点。然而 DOM 缓存只有在你遵守规则的情况下才有可能:

  1. 不要使用onunload, onbeforeunload
  2. 不要使用Cache-control: no-storemust-revalidate
    在 PHP 中,您必须session.cache_limiterpatently_ridiculous(我认为他们拼写它nocache)更改为none.

    session_cache_limiter('none');
    
  3. 不幸的是,HTTPS 也出来了。

如果您不强制浏览器重新加载页面,它们不会。他们将保持 DOM 及其值不变,正如RFC 2616 建议的那样。


但是,如果您正在寻找存储数据的地方,那么有一个非常聪明的技巧——window.name 可以存储数兆字节的数据。它不会发送到服务器,也不会在 Windows 之间共享。

还有 Flash cookie 和 HTML 5localStorage在 IE8 和 Safari 4 中实现。

于 2009-11-19T23:16:24.877 回答
0

第 2 步:处理表单的脚本将输入的值放入一个数组中,并将该数组存储到一个会话变量中(或 text / db / 任何你认为合适的)。

第 1 步:如果找到该会话变量(并且它还清除会话变量),则输出表单的脚本会添加一个 javascript(反过来填充表单)。

于 2009-11-22T22:49:48.563 回答
-3

阻止使用后退按钮。当按下后退按钮时,为用户重新呈现包含新字段的前一页,如果有意义的话,可以显示,也可以隐藏。这样用户就可以正常使用后退按钮,并且您可以完全控制“上一个”页面的外观。

在您的特定用例中,您只需要呈现所有可见字段并填写提交的值的页面。

对于任何向导类型的过程来说,这是一个很好的模式,在这些过程中,您提供一系列表格供用户填写,他们可以选择返回到以前的表格。

为了清楚起见,我建议您使用此建议来捕获 onUnload 事件以触发表单提交(以便您获取输入的值)并重新呈现“返回”将显示的上一页(没有值) . 唯一的替代方法是每次用户离开字段时使用 Ajax 发送输入的值,然后通过 AJAX 与服务器检查每个页面以检索要显示的附加值。

以下是一些额外的页面,讨论了控制后退按钮的功能并使用 unload 事件来持久化表单数据:

于 2009-11-19T11:28:31.130 回答
-3

您可以在网页顶部制作自己的后退按钮,使其比标准的网络浏览器后退按钮更大更漂亮。

在引擎盖下,您的代码可以知道以前的状态是什么并恢复到它,或者如果没有以前的状态,您可以调用浏览器的返回函数?

于 2009-11-12T19:31:56.367 回答