Autosave in MVC (ASP.NET)

7hi4g0 picture 7hi4g0 · Jun 7, 2013 · Viewed 7.9k times · Source

I'm implementing a web system to manage some data from my company. We are using MVC (more specically ASP.NET MVC 4), in which I'm completely new to.

The problem I'm having is that we planned to use autosave, just like GMail. We were planning on using change events queuing and once in a while submit changes through ajax. On a first thought I would use JavaScript, not sure though if that's the best way for MVC. Another trouble that I'm having is that some of the information the user will enter is not inside forms, but in a table instead. Also the layout of the page is a little sparse and I don't believe I can wrap all the inputs into a single form or even if I should do it.

My questions are:

  1. What is the best way to implement autosave using MVC, should I use or not JavaScript?
  2. Is there any library in JavaScript or a feature in ASP.NET MVC to implement the queuing or should I do it by hand?
  3. Also, can I use form to wrap table rows?

Note: I've seen some suggestions to use localstorage or others client persistency, but what I need is server persistency, and we don't even have a save button on the page.

Thanks for the help in advance ;)

Answer

karaxuna picture karaxuna · Jun 7, 2013

You can add form="myformid" attribute to elements that are outside form to include it in form. I would add data-dirty="false" attribute to all elements at the beginning and attach change event that would change data-dirty attribute of changing element to true. Then you can save form each 30 seconds for example (get elements that have data-change=true and pass to server). After saving, every element's data-dirty becomes false again. Example of autosave with jQuery:

window.setInterval(function(){
    var dirtyElements = $('#myformid').find('[data-dirty=true]').add('[form=myformid][data-dirty=true]');
    if(dirtyElements.length > 0){
        var data = dirtyElements.serialize();
        $.post('saveurl', data, function(){
            dirtyElements.attr('data-dirty', false);
            alert('data saved successfully');
        });
    }
}, 30000); // 30 seconds

Attaching event to all elements of form:

$(function(){
    var formElements = $('#myformid')
                           .find('input, select, textarea')
                           .add('[form=myformid]')
                           .not(':disabled')
                           .each(function(){
                                $(this).attr('data-dirty', false).change(function(){
                                    $(this).attr('data-dirty', true);
                                });
                           });
});