17

How to implement a periodical save of a form in the background? Same kinda thing that gmail does.

Phrogz
  • 296,393
  • 112
  • 651
  • 745
krunal shah
  • 16,089
  • 25
  • 97
  • 143

5 Answers5

19
setInterval(function(){
  var form = $('#my-form-id');
  var method = form.attr('method').toLowerCase();      // "get" or "post"
  var action = form.attr('action');                    // url to submit to
  $[method](action, form.serialize(), function(data){
    // Do something with the server response data      
    // Or at least let the user know it saved
  });
},10000);                                              // do it every 10 seconds

If you don't want to use the method of the form, but always want to use 'post', then use:

$.post(action, form.serialize(), ... );

And, if you want to supply your own action for the autosave that is different from the action for the actual save:

$.post("/autosave/comments", form.serialize(), ... );
Phrogz
  • 296,393
  • 112
  • 651
  • 745
  • 1
    -@Phrogz, can you explain in your 1st code block where form validation would go? – tim peterson Dec 01 '12 at 12:50
  • 1
    @timpeterson 3.5 years too late a response, but: I assume you are talking about client-side validation, and you don't want to submit the form if it's invalid? If so, then it's just code, right? `if (formIsValid(form)) $[method](...);` – Phrogz Jul 27 '16 at 16:52
4

You would need a timed loop on the client side that would save the form every x seconds/minutes. A crude way of doing this would be to have a setTimeout javascript function that collects the form's field values and updates the model via an update (PUT in Rails' case) AJAX request.

Example

Here's a crude way of doing it (i.e. there might be a better way):

// repeat every 10 seconds
var repeatTime = 10 * 1000; 

function updateModel(){
    // get field values (using jQuery, etc.)
    // make ajax request using these field values 
    //(make sure put parameters match model attribute names)
    console.log('updated');
    setTimeout(updateModel, repeatTime); // start call over again
}

setTimeout(updateModel, repeatTime);

I included the console.log so that you can test this out in Firebug right now and see that the updateModel executes every 10 seconds. I would recommend using jQuery to generate the PUT AJAX requests.

McStretch
  • 20,495
  • 2
  • 35
  • 40
2

Why not do this purely on the client, using a local database (or whatever)? That should reduce complexity, server load and bandwidth usage.

Permanent or per-session storage -- whatever's appropriate -- and you can save after every keystroke: no need for setTimeout().

Sam Dutton
  • 14,775
  • 6
  • 54
  • 64
1

Sisyphus.js: Gmail-like client-side drafts and bit more. Plugin developed to save html forms data to LocalStorage to restore them after browser crashes, tabs closings and other disasters. http://sisyphus-js.herokuapp.com

Smashing Magazine article: http://coding.smashingmagazine.com/2011/12/05/sisyphus-js-client-side-drafts-and-more/

Himanshu Saini
  • 702
  • 11
  • 25
0

Version that works without jquery:

function urlencodeFormData(fd) {
    var s = '';
    function encode(s) { return encodeURIComponent(s).replace(/%20/g,'+'); }
    for (var pair of fd.entries()) {
        if(typeof pair[1]=='string') {
            s += (s?'&':'') + encode(pair[0])+'='+encode(pair[1]);
        }
    }
    return s;
}

setInterval(function() {
    var form = document.getElementById('my-form-id');
    var request = new XMLHttpRequest();
    request.open(form.method, form.action);
    request.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
    request.send(urlencodeFormData(new FormData(form)));
}, 10000);

If you need to do something with the server response see this post: https://blog.garstasio.com/you-dont-need-jquery/ajax/#posting

Marián Černý
  • 15,096
  • 4
  • 70
  • 83