本地存储保存表单N页数据,直到最后提交

Local Storage to hold form N pages data until final submit

本文关键字:数据 直到最后 提交 存储 保存 表单      更新时间:2023-09-26

我的场景是:我有一个9页长的应用程序,总共有125个不同类型和大小的输入(只有输入、文本区、单选和选择)。我想使用本地存储来保存表单值。用户可以在页面之间移动(例如,在提交应用程序之前查看),所以我不想在他们提交应用程序之前清除本地存储,如果他们从一个页面更改到另一个页面,表单应该从本地存储重新加载其值。一旦他们提交表单,那么我将清除本地存储,但在此之前,本地存储应该保留。

我发现了这个伟大的jquery插件和一个演示页面,它似乎几乎做了我正在寻找的-好吧,有两个例外:

1)插件提示用户,如果他们想恢复他们以前输入的信息,我宁愿没有(我宁愿有数据只是在那里)。我在表单底部的导航按钮只有"上一页"answers"继续"(在第一页,它只是"继续",在最后一页,它们将是"上一页"answers"提交申请")。

2)插件将提示用户,即使没有数据加载(这将是一个非问题,如果我可以只是让它加载数据,如果有任何,跳过它,如果没有)。例如,第一次访问页面时将提示用户恢复先前输入的数据。

这里是演示页面中使用的jquery.remember-state.js的链接。

=======================================================
我把上面的演示和jquery.remember-state.js调整到尝试,使它做我需要的,但它不能正常工作。
这是我的(jsFiddle)。
注1: jsFiddle只是为了显示我的代码,不一定是jsFiddle环境中的工作示例。如果您将代码复制到本地环境中,您应该能够访问console.log以查看是否/哪些内容被保存到localStorage中。
注2: S.O.想要内联格式化的代码,所以我会看看我能做些什么来使它正确格式化。

<!DOCTYPE HTML>
<html lang="en-US">
<head>
  <title>LocalStorage and Unload State Save</title>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="../jQueryPlugins/RememberState/form.css" />
  <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
  <!-- use the modified jquery.remember-state.js code in the JavaScript panel instead
       the script tag below is the original js file
  <script src="http://shaneriley.com/jquery/remember_state/jquery.remember-state.js"></script>-->
  <script type='text/javascript'>//<![CDATA[ 
