jQuery插件序列化表单并恢复/填充表单?

jQuery插件序列化表单并恢复/填充表单?,jquery,forms,serialization,Jquery,Forms,Serialization,是否有jQuery插件可以序列化表单,然后在给定序列化值的情况下恢复/填充表单?我知道表单插件可以序列化为querystring,但是我还没有找到任何可以从querystring恢复表单的东西 我想做的是序列化表单值,在表单更改时存储为cookie,然后在页面首次加载时从cookie(如果存在)恢复表单 我已经找到了这个拼图的各个部分(表单插件、cookie插件、各种不能恢复的autosave插件),但是在我从各个部分拼凑出一些东西之前,我想确保没有一个很好的罐装解决方案等着我 谢谢 Jim以下

是否有jQuery插件可以序列化表单,然后在给定序列化值的情况下恢复/填充表单?我知道表单插件可以序列化为querystring,但是我还没有找到任何可以从querystring恢复表单的东西

我想做的是序列化表单值,在表单更改时存储为cookie,然后在页面首次加载时从cookie(如果存在)恢复表单

我已经找到了这个拼图的各个部分(表单插件、cookie插件、各种不能恢复的autosave插件),但是在我从各个部分拼凑出一些东西之前,我想确保没有一个很好的罐装解决方案等着我

谢谢


Jim

以下是我根据其他人的作品推出的一些小东西,特别是:


查看我的jQuery填充插件:


填充所有表单元素、标签和任何包含的HTML元素。

非常感谢Barnabas Kendall的回答,非常有用

但是,我发现了一个关于恢复单选按钮的错误,它没有选择正确的单选按钮,而是将保存的值复制到组中的所有按钮

幸运的是,修复起来很简单。 替换

