I'm using:
#model IEnumerable<SomeModel1>
in my view. I cannot change that because multiple controllers in our application are returning some variable with the type:
List<SomeModel1>
I also need to pass the same model (SomeModel1) without the IEnumerable for a modal window:
#model WebApplication8.Models.ManageUserViewModel
Is there a way that I can achieve that without putting the models into a parent model?
UPDATE:
View Page:
<div class="container">
<div class="row clearfix">
<div class="col-md-12 column">
<table class="table table-bordered table-hover" id="tab_logic">
<thead>
<tr>
<th class="text-center">
Active
</th>
<th class="text-center">
Email Address
</th>
<th class="text-center">
First name
</th>
<th class="text-center">
Last Name
</th>
<th class="text-center">
Company
</th>
<th class="text-center">
permissions
</th>
<th class="text-center">
Machine<p>Limit</p>
</th>
<th class="text-center">
Machines<p>Consumed</p>
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td style="display:none" >#Html.DisplayFor(model => item.UserId)</td>
<td align="center">
<div class="btn-group btn-toggle">
#if (item.ActiveUser)
{
<button class="btn btn-sm btn-success active">ON</button>
<button class="btn btn-sm btn" onclick="DeActivateUser('#item.UserId')">OFF</button>
}
else
{
<button class="btn btn-sm btn" onclick="ActivateUser('#item.UserId')">ON</button>
<button class="btn btn-sm btn-success active">OFF</button>
}
</div>
</td>
<td>#Html.DisplayFor(model => item.EmailAddress)</td>
<td>#Html.DisplayFor(model => item.FirstName)</td>
<td>#Html.DisplayFor(model => item.LastName)</td>
<td>#Html.DisplayFor(model => item.Company)</td>
<td>
#Html.DisplayFor(model => item.UserPermission)
<b class="dropdown-menu"></b>
<ul class="dropdown-menu">
<li><a onclick="ChangePermission('#item.UserId', '3')">View Only</a></li>
<li><a onclick="ChangePermission('#item.UserId', '4')">View - Print</a></li>
<li><a onclick="ChangePermission('#item.UserId', '5')">View - One Print</a></li>
<li><a onclick="ChangePermission('#item.UserId', '6')">Expire by Use - 5 Opens</a></li>
<li><a onclick="ChangePermission('#item.UserId', '7')">Expire After 5 Days</a></li>
</ul>
</td>
<td align="center">#Html.DisplayFor(model => item.MachineLimit)</td>
<td align="center">#Html.DisplayFor(model => item.MachineCount)</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
<section id="addUser">
#using (Html.BeginForm("Manage", "Account", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))
{
#Html.AntiForgeryToken()
<h2>Add Authorized User(s): </h2>
<hr style="height:7pt;" />
<!-- <hr style="height:0pt; visibility:hidden;" /> -->
<button class="btn btn-default btn-success btn-lg" data-target="#modalId" data-toggle="modal" type="button">
<span class="glyphicon glyphicon-plus"></span> ADD NEW USER
</button>
<div class="modal fade" id="modalId" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Add Authorized User(s)</h4>
</div>
<div class="modal-body">
#Html.ValidationSummary()
<!-- <div class="col-md-4"> -->
<div class="form-group">
#Html.LabelFor(m => m. ().FirstName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.FirstOrDefault().FirstName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.FirstOrDefault().LastName, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.FirstOrDefault().LastName, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.FirstOrDefault().EmailAddress, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.FirstOrDefault().EmailAddress, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.FirstOrDefault().Company, new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.FirstOrDefault().Company, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.FirstOrDefault().UserPermission, new { #class = "col-md-2 control-label" })
<div class="col-md-3 control-label">
#Html.DropDownListFor(m => m.FirstOrDefault().UserPermission, new SelectList(new List<Object>
{
new { value = "2" , text = "View Only"},
new { value = "3" , text = "View - Print" },
new { value = "4" , text = "View - One Print" },
new { value = "5" , text = "Expire by 5 Use" },
new { value = "6" , text = "Expire by 5 Date" }
},
"value", "text", "ViewOnly"))
</div>
#Html.LabelFor(m => m.FirstOrDefault().MachineLimit, new { #class = "col-md-2 control-label" })
<div class="col-md-2 control-label">
#Html.DropDownListFor(m => m.FirstOrDefault().MachineLimit, new SelectList(new List<Object>
{
new { value = "1" , text = "1"},
new { value = "2" , text = "2" },
new { value = "3" , text = "3" },
new { value = "4" , text = "4" },
new { value = "5" , text = "5" }
},
"value", "text", 1))
</div>
</div>
</div>
<div class="modal-footer">
<div class="col-md-3 col-md-10 control-label">
<input type="submit" class="btn btn-default" value="Select/Add" name="Action:Insert" />
</div>
</div>
</div>
</div>
</div>
}
</section>
Passing multiple types into a single view is not really recommended and probably means you are misusing the view in some way. You have 3 options:
Distinct Views
Change what you are doing and make a view for each type.
dynamic Type
Use dynamic as your model type, but this means your view code is littered with if statements - not a good design.
Wrap in a List
Wrap the SomeModel object in a List like this:
SomeModel myModel;
return View(new List<SomeModel> { myModel };
In the case where you have to use SomeModel1,
you can use #Model.firstordefault().{class properties} by keeping IEnumerable declaration above.
Use ViewBag.
// controller
ViewBag.SomeModel = someModel;
// view
#ViewBag.SomeModel.SomeProperty
Related
In my razor view, in the "Panel area - to hold the comment button", I am trying to referencing the view models property BlogPublishedByBlogId.BlogId but I get - "the name BlogPublishedByBlogId does not exist in the current context".
However, I am able to reference the other properties fine using Lamda: model => model.BlogPublishedByBlogId.CreatedDateTime
How do I reference the 'blogId' in the "Panel area - to hold the comment button" area?
#model GbngWebClient.Models.BlogPublishedByBlogIdVM
<h2 class="page-header"><span class="blogtitle">#Session["BlogTitle"]</span></h2>
#{
Layout = "~/Views/Shared/_LayoutUser.cshtml";
}
#if (Model != null)
{
<div class="panel panel-default toppanel">
<div class="panel-body">
<div class="row">
<div class="col-md-2">
#Html.LabelFor(model => model.BlogPublishedByBlogId.CreatedDateTime)
#Html.TextBoxFor(model => model.BlogPublishedByBlogId.CreatedDateTime, new { #class = "form-control", #disabled = "disabled" })
</div>
<div class="col-md-2">
#Html.LabelFor(model => model.BlogPublishedByBlogId.ModifiedDateTime)
#Html.TextBoxFor(model => model.BlogPublishedByBlogId.ModifiedDateTime, new { #class = "form-control", #disabled = "disabled" })
</div>
</div>
<br />
<div class="row">
<div>
#Html.TextAreaFor(model => model.BlogPublishedByBlogId.BlogContent, new { #class = "form-control blogContent", #disabled = "disabled" })
</div>
</div>
</div>
#* Panel area - to hold the comment button. *#
<div class="panel-footer">
<button type="button" class="btn btn-default Comment" data-id="BlogPublishedByBlogId.BlogId" value="Comment">
<span class="glyphicon glyphicon-comment" aria-hidden="true"></span> Get Comment(s)
</button>
</div>
<div id="#string.Format("{0}_{1}","commentsBlock", BlogPublishedByBlogId.BlogId)" style="border: 1px solid #f1eaea; background-color: #eaf2ff;">
<div class="AddCommentArea" style="margin-left: 30%; margin-bottom: 5px; margin-top: 8px;">
<input type="text" id="#string.Format("{0}_{1}", "comment", BlogPublishedByBlogId.BlogId)" class="form-control" placeholder="Add a Comment about the blog..." style="display: inline;" />
<button type="button" class="btn btn-default addComment" data-id="BlogPublishedByBlogId.BlogId"><span class="glyphicon glyphicon-comment" aria-hidden="true"></span></button>
</div>
</div>
</div>
}
The view model:
namespace GbngWebClient.Models
{
public class BlogPublishedByBlogIdVM
{
public BlogPublishedByBlogIdVM()
{
this.BlogPublishedByBlogId = new BlogPublishedByBlogId();
}
public BlogPublishedByBlogId BlogPublishedByBlogId { get; set; }
}
}
I added #Model to the front of:
BlogPublishedByBlogId.BlogId.
I'm trying to call a partial view with details table for some items. However, the partial view does not show any record in the main view. How I can call the Patrial view successfully? the partial view as follows:
#model IDECOHealthInsurance.Models.Pharmacy
#using (Html.BeginForm("pharmacyDetials", "Pharmacy"))
{
<h4>تفاصيل الصيدلية</h4>
<div id="dvPatientNotice" class="MainGridContainer pb-5">
#if (Model.dtItemsDetails != null)
{
<table dir="rtl" id="Paitents" class="MainGrid">
<thead>
<tr style="text-size-adjust:auto">
<th>
رقم الموظف
</th>
<th>
التاريخ
</th>
<th>
الوقت
</th>
<th>
المستفيدون
</th>
<th>
ملاحظات
</th>
<th>
الباركورد
</th>
<th>
أسم العينة
</th>
<th>
الكمية
</th>
<th>
السعر
</th>
</tr>
</thead>
<tbody>
#foreach (System.Data.DataRow row in Model.dtItemsDetails.Rows)
{
<tr style="width:100%">
<td>
#row["EMPLOYEE_NUMBER"]
</td>
<td>
#row["ENTRY_DATE"]
</td>
<td>
#row["ENTRY_TIME"]
</td>
<td>
#row["BENEFICIARIES"]
</td>
<td>
#row["NOTE"]
</td>
<td>
#row["ITEM_CODE"]
</td>
<td>
#row["ITEM_NAME"]
</td>
<td>
#row["QTY"]
</td>
<td>
#row["PRICE"]
</td>
</tr>
}
</tbody>
</table>
}
</div>
}
The controller as follows:
[HttpGet]
public ActionResult pharmacyDetials(Pharmacy model)
{
var masterID = Convert.ToInt32(Session["login"]);
if (masterID == 0)
{
return RedirectToAction("Login");
}
else
{
Models.Pharmacy objPharamcyMode = new Pharmacy();
IDECOServiceReference.IdecoAPIServiceClient idecoAPI = new IDECOServiceReference.IdecoAPIServiceClient();
DataTable dataTable = idecoAPI.GETPHARMACYEMPLOYEEMASTER("", 1);
model.dtItemsDetails = dataTable;
return PartialView("_PharmacyDetails", model);
}
}
And the Main view as follows:
#model IDECOHealthInsurance.Models.Pharmacy
#{
ViewBag.Title = "PharmacyApplication";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table style="height:680px; width:1280px; border:hidden">
<tr>
<td>
<div id="pDetail">
#Html.Partial("_PharmacyDetails", Model)
</div>
</td>
<td>
#using (Ajax.BeginForm("PharmacyApplication", "Pharmacy", new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "updatePnl", InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace, LoadingElementId = "Loading", OnBegin = "" }))
{
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.PHARMACY_NAME, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model => model.PHARMACY_NAME)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EMPLOYEE_NUMBER, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.EMPLOYEE_NUMBER, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.EMPLOYEE_NUMBER, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ENTRY_DATE, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DisplayFor(model => model.ENTRY_DATE, new { htmlAttributes = new { #class = "form-control", #Value = DateTime.Today.ToString("dd/MM/yyyy"), #readonly = "readonly" } })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ENTRY_TIME, new { htmlAttributes = new { #class = "form-control", #Value = DateTime.Today.ToString("HH:mm:ss"), #readonly = "readonly" } })
<div class="col-md-10">
#Html.DisplayFor(model => model.ENTRY_TIME)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BENEFICIARIES, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
زوجة #Html.RadioButtonFor(m => m.BENEFICIARIES, 1)
أبن #Html.RadioButtonFor(m => m.BENEFICIARIES, 2)
أبنة #Html.RadioButtonFor(m => m.BENEFICIARIES, 3)
الموظف #Html.RadioButtonFor(m => m.BENEFICIARIES, 4)
#Html.ValidationMessageFor(model => model.BENEFICIARIES, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Note, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<textarea name="NOTE" id="comments" style="font-family:'Times New Roman';font-size:1.2em; width: 280px; height:auto" placeholder="أكتب ملاحظاتك هنا"></textarea>
#Html.ValidationMessageFor(model => model.Note, "", new { #class = "text-danger" })
</div>
</div>
<div id="showPnl">
<input class="btn btn-default" type="button" value="تفاصيل الصيدلية" onclick="#("window.location.href='" + #Url.Action("pharmacyDetials", "Pharmacy") + "'");" />
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" id="panel" value="أضافة" class="btn btn-default" />
</div>
<input class="btn btn-default" type="button" value="خروج" onclick="#("window.location.href='" + #Url.Action("LogOut", "Pharmacy") + "'");" />
</div>
</div>
}
</td>
</tr>
</table>
<div id="updatePnl">
#Html.Partial("_PartialPharmacyDetails", Model)
</div>
<br />
<br />
<br />
<div id="pnlItemsDetails">
#Html.Partial("_PartialItemsDetails", Model)
</div>
When I click on the pharmacy details (in Arabic) = "تفصيل الصيدلية" button it redirects me to another page which contains the desired table that I want to show in the main view. However, I don't want this to happen I want to show the table without clicking on the button. Could you explain why this problem happened?
The Result at the run time appears as follows:
Result of the application at run time
If you want to prevent your page from redirecting, you've to use an ajax request. Replace below line :
<input class="btn btn-default" type="button" value="تفاصيل الصيدلية" onclick="#("window.location.href='" + #Url.Action("pharmacyDetials", "Pharmacy") + "'");" />
with :
<input class="btn btn-default" type="button" value="تفاصيل الصيدلية" onclick="getPharmacyDetails();" />
and in your javascript section, add below code :
function getPharmacyDetails()
{
$.ajax({
url : '#Url.Content("~/Pharmacy/pharmacyDetials")',
type: "GET",
success: function (result) {
$("#pDetail").html(result);
}
});
}
Also, replace below HTML :
<div id="pDetail">
#Html.Partial("_PharmacyDetails", Model)
</div>
With :
<div id="pDetail"></div>
The above ajax request will execute the partial view and fill the pDetial div with the required result. Try it and Let me know if you've any query.
I have a table showing the information of the users, with an edit button for each one.
I want to show a modal form with the details for the user I want to edit, but I don't know how to get the details from the list, and passing them to the modal as a model.
Here is my View:
#model MyApp.Models.User
#{
ViewBag.Title = "Users";
var roles = new List<string> { "Manager", "Admin" };
var userRoles = (List<string>)ViewData["userRoles"];
}
<h2>#ViewBag.Title</h2>
#if (userRoles.Any(u => roles.Contains(u)))
{
using (Html.BeginForm("Update", "Admin", FormMethod.Post, new { id = "update-form", value = "" }))
{
<div class="modal fade" id="user-editor" >
<div class="modal-header">
<a class="close" data-dismiss="modal"><h3>×</h3></a>
<h3 id="modal-title">Edit User</h3>
</div>
<div class="modal-body">
<div class="form-group">
#Html.Label("Name", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Name, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.Label("Age", new { #class = "col-md-2 control-label" })
<div class="col-md-10">
#Html.TextBoxFor(m => m.Age, new { #class = "form-control" })
</div>
</div>
</div>
<div class="modal-footer">
<a class="btn" data-dismiss="modal">Close</a>
<input type="submit" class="btn btn-primary" value="Save Changes" />
</div>
</div>
}
}
<table class="table-bordered table-hover" id="tbusers">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
#if (userRoles.Any(u => roles.Contains(u)))
{
<th>Edit</th>
}
</tr>
</thead>
<tbody>
#foreach (var u in users)
{
<tr id="#u.Id">
<td>#u.Name</td>
<td>#u.Age</td>
#if (userRoles.Any(u => roles.Contains(u)))
{
<td><a type="button" class="btn edit-btn" href="#user-editor" data-toggle="modal">Edit</a></td>
}
</tr>
}
</tbody>
</table>
I've created a testing sample which will help you understand how can you achieve this.
Index.cshtml which will show a list of employees
#model IEnumerable<MvcApplication1.Models.Employee>
#using MvcApplication1.Models;
<h2>Index</h2>
<table>
#foreach (Employee item in Model)
{
<tr>
<td>#Html.ActionLink(#item.EmployeeName, "Name", new { id = item.ID })</td>
<td>
<button type="button" data-id='#item.ID' class="anchorDetail btn btn-info btn-sm" data-toggle="modal"
data-target="#myModal">
Open Large Modal</button></td>
</tr>
}
</table>
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Details</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
At the same page, reference the following scripts
<script src="~/Scripts/jquery-3.1.1.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
JQuery AJAX call for getting/setting the data of individual employee from ActionMethod at the same page
<script>
$(document).ready(function () {
var TeamDetailPostBackURL = '/Employee/Details';
$(document).on('click', '.anchorDetail', function () {
var $buttonClicked = $(this);
var id = $buttonClicked.attr('data-id');
var options = { "backdrop": "static", keyboard: true };
$.ajax({
type: "GET",
url: TeamDetailPostBackURL,
contentType: "application/json; charset=utf-8",
data: { "Id": id },
datatype: "json",
success: function (data) {
debugger;
$('.modal-body').html(data);
$('#myModal').modal(options);
$('#myModal').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
});
$("#closbtn").click(function () {
$('#myModal').modal('hide');
});
});
Now Create a class of Employee(because i'm not using EF)
public class Employee
{
public int ID { get; set; }
public string EmployeeName { get; set; }
}
Create controller named Employee and 2 ActionMethods like these:
public ActionResult Index()
{
return View(emp);//sends a List of employees to Index View
}
public ActionResult Details(int Id)
{
return PartialView("Details",
emp.Where(x=>x.ID==Convert.ToInt32(Id)).FirstOrDefault());
}
I'm returning PartialView because I need to load a page within a page.
Details.cshtml
#model MvcApplication1.Models.Employee
<fieldset>
<legend>Employee</legend>
<div class="display-label">
#Html.DisplayNameFor(model => model.ID)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.ID)
</div>
<div class="display-label">
#Html.DisplayNameFor(model => model.EmployeeName)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.EmployeeName)
</div>
</fieldset>
<p>#Html.ActionLink("Back to List", "Index")</p>
When you execute and visit the Index page of Employee, you'll see screen like this:
And the Modal Dialog with results will be shown like this:
Note: You need to add reference of jquery and Bootstrap and you can further design/customize it according to your needs
Hope it helps!
I've got a big problem. I just want to have my Create - View for new VacationRequests in my Index-View
It's not possible for me to have two different models in one view.
#*#model System.Collections.Generic.IEnumerable<AppEule.Models.VacationRequest>*#
#model System.Collections.Generic.IEnumerable<GUIManagement.EmployeeVacationRequestViewItem>
#using System.Collections
#using System.Collections.Generic
#using AppEule.Models
#using TestAjax.Helpers
<h2>
#{ViewBag.Title = "Urlaubsanträge";}
</h2>
#*<p>
#Html.ActionLink("Create New", "Create")
</p>*#
<div class="table-responsive">
<table id="mytable" class="table table-bordred table-striped">
<thead>
<th>Zeitraum</th>
<th>Urlaubstage</th>
<th>Vertreter</th>
<th>Status</th>
<th></th>
<th></th>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td class="col-md-4">
#Html.DisplayFor(modelItem => item.VacationStartDateViewString) - #Html.DisplayFor(modelItem => item.VacationEndDateViewString)
</td>
<td class ="col-md-1">
#Html.DisplayFor(modelItem => item.NetVacationDaysViewString)
</td>
<td class="col-md-3">
#Html.DisplayFor(modelItem => item.ShiftPartnerFullName)
</td>
<td class="col-md-2">
#Html.DisplayFor(modelItem => item.VacationRequestProcessingStateViewString)
</td>
<td class="col-md-1">
#Html.NoEncodeActionLink("<span class='fa fa-info'></span>", "Details aneigen", "Details", "VacationRequests", routeValues: new { id = item.VacationRequestID }, htmlAttributes: new { #class = "btn btn-primary btn_small btn-sm" })
</td>
<td class="col-md-1">
#Html.NoEncodeActionLink("<span class='fa fa-ban'></span>", "Urlaubsantrag stornieren", "Delete", "VacationRequests", routeValues: new { id = item.VacationRequestID }, htmlAttributes: new { #class = "btn btn-danger btn_small btn-sm" })
</td>
</tr>
}
</tbody>
</table>
#Html.RenderPartial("~/Views/VacationRequests/_CreateVacationRequest.cshtml", VacationManagement.VacationRequest() Vac);
</div>
How can i access or render the partial view?
#Html.RenderPartial("~/Views/VacationRequests/_CreateVacationRequest.cshtml", VacationManagement.VacationRequest() Vac);
This is the partial view.
#using System
#using System.Activities.Expressions
#model VacationManagement.VacationRequest
#{
Layout = null;
}
<div class="modal fade" id="add" tabindex="-1" role="dialog" aria-labelledby="edit" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true"><span class="glyphicon glyphicon-remove" aria-hidden="true"></span></button>
<div class="modal-header">
<img src="~/Content/images/logo_dash.png" class="img-responsive center-block" alt="Responsive image">
<h4 class="modal-title custom_align" id="Heading">Urlaubsantrag stellen</h4>
</div>
<div class="modal-body">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#* #Html.AntiForgeryToken()*#
#Html.EditorFor(model => model.EmployeeID, new { htmlAttributes = new { #class = "form-control datepicker" } })
<div class="form-horizontal">
#Html.LabelFor(model => model.VacationStartDate, "Urlaubsbeginn", htmlAttributes: new { #class = "control-label" })
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<div class="col-md-12">
#Html.EditorFor(model => model.VacationStartDate, new { htmlAttributes = new { #class = "form-control datepicker" } })
#Html.ValidationMessageFor(model => model.VacationStartDate, "", new { #class = "text-danger" })
</div>
</div>
#Html.LabelFor(model => model.VacationEndDate, "Urlaubsende", htmlAttributes: new { #class = "control-label" })
<div class="form-group">
<div class="col-md-12">
#Html.EditorFor(model => model.VacationEndDate, new { htmlAttributes = new { #class = "form-control datepicker" } })
#Html.ValidationMessageFor(model => model.VacationEndDate, "", new { #class = "text-danger" })
</div>
</div>
</div>
<input type="submit" value="Create" class="btn btn-default" />
}
</div>
<div class="modal-footer ">
<button type="submit" value="Create" class="btn btn-success"> Speichern</button>
</div>
</div>
</div>
</div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
You need to pass an instance of VacationManagement.VacationRequest to the partial view. Change this
#Html.RenderPartial("~/Views/VacationRequests/_CreateVacationRequest.cshtml", VacationManagement.VacationRequest() Vac);
to this
#{ Html.RenderPartial("_CreateVacationRequest", new VacationManagement.VacationRequest()); }
I have a large form and it's becoming too big so I want to start using partial view to keep it cleaner.
Here is a little part of the form that shows the main contact and a list of alternative contacts. The user can add more contacts (the buttons shows a popup to insert new contact) and the user can change the contact from active to inactive (through the checkbox on the table). Right now this is working but like i said i want to be able to use a partial view for the table.
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">Contacts</h3>
</div>
<div class="box-body">
<div class="form-group">
<div class="col-xs-4">
<label>Phone:</label>
#Html.EditorFor(model => model.Persons.Phone, new { htmlAttributes = new { #class = "form-control", #id = "phone" } })
#Html.ValidationMessageFor(model => model.Persons.Phone, "", new { #class = "text-danger" })
</div>
<div class="col-xs-8">
<label>Email:</label>
#Html.EditorFor(model => model.Persons.Email, new { htmlAttributes = new { #id = "email", #class = "form-control", #placeholder = "Introduza o email..." } })
#Html.ValidationMessageFor(model => model.Persons.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<label>Address:</label>
#Html.TextAreaFor(model => model.Persons.Address, new { #class = "form-control", #placeholder = "Introduza a morada...", #rows = 3 })
#Html.ValidationMessageFor(model => model.Persons.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
#if (Model.Contacts != null && Model.Contacts.Count > 0)
{
<table id="example2" class="table table-bordered table-hover dataTable" aria-describedby="example2_info">
<thead>
<tr role="row">
<th class="sorting_asc" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-sort="ascending">Contact</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1">Contact Type</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1">Active</th>
</thead>
<tbody role="alert" aria-live="polite" aria-relevant="all">
#{
string cssClass = string.Empty;
string activo = string.Empty;
}
#for (var i = 0; i < Model.Contacts.Count; i++)
{
cssClass = i % 2 == 0 ? "even" : "odd";
<tr class="´#cssClass">
<td class=" ">#Html.DisplayFor(model => Model.Contacts[i].Contact)</td>
<td class=" ">#Html.DisplayFor(model => Model.Contacts[i].contacttypes.Name)</td>
<td class=" ">#Html.CheckBoxFor(model => Model.Contacts[i].IsActive, new { #class = "flat-green" })</td>
</tr>
#Html.HiddenFor(model => Model.Contacts[i].ContactsId)
}
</tbody>
</table>
}
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<input type="button" value="Add New Contact" class="buttonCreate btn btn-primary btn-sm" />
</div>
</div>
</div>
So here is the same HTML using the partial view
<div class="box box-primary">
<div class="box-header">
<h3 class="box-title">Contacts</h3>
</div>
<div class="box-body">
<div class="form-group">
<div class="col-xs-4">
<label>Phone:</label>
#Html.EditorFor(model => model.Persons.Phone, new { htmlAttributes = new { #class = "form-control", #id = "phone" } })
#Html.ValidationMessageFor(model => model.Persons.Phone, "", new { #class = "text-danger" })
</div>
<div class="col-xs-8">
<label>Email:</label>
#Html.EditorFor(model => model.Persons.Email, new { htmlAttributes = new { #id = "email", #class = "form-control", #placeholder = "Introduza o email..." } })
#Html.ValidationMessageFor(model => model.Persons.Email, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<label>Address:</label>
#Html.TextAreaFor(model => model.Persons.Address, new { #class = "form-control", #placeholder = "Introduza a morada...", #rows = 3 })
#Html.ValidationMessageFor(model => model.Persons.Address, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
#Html.Partial("ContactListControl", Model.Contacts)
</div>
</div>
<div class="form-group">
<div class="col-xs-12">
<input type="button" value="Add New Contact" class="buttonCreate btn btn-primary btn-sm" />
</div>
</div>
</div>
and here is the Partial view:
#model List<RecruitmentWeb.Models.contacts>
<table id="example2" class="table table-bordered table-hover dataTable" aria-describedby="example2_info">
<thead>
<tr role="row">
<th class="sorting_asc" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1" aria-sort="ascending">Contato</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1">Tipo de Contato</th>
<th class="sorting" role="columnheader" tabindex="0" aria-controls="example2" rowspan="1" colspan="1">Activo</th>
</thead>
<tbody role="alert" aria-live="polite" aria-relevant="all">
#{
string cssClass = string.Empty;
string activo = string.Empty;
}
#for (var i = 0; i < Model.Count; i++)
{
cssClass = i % 2 == 0 ? "even" : "odd";
<tr class="´#cssClass">
<td class=" ">#Html.DisplayFor(model => Model[i].Contact)</td>
<td class=" ">#Html.DisplayFor(model => Model[i].contacttypes.Name)</td>
<td class=" ">#Html.CheckBoxFor(model => Model[i].IsActive, new { #class = "flat-green" })</td>
</tr>
#Html.HiddenFor(model => Model[i].ContactsId)
}
</tbody>
The Problem
If the user changes a contact from active to inactive or vice-versa, when I submit the form the changes don't go through. In fact, the list is null and contains no information. It works if i don't use partial view.
So what I'm I missing?
You passing only a property of your model to the partial so the the hidden inputs you are generating have the name attribute name="[0].ContactsId", name="[1].ContactsId" etc. whereas they needs to be name="Contacts[0].ContactsId", name="Contacts[1].ContactsId" etc (ditto for the checkboxes).
Change the partial view model to the same as the main view (you haven't indicated what it is), and then pass the model as
#Html.Partial("ContactListControl", Model)
and adjust the Html helpers to suit. However I would recommend you consider using a custom EditorTemplate for RecruitmentWeb.Models.Contacts rather than a partial view for this.