本地存储保存N页数据直到最终提交

时间:2013-01-11 16:56:00

标签: javascript jquery local-storage

我的场景:我有一个9页长的应用程序,总共大约125个不同类型和大小的输入(只有输入,文本区域,无线电和选择)。我想使用本地存储来保存表单值。用户可以在页面之间移动(例如,在提交应用程序之前进行查看),因此我不想在提交应用程序之前清除本地存储,如果它们在页面之间发生更改,则表单应从本地存储重新加载其值。提交表单后,我将清除本地存储,但在此之前,应保留本地存储。

我发现这个很棒的jquery plugin和一个demo page似乎几乎可以满足我的需求 - 好吧,有两个例外:

1)插件会提示用户是否要恢复之前输入的信息,而这些信息我不想拥有(我宁愿让数据存在)。我在表单底部的导航按钮只是“上一页”和“继续”(在第一页上,它只是“继续”,在最后一页上它们将是“上一页”和“提交申请表”)。

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>

1 个答案:

答案 0 :(得分:0)

我认为这会比现在更加艰难。这是我提出的解决方案:

按下提交按钮时在表单页面上:

<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, '  ')));
        });             
    }
}

一些帮助我的文章(有些是SO,有些是外部的):
  - Clear 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

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