4

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

3 Answers 3

7

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.

Sign up to request clarification or add additional context in comments.

10 Comments

Hi - I'm struggling with the controller - would you be able to help? My model is: 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; } }
My Controller, where I'm stuck is: [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); }
where is multiple items coming here ?
I do not see an collection in your model
Hi - I added the code above to my original post. Using Fiddler, I can see the post back to the server when I click update, and it is passing back (in the post) the updates to the multiple objectives listed - I just can't figure out how to loop through the returned object, to save each one to the database (I'm not sure what a collection is, or if it's required, given the data is being posted back)?? Thank you again, Mark
|
1

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

Comments

0

Take a look in EditorTemplates

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.