views:

92

answers:

3

I have a bunch of text inputs on my page (HTML.TEXTBOX, generated through for loop), and I want to read their values and commit to database only when user has modified something in those textboxes.

What would be a proper way to do that? (Do you think it may make more sense to commit the entire thing to database if number of textboxes is less than 100?)

Also, in general, how would I read values from a bunch on textboxes and commit to the database? I would need something that uses a key-value pair, where key would be the id and value would be that input in the textbox.

A: 

Unless you use for example JavaScript and hidden fields to keep track of user changes, there is no way for you to know which fields have been modified without querying the database, since the web in general, and ASP.NET MVC in particular, is stateless. However, if you loop out the fields with their values filled in with data stored in an object, you can probably save that object in a session variable to compare against on the next request.

Pseudo-example:

public ActionResult GetFormView() 
{
     var values = (select relevant information from db and store in a 
                   IQueryable<Dictionary<string, string>> or something similar
                   where you have a relation between input field id/name and value);

     Session["TheInputListValues"] = values;

     return View(values);    // Your view renders your list of input fields
}


[AcceptVerbs(HttpVerbs.Post)]
public ActionResult SaveChanges(FormCollection form)
{
    var oldValues = (Dictionary<string, string>)Session["TheInputListValues"];
    var changedValues = new Dictionary<string, string>();

    foreach(string key in form.AllKeys)
    {
        if(oldValues.ContainsKey(key))
        {
            if (oldValues[key] != form[key])
            {
                changedValues(key, form[key]);
            }
        }
    }

    SaveToDB(changedValues);

    return Redirect("SomeWhereElse"); // PRG is king!
}

I haven't tested this implementation, but it's worth a try =)

Tomas Lycken
A: 

Your reply helped me, but I have another question.

I have a set of overloads for the edit function, one that renders the textboxes and the another one that commits it to the database.

public ActionResult Edit()
{
    //render textboxes
    return View(); 
}

[ActionName("Edit"), AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(FormCollection fc)
{
     //commit to the database
     return View(); 
}

Now I have the following code in my edit page. However, it is hitting the first method instead of the second one. How do I make it hit the second one? I thought if I would pass formcollection, it would hit the second?

Html.ActionLink("Save", "Edit", new FormCollection())
ActionLink's dont POST forms if I recall.
mxmissile
A: 

I have done something similar using jQuery and it works pretty well. Attach a behavior to the textboxes where if the data changes then submit it's value to an action that saves the data.

$(function(){
  $("input[type='text']").change(function(){
    $.post("/SaveChanges",{id: $(this).attr("id"),value : $(this).attr("text")}); 
  });
});

This would be assuming you had ID's that were some sort of unique key to you record on each input.

<input id="4576" name="4576"/>

you could also have a callback that would say add a class to this field letting them know that the information was saved by changing it to green or something.

Check this out for more details: http://docs.jquery.com/Ajax/jQuery.post

Slee
this is not tested and I just wrote it quickly off the top of my head
Slee