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);
}
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.
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)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With