if(this.type == 'checkbox') {


感谢Barnabas Kendall提供的初始功能和Eggert Jóhannesson提供的单选按钮修复功能,它将正确更新单选按钮

我遇到了一个复选框的问题,如果它们没有被选中,它们将不会被放入数组中,到目前为止还不错。但由于未选中复选框时未存储复选框的状态,如果用户在编辑表单时选中了复选框,则无法恢复此状态

因此,我扩展了还原功能以取消选中数据数组中不存在的所有复选框,这将确保无论在执行还原之前表单中发生了什么更改,都能正确还原复选框的状态:

if (this.name && data[this.name]) {
   if(this.type == "checkbox" || this.type == "radio") {
       $(this).prop("checked", (data[this.name] == $(this).val()));
   } else {
       $(this).val(data[this.name]);
   }
} else if (this.type == "checkbox") {
   $(this).prop("checked", false);
}
完整功能:

$.fn.values = function(data) {
   var inps = $(this).find(":input").get();

    if(typeof data != "object") {
       // return all data
        data = {};

        $.each(inps, function() {
            if (this.name && (this.checked
                        || /select|textarea/i.test(this.nodeName)
                        || /text|hidden|password/i.test(this.type))) {
                data[this.name] = $(this).val();
            }
        });
        return data;
    } else {
        $.each(inps, function() {
            if (this.name && data[this.name]) {
                if(this.type == "checkbox" || this.type == "radio") {
                    $(this).prop("checked", (data[this.name] == $(this).val()));
                } else {
                    $(this).val(data[this.name]);
                }
            } else if (this.type == "checkbox") {
                $(this).prop("checked", false);
            }
       });
       return $(this);
    }
};

我对巴纳巴斯的回答作了如下扩展:

  • 支持具有相同名称的多个输入(复选框通常会这样做)
  • 缓存选择器如果可能,请删除不必要的$

        /* jQuery.values: get or set all of the name/value pairs from child input controls   
         * @argument data {array} If included, will populate all child controls.
         * @returns element if data was provided, or array of values if not
        */
    
        $.fn.values = function(data) {
            var els = this.find(':input').get();
    
            if(arguments.length === 0) {
                // return all data
                data = {};
    
                $.each(els, function() {
                    if (this.name && !this.disabled && (this.checked
                                    || /select|textarea/i.test(this.nodeName)
                                    || /text|hidden|password/i.test(this.type))) {
                        if(data[this.name] == undefined){
                            data[this.name] = [];
                        }
                        data[this.name].push($(this).val());
                    }
                });
                return data;
            } else {
                $.each(els, function() {
                    if (this.name && data[this.name]) {
                        var names = data[this.name];
                        var $this = $(this);
                        if(Object.prototype.toString.call(names) !== '[object Array]'){
                            names = [names]; //backwards compat to old version of this code
                        }
                        if(this.type == 'checkbox' || this.type == 'radio') { 
                            var val = $this.val();
                            var found = false;
                            for(var i = 0; i < names.length; i++){
                                if(names[i] == val){
                                    found = true;
                                    break;
                                }
                            }
                            $this.attr("checked", found);
                        } else {
                            $this.val(names[0]);
                        }
                    }
                });
                return this;
            }
        };
    
    /*jQuery.values:从子输入控件获取或设置所有名称/值对
    *@argument data{array}如果包含,将填充所有子控件。
    *@如果提供了数据,则返回元素;如果未提供数据,则返回值数组
    */
    $.fn.values=函数(数据){
    var els=this.find(':input').get();
    if(arguments.length==0){
    //返回所有数据
    数据={};
    $.each(els,函数(){
    如果(this.name&!this.disabled&&(this.checked
    ||/select | textarea/i.test(this.nodeName)
    ||/text | hidden | password/i.test(this.type))){
    if(数据[this.name]==未定义){
    数据[this.name]=[];
    }
    数据[this.name].push($(this.val());
    }
    });
    返回数据;
    }否则{
    $.each(els,函数(){
    if(this.name&&data[this.name]){
    var name=data[this.name];
    var$this=$(this);
    if(Object.prototype.toString.call(names)!='[Object Array]'){
    names=[names];//向后兼容此代码的旧版本
    }
    如果(this.type=='checkbox'| | this.type=='radio'){
    var val=$this.val();
    var=false;
    对于(var i=0;i

  • 如果您需要处理此情况:
    -而您,贪婪的家伙,需要解析整个矩阵:

    要填充:

    检索值:

    使用
    $('form')。序列化()
    并将结果传递给此函数:

    $.fn.values = function(data) {
       var inps = $(this).find(":input").get();
    
        if(typeof data != "object") {
           // return all data
            data = {};
    
            $.each(inps, function() {
                if (this.name && (this.checked
                            || /select|textarea/i.test(this.nodeName)
                            || /text|hidden|password/i.test(this.type))) {
                    data[this.name] = $(this).val();
                }
            });
            return data;
        } else {
            $.each(inps, function() {
                if (this.name && data[this.name]) {
                    if(this.type == "checkbox" || this.type == "radio") {
                        $(this).prop("checked", (data[this.name] == $(this).val()));
                    } else {
                        $(this).val(data[this.name]);
                    }
                } else if (this.type == "checkbox") {
                    $(this).prop("checked", false);
                }
           });
           return $(this);
        }
    };
    

    序列化为字符串:
    var s=$('form').first().serialize()

    根据该字符串还原:
    $('form').first()。反序列化

    当然,您需要一个反序列化插件,比如我的

    更多信息:

    下面是一个JSFIDLE,让您可以随意设置值、清除、重置和“反序列化”:

    • 支持具有相同名称的多个输入(复选框通常会这样做)
    • 尽可能缓存选择器
    • 返回所有输入的值,如果未设置
      复选框
      收音机
      ,则该值为
      null
    • 如果值为
      null

      $.fn.formData=函数(值){
      变量形式=$(此);
      var inputs=$(':input',form).get();
      var hasNewValues=typeof values=='object';
      if(hasNewValues){
      $.each(输入,函数(){
      var输入=$(此);
      var value=值[this.name];
      if(values.hasOwnProperty(this.name)){
      开关(此.type){
      案例“复选框”:
      input.prop('checked',value!==null&&value);
      打破
      “无线电”案例:
      如果(值===null){
      input.prop('checked',false);
      }else if(input.val()==值){
      输入.prop(“选中”,为真);
      }
      打破
      违约:
      输入.val(值);
      }
      
          /* jQuery.values: get or set all of the name/value pairs from child input controls   
           * @argument data {array} If included, will populate all child controls.
           * @returns element if data was provided, or array of values if not
          */
      
          $.fn.values = function(data) {
              var els = this.find(':input').get();
      
              if(arguments.length === 0) {
                  // return all data
                  data = {};
      
                  $.each(els, function() {
                      if (this.name && !this.disabled && (this.checked
                                      || /select|textarea/i.test(this.nodeName)
                                      || /text|hidden|password/i.test(this.type))) {
                          if(data[this.name] == undefined){
                              data[this.name] = [];
                          }
                          data[this.name].push($(this).val());
                      }
                  });
                  return data;
              } else {
                  $.each(els, function() {
                      if (this.name && data[this.name]) {
                          var names = data[this.name];
                          var $this = $(this);
                          if(Object.prototype.toString.call(names) !== '[object Array]'){
                              names = [names]; //backwards compat to old version of this code
                          }
                          if(this.type == 'checkbox' || this.type == 'radio') { 
                              var val = $this.val();
                              var found = false;
                              for(var i = 0; i < names.length; i++){
                                  if(names[i] == val){
                                      found = true;
                                      break;
                                  }
                              }
                              $this.attr("checked", found);
                          } else {
                              $this.val(names[0]);
                          }
                      }
                  });
                  return this;
              }
          };
      
      $.fn.deserialize = function (serializedString) 
      {
          var $form = $(this);
          $form[0].reset();
          serializedString = serializedString.replace(/\+/g, '%20');
          var formFieldArray = serializedString.split("&");
      
          // Loop over all name-value pairs
          $.each(formFieldArray, function(i, pair){
              var nameValue = pair.split("=");
              var name = decodeURIComponent(nameValue[0]);
              var value = decodeURIComponent(nameValue[1]);
              // Find one or more fields
              var $field = $form.find('[name=' + name + ']');
      
              // Checkboxes and Radio types need to be handled differently
              if ($field[0].type == "radio" || $field[0].type == "checkbox") 
              {
                  var $fieldWithValue = $field.filter('[value="' + value + '"]');
                  var isFound = ($fieldWithValue.length > 0);
                  // Special case if the value is not defined; value will be "on"
                  if (!isFound && value == "on") {
                      $field.first().prop("checked", true);
                  } else {
                      $fieldWithValue.prop("checked", isFound);
                  } 
              } else { // input, textarea
                  $field.val(value);
              }
          });
          return this;
      }