I want to add students to the Attendance Table through the Class_Schedule controller. To do this I created an public ActionResult:
public ActionResult Register(int? id)
{
if (id == null)
{
return RedirectToAction("Index");
}
Class_Schedule class_Schedule = db.Class_Schedule.Find(id);
if (class_Schedule == null)
{
return RedirectToAction("Index");
}
//This is the collects the class_schedule ID to make the attendance specific for each class ViewBag.CSid = id;
ViewBag.studentID = new SelectList(db.Students, "StudentID", "Full_Name");
ViewBag.instructorID = new SelectList(db.Instructors, "InstructorID", "Name");
var attendances = db.Attendances;
return View(attendances.ToList());
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Register([Bind(Include = "AttendanceID,csID,InstructorID,StudentID")] Attendance attendance)
{
try
{
if (ModelState.IsValid)
{
db.Attendances.Add(attendance);
db.SaveChanges();
//ViewBag.msg = "Instructor Added";
return RedirectToAction("Register");
}
return View(attendance);
}
catch
{
return View(attendance);
}
}
This is my view:
#model IEnumerable<BBM.Models.Attendance>
#{
ViewBag.Title = "Register";
}
<h2>Class Schedule #ViewBag.CSid</h2>
#using (Html.BeginForm("Register","Class_Schedule", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-group">
#{
var studentid = Model.Select(model => model.StudentID.ToString());
}
#Html.Label("StudentID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("StudentID", null, htmlAttributes: new { #class = "form-control" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
<h4>Student register</h4>
<table class="table">
<tr>
<th>
Attendance ID
</th>
<th>
Student ID
</th>
<th>
Student Name
</th>
<th>
Expiry Date
</th>
</tr>
#if (Model != null)
{
foreach (var item in Model.Where(p => p.csID.Equals(ViewBag.csID)))
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.AttendanceID)
</td>
<td>
#Html.DisplayFor(modelItem => item.StudentID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Student.Full_Name)
</td>
<td>
#if (item.Student.Payments != null && item.Student.Payments.Any(p => p.Expires > DateTime.Now))
{
#Html.DisplayFor(modelItem => item.Student.Payments.OrderByDescending(p => p.paymentID).First(p => p.Expires > DateTime.Now).Expires)
}
else
{
#Html.DisplayName("Expired");
}
</td>
</tr>
}
}
</table>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
This view has a select list to select the students you want to add but but the student ID isn't going into the parameter and the postMethod isn't happening
The ones that are already in there are for test purposes and i did them through the sql server
You have only a specified drop-down id and html attribute. you forgot to pass data to the drop-down helper as you fill in the ViewBag. Update as below for student
#Html.DropDownList("StudentID",htmlAttributes:new { #class = "control-label col-md-2" },selectList:new SelectList(ViewBag.studentID))
Please check that you getting studentId on the post method.
Related
I am quite new to ASP.NET and MVC and I'm currently trying the following:
Model: Properties of the form
View: Display a form to the user
Controller:
Action: Do something
Go back to initial view and display values to user
With normal html I got this to work. With razor syntax I so far did not manage to re-display the values after the form was submitted.
My model:
namespace MyModels
{
public class SubmitTicketFormModel
{
[DisplayName("First Name")]
public string _firstName { get; set; }
[DisplayName("Last Name")]
public string _lastName { get; set; }
}
}
My View:
#model MyModels.SubmitTicketFormModel
#{
ViewData["Title"] = "SubmitTicketView";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Request</h1>
#using (Html.BeginForm("SubmitTicketAction", "SubmitTicketContoller", FormMethod.Post))
{
<div class="form-group">
#Html.LabelFor(model => model._firstName)
#Html.TextBoxFor(model => model._firstName, new { #class = "form-control" })
#Html.LabelFor(model => model._lastName)
#Html.TextBoxFor(model => model._lastName, new { #class = "form-control" })
</div>
<input type="submit" value="Post comment" />
}
<table class="table table-bordered table-sm">
<thead class="thead-light">
<tr>
<th>col1</th>
<th>col2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
#Model._firstName
</td>
<td>
#Model._lastName
</td>
</tr>
</tbody>
</table>
Controller:
public class SubmitTicketController : Controller
{
public ActionResult SubmitTicketView()
{
var TicketInstance = new SubmitTicketFormModel();
return View(TicketInstance);
}
[HttpPost]
public ActionResult SubmitTicketAction(SubmitTicketFormModel model)
{
var NewTicketInstance = new SubmitTicketFormModel()
{
_firstName = model._firstName,
_lastName = model._lastName
};
return View(NewTicketInstance);
}
}
}
Can you please guide me in the right direction?
If you want the same View to render after the user clicks on submit button, then I guess you don't want that #using (Html.BeginForm("SubmitTicketAction", "SubmitTicketContoller", FormMethod.Post)) in the UI to show up again. Only the values of first name and last name in your view of which you've written your logic down in your view.
In that case, you can just pass a ViewBag in your view from controller which will help your View understand whether it has to show the input form or display user's entered data.
[HttpPost]
public ActionResult SubmitTicketAction(SubmitTicketFormModel model)
{
var NewTicketInstance = new SubmitTicketFormModel()
{
_firstName = model._firstName,
_lastName = model._lastName
};
ViewBag.Check = "true";
return View(ViewName , modelname);
}
And then in your view,
#model MyModels.SubmitTicketFormModel
#{
ViewData["Title"] = "SubmitTicketView";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#if(ViewBag.Check != null)
{
<h1>Request</h1>
#using (Html.BeginForm("SubmitTicketAction", "SubmitTicketContoller", FormMethod.Post))
{
<div class="form-group">
#Html.LabelFor(model => model._firstName)
#Html.TextBoxFor(model => model._firstName, new { #class = "form-control" })
#Html.LabelFor(model => model._lastName)
#Html.TextBoxFor(model => model._lastName, new { #class = "form-control" })
</div>
<input type="submit" value="Post comment" />
}
}
else
{
<table class="table table-bordered table-sm">
<thead class="thead-light">
<tr>
<th>col1</th>
<th>col2</th>
</tr>
</thead>
<tbody>
<tr>
<td>
#Model._firstName
</td>
<td>
#Model._lastName
</td>
</tr>
</tbody>
</table>
}
I have recently learning ASP.NET MVC5.
I am trying to see both the form and a table(return as partialview) in one view but i'm getting this error.
System.NullReferenceException: Object reference does not set to an instance of an object.
Here is my Model:
public class Prescription
{
[Key]
public int PrescriptionID { get; set; }
[ForeignKey("Assessment")]
public int? AssessmentID { get; set; }
public Assessment Assessment { get; set; }
[ForeignKey("Medicine")]
[Display(Name ="Prescription")]
public int? MedcineID { get; set; }
public Medicine Medicine { get; set; }
}
My main view where I want to put my partial view:
#using ClinicManagemet
#model ClinicManagemet.Models.Prescription
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Prescription</h4>
<hr />
<div class="form-group">
#Html.LabelFor(model => model.MedcineID, "MedcineID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("MedcineID", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.MedcineID, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
#Html.Action("ViewPrescription","Assessments")
<div>
#Html.ActionLink("Back to Home", "Home")
</div>
My partial view:
#model IEnumerable<ClinicManagemet.Models.Prescription>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Assessment.Complaint)
</th>
<th>
#Html.DisplayNameFor(model => model.Medicine.MedicineName)
</th>
<th></th>
</tr>
#foreach (var item in Model) { //Here is the line where I get the error
<tr>
<td>
#Html.DisplayFor(modelItem => item.Assessment.Complaint)
</td>
<td>
#Html.DisplayFor(modelItem => item.Medicine.MedicineName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.PrescriptionID }) |
#Html.ActionLink("Details", "Details", new { id=item.PrescriptionID }) |
#Html.ActionLink("Delete", "Delete", new { id=item.PrescriptionID })
</td>
</tr>
}
</table>
My partial view's controller:
public ActionResult ViewPrescription()
{
return PartialView();
}
Edit: If I fix this, I'll try to add Ajax so whenever I insert something, it will just refresh the partial view.
Load your partial view like this,
#{
Html.RenderAction("ViewPrescription","YourControllerName")
}
And in your ViewPrescription method, return the data,
{
//Fetch the data here
return PartialView(model);
}
Hope it helps.
You're not passing a model into the partial view when returning the view.
public ActionResult ViewPrescription()
{
ClinicManagemet.Models.Prescription model = _service.GetPerscription();
return PartialView(model);
}
I am writing a web page with MVC and Entity Framework.
I have an order with line items attached and want to return a complex object to the controller for processing.
I have now included all the code.
My view:
#model BCMManci.ViewModels.OrderCreateGroup
#{
ViewBag.Title = "Create";
}
<h2>New Order</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h4>#Html.DisplayFor(model => model.Order.Customer.FullName)</h4>
<table>
<tr>
<td><b>Order Date:</b> #Html.DisplayFor(model => model.Order.OrderDate)</td>
<td><b>Status:</b> #Html.DisplayFor(model => model.Order.OrderStatus.OrderStatusName)</td>
</tr>
<tr>
<td colspan="2">
<b>Notes</b>
#Html.EditorFor(model => model.Order.Notes, new { htmlAttributes = new { #class = "form-control" } })
</td>
</tr>
</table>
#Html.ValidationMessageFor(model => model.Order.Notes, "", new { #class = "text-danger" })
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<table class="table table-striped table-hover">
<thead>
<tr>
<td>Name</td>
<td>Price</td>
<td>Discount</td>
<td>Total</td>
<td>Quantity</td>
</tr>
</thead>
<tbody>
#foreach (var product in Model.ProductWithPrices)
{
<tr>
<td>
#Html.DisplayFor(modelItem => product.ProductName)
</td>
<td>
#Html.DisplayFor(modelItem => product.SellingPrice)
</td>
<td>
#Html.DisplayFor(modelItem => product.DiscountPrice)
</td>
<td>
#Html.DisplayFor(modelItem => product.TotalPrice)
</td>
<td>
#Html.EditorFor(modelItem => product.Quantity, new { htmlAttributes = new { #class = "form-control" } })
</td>
</tr>
}
</tbody>
</table>
<input type="submit" value="Create" class="btn btn-default" />
}
<div class="btn btn-danger">
#Html.ActionLink("Cancel", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Order,ProductWithPrices,Order.Note,product.Quantity")] OrderCreateGroup order)
{
try
{
if (ModelState.IsValid)
{
db.Orders.Add(order.Order);
foreach (var orderItem in order.ProductWithPrices.Select(item => new OrderItem
{
OrderId = order.Order.OrderId,
ProductId = item.ProductId,
Quantity = item.Quantity,
ItemPrice = item.SellingPrice,
ItemDiscount = item.DiscountPrice,
ItemTotal = item.TotalPrice
}))
{
db.OrderItems.Add(orderItem);
}
db.SaveChanges();
return RedirectToAction("ConfirmOrder", new {id = order.Order.OrderId});
}
}
catch (DataException /* dex */)
{
//TODO: Log the error (uncomment dex variable name and add a line here to write a log.
ModelState.AddModelError("", "Unable to save changes. Try again, and if the problem persists see your system administrator.");
}
ViewBag.Products = db.Products.Where(model => model.IsActive == true);
PopulateDropdownLists();
return View(order);
}
Data Source:
public class OrderCreateGroup
{
public OrderCreateGroup()
{
ProductWithPrices = new List<ProductWithPrice>();
}
public Order Order { get; set; }
public ICollection<ProductWithPrice> ProductWithPrices { get; set; }
}
public class ProductWithPrice : Product
{
public decimal SellingPrice { get; set; }
public decimal DiscountPrice { get; set; }
public int Quantity { get; set; }
public decimal TotalPrice { get; set; }
}
However, the values that are entered on the form are not being passed, through. So I can't access them in the controller. The 'productWithPrices' collection is null although there is Data in it on the web page.
I have tried making it asyc and also tried changing the ActionLink button like below but it didn't get to the controller.
#Html.ActionLink("Create", "Create", "Orders", new { orderCreateGoup = Model }, null)
This is the controller but it now doesn't make sense as the parameter passed in the datasource for the page.
public ActionResult Create(OrderCreateGroup orderCreateGoup)
Please, can you give me direction on the best way of doing this?
In your OrderCreateGroup class initialize the collection to an empty list.
public class OrderCreateGroup
{
public OrderCreateGroup()
{
ProductWithPrices = new List<ProductWithPrice>();
}
public Order Order { get; set; }
public ICollection<ProductWithPrice> ProductWithPrices { get; set; }
}
You'll need to add #Html.HiddenFor(m => m.SellingPrice) and similarly for other bound fields that are using DisplayFor if you want to post them back to the controller.
Note: For your benefit, try to have a look at the generated HTML code when your page is rendered in the browser and see what tags are generated inside the <form> tag with a name attribute.
make sure you bind the appropriate property from the complex object, like the following:
#model BCMManci.ViewModels.OrderCreateGroup
...
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
...
<div class="form-group">
#Html.LabelFor(model => model.LastName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.OrderCreateGroup.Order.Quantity, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.OrderCreateGroup.Order.Quantity, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
Note:model.OrderCreateGroup.Order.Quantity would be one the your order's property.
hope this helps.
I have been working on this and have been searching for hours and still can not figure out a solution.
I am trying to display the ItemNames of the checked checkboxes from my AsoociateMenuItems view to my Index view. Would appreciate any help I can get.
MenuItemViewModel:
public class MenuItemViewModel
{
public int MenuId { get; set; }
public double ItemPrice { get; set; }
public string ItemName { get; set; }
public bool Selected { get; set; }
public virtual ICollection<IngredientViewModel> Ingredients { get; set;}
}
OrderViewModel:
public class OrderViewModel
{
public int OrderId { get; set; }
public int TableNum { get; set; }
public string Notes { get; set; }
public double Discount { get; set; }
public virtual ICollection<MenuItemViewModel> MenuItem { get; set; }
}
Index:
#model IEnumerable<Final_POS.Models.Order>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Employee.EmpName)
</th>
<th>
#Html.DisplayNameFor(model => model.TableNum)
</th>
<th>
+
#Html.DisplayNameFor(model => model.Discount)
</th>
<th>
#Html.DisplayNameFor(model => model.MenuItems)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Employee.EmpName)
</td>
<td>
#Html.DisplayFor(modelItem => item.TableNum)
</td>
<td>
#Html.DisplayFor(modelItem => item.Discount)
</td>
<td>
#Html.EditorFor(modelItem => item.MenuItems)
</td>
<td>
#Html.ActionLink("Edit", "AsoociateMenuItems", new { id=item.OrderId }) |
#Html.ActionLink("Details", "Details", new { id=item.OrderId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.OrderId })
</td>
</tr>
}
</table>
AsoociateMenuItems:
-this is a replacement for my edit view
#model Final_POS.Models.ViewModel.OrderViewModel
#{
ViewBag.Title = "AsoociateMenuItems";
}
<h2>AsoociateMenuItems</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>OrderViewModel</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.OrderId, new { htmlAttributes = new { #class = "form-control" } })
<div class="form-group">
#Html.LabelFor(model => model.TableNum, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.TableNum, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.TableNum, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.HiddenFor(model => model.Notes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.HiddenFor(model => model.Notes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Notes, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Discount, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Discount, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Discount, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EmployeeEmpId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EmployeeEmpId, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EmployeeEmpId, "", new { #class = "text-danger" })
</div>
</div>
#Html.EditorFor(model => model.MenuItem)
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
This next code snippet is being used by my AsoociateMenuItems in this line #Html.EditorFor(model => model.MenuItem)
MenuItemViewModel: (View)
#model Final_POS.Models.ViewModel.MenuItemViewModel
<fieldset>
#Html.HiddenFor(model => model.MenuId)
#Html.CheckBoxFor(model => model.Selected)
#Html.DisplayFor(model => model.ItemName)
#Html.DisplayFor(model => model.ItemPrice)
</fieldset>
Controller:
public class OrdersController : Controller
{
private POSContext db = new POSContext();
// GET: Orders
public ActionResult Index()
{
var orders = db.Orders.Include(o => o.Employee);
return View(orders.ToList());
}
// GET: Orders/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Order order = db.Orders.Find(id);
if (order == null)
{
return HttpNotFound();
}
return View(order);
}
// GET: Orders/Create
public ActionResult Create()
{
ViewBag.EmployeeEmpId = new SelectList(db.Employees, "EmpId", "EmpName");
return View();
}
// POST: Orders/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "OrderId,TableNum,Discount,EmployeeEmpId")] Order order)
{
if (ModelState.IsValid)
{
db.Orders.Add(order);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.EmployeeEmpId = new SelectList(db.Employees, "EmpId", "EmpName", order.EmployeeEmpId);
return View(order);
}
// GET: Orders/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Order order = db.Orders.Find(id);
if (order == null)
{
return HttpNotFound();
}
ViewBag.EmployeeEmpId = new SelectList(db.Employees, "EmpId", "EmpName", order.EmployeeEmpId);
return View(order);
}
// POST: Orders/Edit/5
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "OrderId,TableNum,Discount,EmployeeEmpId")] Order order)
{
if (ModelState.IsValid)
{
db.Entry(order).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.EmployeeEmpId = new SelectList(db.Employees, "EmpId", "EmpName", order.EmployeeEmpId);
return View(order);
}
// GET: Orders/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Order order = db.Orders.Find(id);
if (order == null)
{
return HttpNotFound();
}
return View(order);
}
// POST: Orders/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
Order order = db.Orders.Find(id);
db.Orders.Remove(order);
db.SaveChanges();
return RedirectToAction("Index");
}
public ActionResult AsoociateMenuItems(int? id)
{
Order _order = db.Orders.Find(id);
if (_order == null)
{
return HttpNotFound();
}
OrderViewModel _orderViewModel = new OrderViewModel()
{
OrderId = _order.OrderId,
Discount = _order.Discount,
TableNum = _order.TableNum,
EmployeeEmpId = _order.EmployeeEmpId
};
List<MenuItemViewModel> _menuItemViewModel = new List<MenuItemViewModel>();
foreach (MenuItem menuItem in db.MenuItems)
{
_menuItemViewModel.Add(new MenuItemViewModel()
{
MenuId = menuItem.MenuId,
ItemName = menuItem.ItemName,
ItemPrice = menuItem.ItemPrice,
Selected = _order.MenuItems.Contains(menuItem)
});
}
_orderViewModel.MenuItem = _menuItemViewModel;
return View(_orderViewModel);
}
[HttpPost]
public ActionResult AsoociateMenuItems(OrderViewModel _orderViewModel)
{
Order _order = db.Orders.Find(_orderViewModel.OrderId);
_order.MenuItems.Clear();
foreach (MenuItemViewModel _menuItemViewModel in _orderViewModel.MenuItem)
{
if (_menuItemViewModel.Selected)
{
MenuItem _menuItem = db.MenuItems.Find(_menuItemViewModel.MenuId);
_order.MenuItems.Add(_menuItem);
}
}
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
}
}
Let's start.
Your question is really hard for understanding. BUT I hope that I understood.
At first, you should use model in all views. It is really important. You MUST do it. The easiest way - just extend you OrderViewModel with EmpName
public class OrderViewModel
{
public int OrderId { get; set; }
public int TableNum { get; set; }
public string Notes { get; set; }
public double Discount { get; set; }
public string EmpName { get; set; }
public virtual ICollection<MenuItemViewModel> MenuItems { get; set; } //renamed to plural
}
Than change your Index View
#model IEnumerable<OrderViewModel>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.EmpName)
</th>
<th>
#Html.DisplayNameFor(model => model.TableNum)
</th>
<th>
#Html.DisplayNameFor(model => model.Discount)
</th>
<th>
#Html.DisplayNameFor(model => model.MenuItems)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.EmpName)
</td>
<td>
#Html.DisplayFor(modelItem => item.TableNum)
</td>
<td>
#Html.DisplayFor(modelItem => item.Discount)
</td>
<td>
#Html.EditorFor(modelItem => item.MenuItems)
</td>
<td>
#Html.ActionLink("Edit", "AsoociateMenuItems", new { id=item.OrderId }) |
#Html.ActionLink("Details", "Details", new { id=item.OrderId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.OrderId })
</td>
</tr>
}
</table>
Than change the controller method Index (Just get menuitems from db also)
// GET: Orders
public ActionResult Index()
{
var orders = db.Orders.Include(o => o.Employee).Include(o => o.MenuItems);
var orderModels = new List<OrderViewModel>();
foreach(var _order in orders)
{
OrderViewModel _orderViewModel = new OrderViewModel()
{
OrderId = _order.OrderId,
Discount = _order.Discount,
TableNum = _order.TableNum,
EmpName = _order.Employee.EmpName
};
List<MenuItemViewModel> _menuItemViewModels = new List<MenuItemViewModel>();
foreach (MenuItem menuItem in order.MenuItems)
{
if(_order.MenuItems.Contains(menuItem)) //where selected is true
{
_menuItemViewModel.Add(new MenuItemViewModel()
{
MenuId = menuItem.MenuId,
ItemName = menuItem.ItemName,
ItemPrice = menuItem.ItemPrice,
});
}
}
_orderViewModel.MenuItems = _menuItemViewModels;
orderModels.Add(_orderViewModel);
}
return View(orderModels);
}
I hope you will understand what I meant. And sure, my code need code refactoring, but you can do it by yourself.
I want to call my StudentName depending of Id selected that I use in selectlist to use in a bootstrap alert after post action, but I can not get it.
ViewModel:
public class StudentsViewModel
{
public String StudentName { get; set; }//ForeignKey
public int StudentId { get; set; }//ForeignKey
public int SelectedStudent { get; set; }
public IEnumerable<SelectListItem> Student{ get; set; }
}
}
Get Controller:
public ActionResult Create(Students model)
{
var student= db.StudentsList.Select(x => x.StudentName).ToList();
var vm = new StudentsViewModel
{
Student= new SelectList(db.StudentList, "StudentId", "StudentName"),
StudentName = student.ToString()
};
POST CONTROLLER:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(StudentsViewModel model)
{
var student =
db.StudentsList.Where(x => x.StudentId == model.SelectedStudent)
.Select(x => x.StudentName)
.FirstOrDefault();
try
{
if (ModelState.IsValid)
{
var student=
db.StudentsList.Where(x => x.StudentId == model.SelectedStudent)
.Select(x => x.StudentName)
.FirstOrDefault();
var studs= new Students
{
StudentId = model.SelectedStudent,
StudentName = student
};
db.StudentsList.Add(studs);
db.SaveChanges();
Success(string.Format("Register of" + student + "has been created"),true);
return RedirectToAction("Index", "Students");
}
}
catch (Exception)
{
Danger(string.Format("Cannot create your register"), true);
}
return View(model);
}
Index Students View(Where I want to display my bootstrap alert)
#model IEnumerable<xxx.Models.Student>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Student.StudentName)
</th>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Student.StudentName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.StudentId }) |
#Html.ActionLink("Details", "Details", new { id=item.StudentId }) |
#Html.ActionLink("Delete", "Delete", new { id=item.StudentId })
</td>
</tr>
}
</table>
Create View:
#model xxx.Models.ViewModels.StudentViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Students</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-10">
#Html.DropDownListFor(m => m.SelectedStudent, Model.Student, "-Select an option-", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SelectedStudent)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
So my consult is
var student= db.StudentsList.Where(x => x.StudentId == model.SelectedStudent).Select(x => x.StudentName).FirstOrDefault();
But in my call StudentName = student I put a breakpoint and always come null.
Thankyou in advance