tdc
tdc

Reputation: 5464

How can I use localStorage to save form data (text, textarea & checkbox)?

I have a huge form with a lot of inputs, textareas, and checkboxes. The form has a captcha on it. I want to save the form answers locally with localStorage so that if the captcha returns fail, their form data will be repopulated.

HTML

<form name="wellnessForm" id="wellnessForm" action="confirm.php" method="POST">
  <input type="text" name="firstName" />
  <br/>
  <input type="checkbox" name="noConcernsChk[]" value="1" />
  <input type="checkbox" name="noConcernsChk[]" value="2" />
  <br/>
  <textarea>
  </textarea>
</form>

jQuery

// DOM ready
$(function(){
    $(':text').blur(function(e){
        localStorage.setItem("flag", "set");
        var data = $('#wellnessForm').serializeArray();
        $.each(data, function(i, obj){
            localStorage.setItem(obj.name, obj.value);  
        });
    });
    $(':checkbox').click(function(e){
        localStorage.setItem("flag", "set");
        var data = $('#wellnessForm').serializeArray();
        $.each(data, function(i, obj){
            localStorage.setItem(obj.value, e.checked);
        });
    });

    // test if there is already saved data
    if( localStorage.getItem("flag") == "set" ){

        var data = $("#wellnessForm").serializeArray();

        // have to select the valid inputs based on their name attribute
        $.each(data, function(i, obj){

            // check if checkbox
            if(obj.name == 'noConcernsChk[]'){
                $( "[value='"+obj.value+"']:checkbox" ).prop('checked', true);
            }
            else{
                $("[name='" + obj.name + "']").val(localStorage.getItem(obj.name));
            }

        }); 
    }

    // provide mechanism to remove data (TODO: remove actual data not just kill the flag)
    $("#clearData").click(function(e){
        e.preventDefault();
        localStorage.setItem("flag", "");
    });

});

Source on codepen

How far I got
As you can see by my example, I have text inputs working. However I'm stuck on checkboxes. I would like to have the localStorage remember if the boxes were checked or not, and if they were, re-check them in the form for the user. I also haven't gotten textarea working yet but that shouldn't be too hard.

Question
How can you store checkbox state to local storage, and then recall it (and have the proper boxes checked)?

Upvotes: 2

Views: 7167

Answers (2)

mar10
mar10

Reputation: 14794

Another option would be to use an existing plugin.

For example persisto is an open source project that provides an easy interface to localStorage/sessionStorage and automates persistence for form fields (input, radio buttons, and checkboxes).
(Disclaimer: I am the author.)

persisto features

Note that this requires jQuery as a dependency.

For example:

<form name="wellnessForm" id="wellnessForm" action="confirm.php" method="POST">
  <input type="text" name="firstName" />
  <br/>
  <input type="checkbox" name="noConcernsChk[]" value="1" />
  <input type="checkbox" name="noConcernsChk[]" value="2" />
  <br/>
  <textarea name="detailsText">
  </textarea>
</form>

could be handled like this:

// Maintain client's preferences in localStorage:
var store = PersistentObject("wellnessData");

// Initialize form elements with currently stored data
store.writeToForm("#wellnessForm");

// Allow users to edit and save settings:
$("#wellnessForm").submit(function(e){
  // ... maybe some validations here ...
  store.readFromForm(this);
  e.preventDefault();
});

Upvotes: 1

wener
wener

Reputation: 7750

localStorage can store only string values.

first of all, you have to serialize the data use jQuery.serialize, then you can store it like

localStorage['data']=$('form').serialize()

edit

For restore, you have make some rules.Add data-binding to tag, save form value as key/value pair, the key is data-binding, then you can restore it.

Something like this

var data = {};
$('[data-binding]')
.each(function(){ data[$(this).data('binding')] = $(this).serialize(); })

localStorage['data'] = JSON.stringify(data);

For restore

var data = JSON.parse(localStorage['data']);
$('[data-binding]')
    .each(function()
    { 
         // handle the set value
         // need consider the different value type for different field type


         var $this = $(this);
         var val = data[$this.data('binding')];

         // for chechbox
         if($this.is('[type=checkbox]'))
            $this.prop('checked',val)
        // for others
        else
            $this.val(val);


    })

Example in my code:

// u5 = utils
U5 = {};

/**
 * 加载配置到界面,data-setting属性指定setting项
 * @param setting
 */
U5['LoadSettingToUI'] = function (setting)
{
    $('[data-setting]')
        .each(function()
        {
            var $this = $(this);
            var val;
            val = setting[$this.data('setting')];
            // 根据不同的类型进行值的转换 for jquery mobile
            if($this.is('select[data-role=slider]'))// 这里没有使用jqmData来判断,考虑兼容问题
            {
                $this.val(val?'on':'off');
            }else if($this.is('[type=checkbox]'))
            {
                $this.prop('checked',!!val);
            }else{
                $this.val(val);
            }
        });
};
/**
 * 从页面获取配置,data-setting属性指定setting项
 * @return {object}
 */
U5['GetSettingFromUI'] = function ()
{
    var setting = {};
    $('[data-setting]').each(function()
    {
        var $this = $(this);
        /**
         * @type {string|boolean}
         */
        var val;
        val = $this.val();
        // 根据不同的类型进行值的转换
        if(/^on|off$/.test(val))
        {
            val = val === 'on';
        }else if($this.is('[type=checkbox]'))
        {
            val = $this.prop('checked');
        }
        //
        setting[$this.data('setting')] = val;
    });
    return setting;
};

Full demo here

Upvotes: 2

Related Questions