使用jQuery选择/提交仅更改的表单字段

Dim*_*kiy 14 javascript jquery asp.net-mvc-3

我正在寻找一种方法只将更改的表单字段提交给服务器.所以,假设我有一个表格

<form>
    <input type="text" name="a"/>
    <select name="b">...</select>
    <input type="checkbox" name="c"/>
</form>
Run Code Online (Sandbox Code Playgroud)

已经填充了某些数据.用户编辑表单并单击"提交".如果用户只更改了输入b,那么我只想提交输入b.如果只更改了a和c,我只想提交a和c.等等.

我可以自己写一些东西来完成这个,但我想知道可能已经有一些我可以使用的东西了吗?理想情况下,我希望代码简短.像这样的东西是完美的:

$('form').serialize('select-only-changed');
Run Code Online (Sandbox Code Playgroud)

另外,我遇​​到了这个http://code.google.com/p/jquery-form-observe/,但我发现它存在问题.这个插件是否能够稳定运行?

ndp*_*ndp 27

另一种方法是serialize在页面加载时使用表单,然后在提交时,仅提交更改.

$(function() {

  var $form = $('form');

  var startItems = convertSerializedArrayToHash($form.serializeArray()); 

  $('form').submit() {
    var currentItems = convertSerializedArrayToHash($form.serializeArray());
    var itemsToSubmit = hashDiff( startItems, currentItems);

    $.post($form.attr('action'), itemsToSubmit, etc.
  }
});
Run Code Online (Sandbox Code Playgroud)

然后,您需要编写的所有hashDiff功能都是直接且通常有用的功能.

这很好,因为它可以很容易地打包到一个插件中,如果你使用的是Ajax,它可以在同一个表单上重复工作.

function hashDiff(h1, h2) {
  var d = {};
  for (k in h2) {
    if (h1[k] !== h2[k]) d[k] = h2[k];
  }
  return d;
}

function convertSerializedArrayToHash(a) { 
  var r = {}; 
  for (var i = 0;i<a.length;i++) { 
    r[a[i].name] = a[i].value;
  }
  return r;
}
Run Code Online (Sandbox Code Playgroud)

这是一个最小的测试:

  describe('hashDiff()', function() {
    it('should return {} for empty hash',function() {
      expect(hashDiff({},{})).toEqual({});
    });
    it('should return {} for equivalent hashes',function() {
      expect(hashDiff({a:1,b:2,c:3},{a:1,b:2,c:3})).toEqual({});
    });
    it('should return {} for empty hash',function() {
      expect(hashDiff({a:1,b:2,c:3},{a:1,b:3,c:3})).toEqual({b:3});
    });
  });
Run Code Online (Sandbox Code Playgroud)


Mar*_*man 15

另一种选择是将字段标记为disabled提交之前.默认情况下,disabled不会使用默认表单帖子序列化或提交字段.

简单的例子:

function MarkAsChanged(){
    $(this).addClass("changed");
}
$(":input").blur(MarkAsChanged).change(MarkAsChanged);

$("input[type=button]").click(function(){
    $(":input:not(.changed)").attr("disabled", "disabled");
    $("h1").text($("#test").serialize());
});
Run Code Online (Sandbox Code Playgroud)

jsfiddle.


小智 5

您可以在输入字段中添加"oldvalue"参数.在使用JavaScript或服务器端生成页面时填充此值.

<input name="field1" value="10" oldvalue="10">
Run Code Online (Sandbox Code Playgroud)

然后使用以下函数序列化:

function serializeForm() {
    data = "";
    $("input,textarea").each(function (index, obj) {
        if ($(obj).val() != $(obj).attr("oldvalue")) {
            data += "&" + $(obj).serialize();
        }
    });
    return data.substr(1);
}
Run Code Online (Sandbox Code Playgroud)

数据发送到服务器后,您的脚本可以更新'oldvalue'参数,以防止再次发送数据,除非进行进一步的更改.