返回按钮处理动态表单
-
19-09-2019 - |
题
我有一个带有文本字段数组的表单。用户(通过 javascript)可以向表单添加任意数量的文本字段。提交表单并按后退按钮后,表单仅显示首次呈现时原始表单上的字段(任何添加的文本字段都会丢失)。允许后退按钮以用户提交表单时的状态呈现表单的最佳方法是什么?欢迎任何想法,我尝试过的一些事情是:
- 将表单数据放入 cookie 中(此 不适合情侣 原因,但对我来说最大的杀手 是,cookie 只限于 4K in 尺寸)
- 将表单数据放入会话中
- 通过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>
这和我之前发的一个问题很像 后退按钮留下表单数据的最佳方式, 但是,此表单的元素是由用户修改的。
解决方案
我找不到为此预先编写的库,但我确信它之前已经解决了。如果我自己必须这样做,我会采取这种方法:
使用 命令模式 这样,通过添加控件来修改页面 UI 的每个方法也会调用 AJAX 方法,以将调用的方法(文本 Javascript 表示)推送到存储在服务器会话中的队列中。
body onLoad 完成后,使用 AJAX 方法在服务器会话中查询用户所在页面的命令队列。如果检索到一个,只需
eval
队列中的每个成员按照用户执行此操作的顺序重建页面的 UI。
请记住,通过这种方法,您不仅记录了控件的添加,还记录了控件的删除。您将需要单独的状态持有者用于用户输入控件,例如文本框(您可能还需要具有 AJAX 方法访问的服务器端会话)。
其他提示
怎么样创建一个 <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.onbeforeunload
如果您只需要它记住提交的值。onunload
不起作用,因为某些浏览器在该事件发生之前已经存储了旧的表单值。在 Firefox 中,隐藏输入的位置很重要。由于某种原因,如果您将其放在动态添加的字段下方,Firefox 会混淆它是哪个输入,并且无法记住该值。
该示例在 Opera 中不起作用。它可以在 Opera 中工作,但这很痛苦。Opera对load和unload事件的调用不一致,所以你必须使用onsubmit来代替,或者在轮询间隔上设置隐藏字段,或者其他什么。更糟糕的是,当 Opera 记住以前的表单字段值时,它实际上不会填充它们,直到 后 onload 已触发!这已经导致了很多很多表单脚本问题。如果您需要与 Opera 兼容,您可以通过在加载中设置一个小的超时来等待表单值输入来解决这个问题。
在好的浏览器中,您只需通过以下方式即可使其完美运行 不打破它.
Firefox 1.5 对单个浏览器会话的整个网页(包括其 JavaScript 状态)使用内存缓存。在访问的页面之间前后移动不需要页面加载,并且 JavaScript 状态会被保留。 来源
这在以下版本中得到支持 歌剧 和 网络工具包 也。然而 DOM 缓存只有在你遵守规则的情况下才有可能:
- 不要使用
onunload
,onbeforeunload
. 不要使用
Cache-control: no-store
或者must-revalidate
.
在 PHP 中你必须改变session.cache_limiter
从patently_ridiculous
(我认为他们拼写它nocache
) 到none
.session_cache_limiter('none');
- 不幸的是 HTTPS 也已经过时了。
如果您不强制浏览器重新加载页面,它们就不会。他们将保持 DOM 及其值不变,就像 RFC 2616 建议.
然而, ,如果您正在寻找存储数据的地方,这里有一个非常聪明的技巧 – window.name可以存储兆字节的数据. 。它不会发送到服务器,也不会在窗口之间共享。
还有 Flash cookies 和 HTML 5 localStorage
在 IE8 和 Safari 4 中实现。
第2步:处理表单的脚本将输入的值放入数组中,并将该数组存储到会话变量中(或文本/数据库/任何您认为合适的变量)。
步骤1:如果找到该会话变量(并且它还会清除会话变量),则输出表单的脚本会添加一个 javascript(依次填充表单)。
您可以在网页顶部制作自己的后退按钮,并使其比标准网络浏览器后退按钮更大、更漂亮。
在幕后,您的代码可以知道以前的状态是什么并恢复到它,或者如果没有以前的状态,您可以调用浏览器的后退函数吗?
阻止使用后退按钮。当按下后退按钮时,为用户重新呈现上一页,其中包含新字段,如果有意义的话可以显示,也可以隐藏。这样,用户就可以正常使用后退按钮,并且您可以完全控制“上一页”页面的外观。
在您的特定用例中,您只需渲染页面,其中所有字段可见并填充提交的值。
对于任何向导类型的流程来说,这是一个很好的模式,您可以提供一系列表单供用户填写,并且他们可以选择返回到上一个表单。
为了完全清楚,我建议您使用 关于捕获 onUnload 事件的建议 触发表单提交(以便您获取输入的值)并重新呈现“后退”将显示的上一页(没有值)。唯一的替代方法是使用 Ajax 在每次用户离开字段时发送输入的值,然后让每个页面通过 AJAX 与服务器进行检查以检索要显示的其他值。
以下是一些其他页面,讨论控制后退按钮的功能并使用卸载事件来保存表单数据: