使用jQuery来存储复杂表单的状态

19

我有一个相当复杂的表单,其中有许多由用户填写的“步骤”。一些步骤(将它们视为表单段)具有默认选项,但是在点击“输入自定义值”时,它们会显示一组此前隐藏的字段,用户可以在其中输入信息。以下是一个示例:

<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。这是我的任务。我想让用户保存表单的状态。因此,一旦用户填写了整个表单,为某些段选择平均默认值,并为其他段输入自定义值,则用户可以单击按钮并将整个状态保存以供稍后恢复。 我在思考,如果我可以将状态保存在可以序列化的对象中,我就可以将其保存在数据库表或其他持久存储中。

用户可以在以后的某个时间返回并重构整个以前的会话。

我该如何做到这一点?有getAttributes插件http://plugins.jquery.com/project/getAttributes和jQuery serialize方法,但我无法开始。请指导我正确的方向。

4个回答

25

下面是两个帮助处理这个过程的函数。 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"));

5
这非常有用!对于不知道如何调用该函数的人,我需要注意一下:我是这样使用它的: sessionStorage.setItem("formdata",formToString(jQuery("#form")));,然后这样调用它:var storedform = sessionStorage.getItem("formdata"); stringToForm(storedform,jQuery("#form")); - Julian K
$j(this) 表达式是打字错误吗?使用此脚本时我得到 JavaScript 错误,并且认为应该是 $(this),对吗? - Matt
这不是一个打字错误,但我从答案中删除了它,因为只有 $ 是访问 jQuery 的默认方式。请参阅 https://learn.jquery.com/using-jquery-core/avoid-conflicts-other-libraries/ 以获取更多信息。 - Reese
@JulianK您好,谢谢您。您能否详细说明一下sessionStorage?在我的情况下,用户被引导离开表单,然后再次回到它,显然当用户返回时,我不希望用户每次都点击相同的下拉菜单 - 这将很烦人。非常感谢您的任何想法。 - BenKoshy
1
应该使用formObject[this.id] = elem.prop("checked");来使其工作。(jQuery 2.2.0) - Artistan
显示剩余5条评论

1

我会首先使用dumbFormState jQuery插件

该插件实际上可以在您输入时自动保存内容等等,因此当他们返回时,它已经再次填写,您不需要服务器端来完成它。

之后,我会创建更多的jQuery插件,以在dumbFormState插件之后加载,然后显示/隐藏已填写的区域。如果在有人填写表单之前调用此插件,它将是空白的,您的逻辑也不应显示/隐藏空白内容。


0

我猜你正在寻找.serialize(),它可以序列化表单数据。为了做到这一点,你的input元素需要在一个form标签内,而且所有的元素都必须有name属性。

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

alert(form1data);

谢谢您的建议。正如我在问题中所提到的,我知道序列化方法,但是对我来说,那似乎只是解决方案的一部分。要恢复表单,我必须读取存储的序列化数据,然后将表单重构回原始状态,包括所有自定义条目...也就是说,如果隐藏的段落被显示出来以输入自定义值,我想把它带回来。我该怎么做呢? - punkish
@punkish:我不知道jQuery核心中是否有deserialize()方法。因此,您要么编写自己的自定义解析器,要么寻找插件。 - jAndy
@punkish 这是我的formstate插件 - 它是serialize()和缺失的unserialize()的替代品,它可以处理对象而不是字符串;我想要一个轻量级的插件,只处理表单状态,而不是字符串表示或存储方法。它以明智的方式处理单选按钮、复选框等。 - mindplay.dk

0

你可以将非默认数据放入json中,然后通过post请求将其发送到服务器进行保存。

因此,一旦用户返回页面,您就会自动查看他们是否保存了某些内容,然后您可以询问他们是否要使用它或从保存的数据中填充表单。

保存默认值是浪费带宽的,因为您不会改变加载表单时的默认值。

更新:

要将其保存为JSON,我认为只需将其构建成一个长字符串即可,因为格式很简单,所以您将所有内容都作为单个字符串发送。

您可能还想保存他们所在的阶段,或者在他们进入每个阶段时自动保存,这可能是更好的选择,以防计算机崩溃,他们不必重新开始,但您可能需要启用复选框来打开自动保存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接