Mark
Mark

Reputation: 7818

asp.net mvc update multiple records

is it possible to have a view for editing multiple records, in the same way that the index.cshtml view loops through records to display them (as below)?

@foreach (var item in Model) {
<tr>
    <td>
        @Html.DisplayFor(modelItem => item.tvid)
    </td>

So for each row above, it would relate to a different row in the database.

Does anyone know of any examples showing how this may be achieved?

Thanks for any pointers,

Mark

UPDATE

Model:

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Web;

namespace MvcObjectives.Models
{
public class objectives
{
    public int ID { get; set; }
    public int tvid { get; set; }
    public string tlnt { get; set; }
    public DateTime month { get; set; }

    public string objective  { get; set; }
    public int score { get; set; }
    public int possscore { get; set; }
    public string comments { get; set; }
 }

}

Controller:

 [HttpPost]
    public ActionResult Edit(objectives objectives)
    {
        if (ModelState.IsValid)
        {
            db.Entry(objectives).State = EntityState.Modified;
            foreach (objective Objective in objectives.objective)

            { }

            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(objectives);
    }

I'm stick with the controller, if anyone can offer any assistance?

Thanks again,

Mark

2nd Update

The GET Controller to send the records to the view is:

        // GET: /Objective/Edit/
        public ActionResult Edit()
        {
            return View(db.objectives.ToList());
        }

The POST controller (where the values are posted back from the view) is:

        // POST: /Objective/Edit/
        [HttpPost]
        public ActionResult Edit(List<objectives> objectives)
        {
            if (ModelState.IsValid)
            {
         // the next part is where I am stuck - how to loop through the returned objectives, and update the records in the database
                db.Entry(objectives).State = EntityState.Modified;
                foreach (objectives obj in objectives)
                {
                    var tempObj = (from objv in db.objectives
                                   where objv.ID==obj.ID
                                   select objv).First();
              }

              //  to do - how to save the updates sent back????

                return RedirectToAction("Index");
            }
            return View(objectives);
        }

Upvotes: 4

Views: 10917

Answers (3)

Shyju
Shyju

Reputation: 218942

Use an Editor template

Assuming your ViewModel/Model looks like this

public class UserViewModel 
{
  public int UserId { set;get;}
  public string Name { set;get;}   
  public IEnumerable<Address> Addresses { set;get;}

  public UserViewModel()
  {
     if(this.Addresses==null)
         this.Addresses=new List<Address>();
  }
}
public class Address
{
  public int AddressID { set;get;}
  public string AddressLine1 { set;get;}
}

Now create an editor template called addresses.cshtml with below content.

@model YourNameSpace.Address
@Html.TextBoxFor(x => x.AddressLine1)

In your main view, you can call this like

@model UserViewModel 
@using (Html.BeginForm())
{
  //other elements
 @Html.EditorFor(m=>m.Addresses)
 <input type="submit" value="Save" />
}

Now you will get the data in your HttpPost Ation method

[HttpPost]
public ActionResult Save(UserViewModel model)
{  
   foreach (Address address in model.Addresses)
   {
      //now check for address.AddressLine here
   } 
}

EDIT : Based on the user's comment and updation on the question.

(Request to the OP : Next time when you post a question, include all the relevant details to the question in the first time itself.)

Create a ViewModel to wrap your List of Objective class.

public class ObjectivesEdit
{
    public IEnumerable<Objective> Objectives { set; get; }
    public ObjectivesEdit()
    {
        if (Objectives == null)
            Objectives = new List<Objective>();
    }
}

And in your GET Action method send this Wrapper View model to the View with values filled

  public ActionResult Edit()
  {
     ObjectivesEdit objEdit = new ObjectivesEdit();
     List<Objective> objList = new List<Objective>();
       // you can replace this manual filling with data from database
     objList.Add(new Objective { ID = 1, score = 65 });
     objList.Add(new Objective { ID = 2, score = 43 });
     objList.Add(new Objective { ID = 3, score = 78 });
     objEdit.Objectives = objList;
     return View(objEdit);
  }

Your Editor template should look like this. It should be named objective.cshtml

@model EditorTemplateDemo.Models.Objective           
<p>
Score for @Model.ID is  @Html.TextBoxFor(x => x.score)
@Html.HiddenFor(x => x.ID)
</p>

And your main View

@model EditorTemplateDemo.Models.ObjectivesEdit
@using (Html.BeginForm())
{
  @Html.EditorFor(x=>x.Objectives)
  <input type="submit" value="Save" />    
}

And finally your HTTPPOST action method will look like this

    [HttpPost]
    public ActionResult Edit(ObjectivesEdit model)
    {
        if (model.Objectives != null)
        {
            // Put a break point here and you will see the posted data
            foreach (var item in model.Objectives)
            {
                 context.Entry(item).State = EntityState.Modified;
            }
            //Save and redirect  
            context.SaveChanges();
            return RedirectToAction("Index");     
        }
        return View(model);
    }

This should work. Tested.

To avoid further questions, I am sharing a working sample of the above code here. Please use visual studio breakpoints int he code to see what value is being posted.

Upvotes: 7

VJAI
VJAI

Reputation: 32768

Suppose you have a model called Person.. and you want to edit a bunch of persons in a View and post them to an action.

public ViewResult Edit()
{
    return View(list of persons to edit);
}

public ViewResult Edit(List<Person> persons)
{
    // save to db?
}

Now to create a view that displays say multiple persons to edit.

Edit.cshtml

@model List<Person>

@for (int i = 0; i < Model.Count; i++) {
   <h4>Person Number: @i</h4>
   @:First Name: @Html.EditorFor(m => m[i].FirstName)
   @:Last Name: @Html.EditorFor(m => m[i].LastName)
}

Upvotes: 1

Hadas
Hadas

Reputation: 10384

Take a look in EditorTemplates

Upvotes: 0

Related Questions