$(window).load(function(){
(function($) {
  /* jQuery form remember state plugin
     Name: rememberState
     Version: 1.3
     Description: When called on a form element, localStorage is used to
     remember the values that have been input up to the point of either
     saving or unloading. (closing window, navigating away, etc.) If
     localStorage isn't available, nothing is bound or stored.
     The plugin looks for an element with a class of remember_state to show
     a note indicating there is stored data that can be repopulated by clicking
     on the anchor within the remember_state container. If the element doesn't
     exist, it is created and prepended to the form.
     Usage: $("form").rememberState("my_object_name");
     Notes: To trigger the deletion of a form's localStorage object from
     outside the plugin, trigger the reset_state event on the form element
     by using $("form").trigger("reset_state");
  */
  if (!window.localStorage || !window.JSON) {
    if (console && console.log) {
      !window.localStorage && console.log("ERROR: you browser does not support" +
        " localStorage (use this polyfill https://gist.github.com/350433)");
      !window.JSON&& console.log("ERROR: you browser does not support" +
        " JSON (use this polyfill http://bestiejs.github.com/json3/)");
    }
    return $.fn.rememberState = function() { return this; };
  }
  var remember_state = {
    name: "rememberState",
    clearOnSubmit: false, //default was true;
    //  ****************************
    /*noticeDialog: (function() {
        return $("<p />", {"class": "remember_state"})
        .html('Do you want to <a href="#">restore your previously entered info</a>?');
    })(),*/
    //  ****************************    
    ignore: null,
    noticeSelector: ".remember_state",
    use_ids: false,
    objName: false,
    clickNotice: function(e) {
      var data = JSON.parse(localStorage.getItem(e.data.instance.objName)),
          $f = $(this).closest("form"),
          $e;
      for (var i in data) {
        $e = $f.find("[name='"" + data[i].name + "'"]");
        if ($e.is(":radio, :checkbox")) {
          $e.filter("[value=" + data[i].value + "]").prop("checked", true);
        }
        else if ($e.is("select")) {
          $e.find("[value=" + data[i].value + "]").prop("selected", true);
        }
        else {
          $e.val(data[i].value);
        }
        $e.change();
      }
      e.data.instance.noticeDialog.remove();
      e.preventDefault();
    },
    chooseStorageProp: function() {
      if (this.$el.length > 1) {
        if (console && console.warn) {
          console.warn("WARNING: Cannot process more than one form with the same" +
            " object. Attempting to use form IDs instead.");
        }
        this.objName = this.$el.attr("id");
      }
    },
    errorNoID: function() {
      if (console && console.log) {
        console.log("ERROR: No form ID or object name. Add an ID or pass" +
          " in an object name");
      }
    },
    saveState: function(e) {
      var instance = e.data.instance;
      var values = instance.$el.serializeArray();
      // jQuery doesn't currently support datetime-local inputs despite a
      // comment by dmethvin stating the contrary:
      // http://bugs.jquery.com/ticket/5667
      // Manually storing input type until jQuery is patched
      instance.$el.find("input[type='datetime-local']").each(function() {
        var $i = $(this);
        values.push({ name: $i.attr("name"), value: $i.val() });
      });
      values = instance.removeIgnored(values);
      values.length && internals.setObject(instance.objName, values);
    },
    save: function() {
      var instance = this;
      if (!this.saveState) {
        instance = this.data(remember_state.name);
      }
      instance.saveState({ data: { instance: instance } });
    },
    removeIgnored: function(values) {
      if (!this.ignore) { return values; }
      $.each(this.ignore, function(i, name) {
        $.each(values, function(j, input) {
          if (name === input.name) { delete values[j]; }
        });
      });
      return values;
    },
    init: function() {
      var instance = this;
        //  ****************************
     /* if (instance.noticeDialog.length && instance.noticeDialog.jquery) {
        instance.noticeDialog.find("a").bind("click." + instance.name, {
          instance: instance
        }, instance.clickNotice);
      }*/
        //  ****************************
      instance.chooseStorageProp();
      if (!instance.objName) {
        instance.errorNoID();
        return;
      }
      if (localStorage[instance.objName]) {
            //  **************************** 
        /*if (instance.noticeDialog.length && typeof instance.noticeDialog === "object") {
          instance.noticeDialog.prependTo(instance.$el);
        }
        else {
          instance.$el.find(instance.noticeSelector).show();
        }*/
            //  ****************************
      }
      if (instance.clearOnSubmit) {
        instance.$el.bind("submit." + instance.name, function() {
          instance.$el.trigger("reset_state");
          $(window).unbind("unload." + instance.name);
        });
      }
      instance.$el.bind("reset_state." + instance.name, function() {
          localStorage.removeItem(instance.objName);
      });
        //  ****************************
      /*$(window).bind("unload." + instance.name, { instance: instance }, instance.saveState);
      instance.$el.find(":reset").bind("click.remember_state", function() {
          $(this).closest("form").trigger("reset_state");
      });*/
    }
  };
  var internals = {
    setObject: function(key, value) { localStorage[key] = JSON.stringify(value); },
    getObject: function(key) { return JSON.parse(localStorage[key]); },
    createPlugin: function(plugin) {
      $.fn[plugin.name] = function(opts) {
        var $els = this,
            method = $.isPlainObject(opts) || !opts ? "" : opts;
        if (method && plugin[method]) {
          plugin[method].apply($els, Array.prototype.slice.call(arguments, 1));
        }
        else if (!method) {
          $els.each(function(i) {
            var plugin_instance = $.extend(true, {
              $el: $els.eq(i)
            }, plugin, opts);
            $els.eq(i).data(plugin.name, plugin_instance);
            plugin_instance.init();
          });
        }
        else {
          $.error('Method ' +  method + ' does not exist on jQuery.' + plugin.name);
        }
        return $els;
      };
    }
  };
  internals.createPlugin(remember_state);
})(jQuery);
});//]]>  
</script>
  <script>
  var thisPage = 'page1';   //defines the variable to use for local storage
    $(function() {
      $("form")
        .rememberState({objName: thisPage})
        .submit(function() {localStorage.setItem(thisPage, $(this).serializeArray());
        return true;
      });
    });
  </script>
</head>
<body>
  <form method="post" action="page2.cfm">
    <fieldset>
      <dl>
        <dt><label for="first_name">First Name</label></dt>
        <dd><input type="text" name="first_name" id="first_name" /></dd>
        <dt><label for="last_name">Last Name</label></dt>
        <dd><input type="text" name="last_name" id="last_name" /></dd>
      </dl>
    </fieldset>
    <fieldset class="actions">
      <input type="submit" value="Continue" />
    </fieldset>
  </form>
</body>
</html>

我以为这会比实际情况更困难。下面是我想到的解决方案:

当submit按钮被按下时,在表单页面上:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>  
<script type="text/javascript">    
$(document).ready(function()    {
var thisPageID = 'page1';  // each page gets its own    
    $('form').submit(function() {    
        var formFields = $(this).serialize();    
        localStorage.setItem(thisPageID, formFields);    
        data = localStorage.getItem(thisPageID);    
        return true;    
    });    
});    
</script>    

然后在最后一个页面上,我根据页面id从本地存储中检索每个页面的数据,并用数据填充div标记。

function getLocalData(id){
    var ApplicantData;
    ApplicantData = localStorage.getItem(id);
    if (ApplicantData){
        $.each(ApplicantData.split('&'), function (index, elem) {
            var vals = elem.split('=');
            var $div = $("#"+vals[0]);
            var separator = '';
            //  console.log($div);
            if ($div.html().length > 0) {
                separator = ', ';
            }
            $div.html($div.html() + separator + decodeURIComponent(vals[1].replace(/'+/g, '  ')));
        });             
    }
}

一些对我有帮助的文章(有些是内部的,有些是外部的):
-清除localStorage
——http://www.simonbingham.me.uk/index.cfm/main/post/uuid/using-html5-local-storage-and-jquery-to-persist-form-data-47
- http://www.thomashardy.me.uk/using-html5-localstorage-on-a-form

还有更多,但这是我仍然在标签中打开的全部。