Frage

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 ;)

War es hilfreich?

Lösung

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

Andere Tipps

Answers...

  1. Definitely use javascript and AJAX, you don't want the page to keep refreshing when the user makes a change
  2. I don't know about any libraries, but I would be happy to do this by hand. Detect the changes using javascript and then post the data via AJAX
  3. You can access any form field from your controller with the FormCollection parameter, or the classic Form["fieldname"] method. As long as your table cells have unique name values you will be able to fetch the data
  1. That's really your only option. If you submit the form without Ajax then you're going to experience a full page reload. It doesn't sound like that's what you want.

  2. There are a lot of ways to implement this (also look at the answer karaxuna just posted). You could attach an event to all of your inputs and any time any of them change use a timer to save the data. If another change event occurs then reset the timer so you don't end up saving for each change event.

    Or if you don't need it to be that complex just use a simple timer to save every X minutes regardless of whether any new data has been entered.

  3. You can put a table within a form; there's nothing wrong with that. I would just suggest using proper inputs so it's easy to serialize the data and send it to the server.

1 ) Use Javascript! jQuery makes it fairly easy to execute your auto saves asynchronously in the background using AJAX calls.

2 ) None that i am aware of, but it shouldn't be too hard.

3 ) No, unfortunately you can't, but you could do something like this:

<table id="mainTable">
 <tr>
  <td>
   <form id="someForm">
        <table class="aSubTable">
         <tr>
          <td><!-- fields go here --></td>
          <td><!-- fields go here --></td>
         </tr>
        </table>
   </form>
  </td>
 <tr>
</table>

(i am aware that this example code doesn't leverage Razor, but it shouldn't be hard to figure out which parts to replace with Razor for your own means)

we can Auto save form using Ajax 
function AutoSaveMyForm(spanid) {
    var dataToPost = $("form").serialize()
    $.ajax({
        type: "POST",
        url: "/MyController/AutoSaveActionMethod",
        data: dataToPost,
        cache: false,
        success: function(resultdata) {
            if (resultdata['Code'] == '1') { // show success saved
                console.log(resultdata['ResultMsg']);
                if (spanid == "SaveLastStep") {
                    window.location = "/Dashboard/Index";
                }
                $('#' + spanid).html('Save Successfully.');
            } else if (resultdata['Code'] == '0') { // show error
                console.log(resultdata['ResultMsg']);
                $('#' + spanid).html('Not Saved');
            } else { // an error has occured
                $('#' + spanid).html('Error Generated.');
            }
        }
    });
}

window.setInterval(function() {
    AutoSaveMyForm('SpanIdToShowResult')
}, 60000); // 1 min

By using set interval method we can call javascript method which call ajax to save form and pass any span id to get result back

You can use a SignalR hub to communicate dynamically between your page and the server. See https://github.com/SignalR/SignalR/wiki and http://signalr.net/ for details of this technology.

That way, you can send change events directly to the server. You can throttle them using a producer-consumer model in JavaScript, but SignalR's performance is good enough that you should be able to get away without having to do this.

You can embed a table inside a form, but again, SignalR uses a different means of client-to-server communication.

Best of luck.

Partial answer for your Question 1 only : Yes, right out of the box, mvc 4 is going to work great with javascript (jquery) and ajax

The answers above show you some of the ways that you will write javascript /ajax in your razor views, then you will be communicating to a controller (which should get data from a "model" ) then part of the whole .net mvc framework experience is tied in with various settings, web.config you can then test when your change values to false

Example

in your web.config, you will see

<appSettings>
    <add key="webpages:Version" value="2.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="PreserveLoginUrl" value="true" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

MVC 3 even had this working very well:

<appSettings>
    <add key="webpages:Version" value="1.0.0.0" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top