Creating an object.cshtml editor template with MVC and Razor - asp.net-mvc

I am looking to create an editor template for Object.cshtml to change the behavior of the Html.EditorForModel() method. I can't find any example of this using Razor. I have seen this example using MVC2 and WebForm view engine but don't know enough about razor to convert it. Even a simple example would be very helpful.

I'm just going to do the Display template and leave the rest as an exercise for the reader:)
#if (Model == null) {
<text>#ViewData.ModelMetadata.NullDisplayText</text>
} else if (ViewData.TemplateInfo.TemplateDepth > 1) {
<text>#ViewData.ModelMetadata.SimpleDisplayText</text>
} else {
<table cellpadding="0" cellspacing="0" border="0">
#foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForDisplay && !ViewData.TemplateInfo.Visited(pm))) {
if (prop.HideSurroundingHtml) {
<text>#Html.Display(prop.PropertyName)</text>
} else {
<tr>
<td>
<div class="display-label" style="text-align: right;">
#prop.GetDisplayName()
</div>
</td>
<td>
<div class="display-field">
#Html.Display(prop.PropertyName)
</div>
</td>
</tr>
}
}
</table>
}

This seem to work for Editor Template for bootstrap, please let me know of any improvements
Object.cshtml
#if (Model == null)
{
<text>#ViewData.ModelMetadata.NullDisplayText</text>
}
else if (ViewData.TemplateInfo.TemplateDepth > 1)
{
<text>#ViewData.ModelMetadata.SimpleDisplayText</text>
}
else
{
foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForDisplay && !ViewData.TemplateInfo.Visited(pm)))
{
if (prop.HideSurroundingHtml)
{
<text>#Html.Editor(prop.PropertyName)</text>
}
else
{
<div class="form-group">
#Html.Label(prop.PropertyName, new { #class = "control-label col-md-2", #style = "text-align:right;" })
<div class="col-md-10">
#Html.Editor(prop.PropertyName, null, new { #class = "form-control " })
#Html.ValidationMessage(prop.PropertyName, "", new { #class = "text-danger" })
</div>
</div>
}
}
}

Related

ASP.NET MVC - add to a viewmodel list and submit

I have an ASP.NET MVC program with an order/odc request form. I have a customer, order and order item model. What I want to do is allow the user to place an order for a list of items to be approved. I have the viewmodel being passed to the form/view with a few fields including a list of order item objects. I am able to dynamically add rows to the table which shows the list of order items but on submit there is nothing in the viewmodel list. What am I doing wrong? How do I pass the items entered into the table to the view so that I can submit to the database?
Controller
public ActionResult NewOdc()
{
var viewModel = new NewOdcViewModel()
{
OdcItems = new List<tblOdcItem>()
};
viewModel.OdcItems.Add(new tblOdcItem());
return View(viewModel);
}
I call this code from jQuery to add a new item to the list:
public ActionResult GetView(string rowCount)
{
tblOdcItem item = new tblOdcItem();
return PartialView("_OdcItemEditor", item);
}
And on submit I call this code:
[HttpPost]
public ActionResult NewOdcSubmit(NewOdcViewModel viewModel)
{
_context.tblOdcs.Add(new tblOdc());
...
I'm using a foreach to go through the list and create a partial for each item.
View:
#using (Html.BeginForm("NewOdcSubmit", "Odc", FormMethod.Post))
{
if (Model != null)
{
#Html.HiddenFor(m => m.OdcItems);
}
<div class="panel panel-info">
<div class="panel-heading">
<h2 class="panel-title">Enter New ODC</h2>
</div>
<div class="panel-body">
#Html.AntiForgeryToken()
<div class="form-group">
#Html.LabelFor(model => model.User.UserName, new { #class = "col-md-2 col-sm-1 control-label" })
<div class="col-md-2 col-sm-3">
#Html.TextBoxFor(model => model.User.UserName, new { #Value = ((PM_Portal2020.Models.tblUser)Session["User"]).UserName, #readonly = true })
</div>
#Html.LabelFor(model => model.User.Phone, new { #class = "col-md-2 col-sm-1 control-label" })
<div class="col-md-2 col-sm-3">
#Html.TextBoxFor(model => model.User.Phone, new { #Value = ((PM_Portal2020.Models.tblUser)Session["User"]).Phone })
</div>
</div>
<div class="form-group col-md-10 col-sm-12">
<label>Expenses</label>
<table id="submissionTable" class="table table-bordered">
<thead>
<tr>
<th>Qty</th>
<th>Description</th>
<th>Estimated Cost</th>
</tr>
</thead>
<tbody>
#foreach (PM_Portal2020.Models.tblOdcItem item in Model.OdcItems)
{
#Html.Partial("_OdcItemEditor", item)
}
</tbody>
</table>
<p>
<button id="add" type="button" class="btn btn-primary">Add</button>
</p>
</div>
<div class="form-group col-lg-10 col-sm-12">
#Html.LabelFor(model => model.Details, new { #class = "col-md-2 col-sm-1 control-label" })
<div class="">
#Html.TextAreaFor(model => model.Details, new { #class = "form-control" })
</div>
</div>
</div>
<div class="panel-footer">
<div class="">
<button type="submit" class="btn btn-success">Save</button>
#Html.ActionLink("Back", "Index")
</div>
</div>
</div>
}
PartialView in Shared folder:
#model PM_Portal2020.Models.tblOdcItem
<tr #Html.Id("tablerow" + Model.ID)>
<td>
<div class="editor-field">
#Html.TextBoxFor(model => model.Quantity, new { #class = "text-box single-line", name = "Quantity[" + Model.ID + "]", type = "text", value = "", required = "required" })
</div>
</td>
<td>
<div class="editor-field">
#Html.TextBoxFor(model => model.Description, new { #class = "text-box single-line", name = "Description[" + Model.ID + "]", type = "text", value = "", required = "required", id = "itemDesc" })
</div>
</td>
<td>
<div class="editor-field">
#Html.TextBoxFor(model => model.EstimatedCost, new { #class = "text-box single-line", name = "EstimatedCost[" + Model.ID + "]", type = "text", value = "", required = "required" })
</div>
</td>
<td>
<button type="button" class="btn btn-primary" onclick="removeTr(this);">
<span class="glyphicon glyphicon-trash"></span>
</button>
</td>
</tr>
View Model
public class NewOdcViewModel
{
public NewOdcViewModel()
{
}
public IList<tblOdcItem> OdcItems { get; set; }
public string Details { get; set; }
public int OdcId { get; set; }
public tblUser User { get; set; }
}
It submits to the controller but the odcitems list is always count = 0. Any help would be great. Thanks
Here is the javascript example, just use this function on add/delete operation to re-arrange name.
function RearangeName(){
var i = 0;
$("#submissionTable>tbody>tr").each(function () {
$(this).find("input").each(function () {
if ($(this).prop("name").indexOf('Quantity') > 0) {
$(this).attr('name', "OdcItems[" + i + "].Quantity");
}
if ($(this).prop("name").indexOf('Description') > 0) {
$(this).attr('name', "OdcItems[" + i + "].Description");
}
if ($(this).prop("name").indexOf('EstimatedCost') > 0) {
$(this).attr('name', "OdcItems[" + i + "].EstimatedCost");
}
});
i++;
});
}
the name should be matched with model property, so in partial view, you have set name as OdcItems[0].Quantity instead of Quantity[" + Model.ID + "].
#Html.TextBoxFor(model => model.Quantity, new { #class = "text-box single-line", name = "OdcItems[0].Quantity", type = "text", value = "", required = "required" })
eg.
OdcItems[0].Quantity
OdcItems[1].Quantity
OdcItems[2].Quantity
....
OdcItems[n].Quantity

asp.net mvc displaying contents in view on condition

I have a following view in my project where i have one dropdown and one textbox and submit button.I want to execute following scenario.
On click of submit only,I want to display the table contents.So if there is data,it will display data or else it will display "No records found".Is it possible?
My view is as follows:
model mvclearn.Models.Employee
#{
ViewBag.Title = "menu";
}
#{
Layout = null;
}
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<style>
.error {
color: red;
}
</style>
<div class="container">
<div class="container"style="width:30%">
#using (Html.BeginForm("save", "Test", FormMethod.Post))
{
#Html.DropDownListFor(m => m.Service_Code, Model.ser_code, "--select--", new { #class = "form-control", #placeholder = "Enter Service code" })
#Html.ValidationMessageFor(m => m.Service_Code, "", new { #class = "error" })
#Html.TextBoxFor(m => m.Service_Name, new { #class = "form-control", #placeholder = "Service Name" })
#Html.ValidationMessageFor(m => m.Service_Name, "", new { #class = "error" })
<input type="submit" value="submit" class="btn-block" />
}
<table class="table">
#{
if (Model.data!=null && Model.data.Count() > 0)
{
<tr>
<th>
#Html.DisplayName("Service_Code")
</th>
<th>
#Html.DisplayName("Service_Name")
</th>
</tr>
foreach (mvclearn.Models.Employee item in Model.data)
{
<tr>
<td>
#item.Service_Code
</td>
<td>
#item.Service_Name
</td>
</tr>
}
}
else
{
<p>No records found</p>
}
}
</table>
</div>
In your case, you have done a nice job but the way you are dealing with the model seems to be incorrect.You cannot use Model.data!= null statement,instead,I suggest you to do something like this.Check whether the Model's attributes are null or not!
if (Model.EmployeeName!=null ){
//your code here
}
Another possible reason for your problem is the model returns null values so check whether the model's attributes has the values when it is in the view.
Hope it helped.
You Can Embed Table tag in the If condition like this ...
#if(Model.data!=null && Model.data.Count() > 0)
{
<table>
<tr>
<td></td>
</tr>
</table>
}else{
<p>There is no records</p>
}

MVC PagedList Dynamic Page/Page Size determined by model

I am using the PagedList.mvc helper to handle the paging of my application, in all examples i have found people tend to explicitly set the page size. I wish to set the page size dynamically from data in a model as well create new pages from the data as well.
Table
I have the table stipulated in the image above, i would like it that page 1 is all entries that have the MonthInt as 1 and page 2 all entries as MonthInt 2 etc.. however i want each page size to be determined by how many entries there are for each month.. it currently dynamically sets the sizes of the pages according to the first page and only limits the first page to display entries with the MonthInt 1-3, after that it goes to the next page but doesnt follow the same rule.. Any help/suggestions would be great,
Controller Code:
// GET: Customers/Details/5
public ActionResult Details(int? id, string sortOrder, string searchString, string currentFilter, int? page)
{
Customer customer = db.Customers.Find(id);
var viewModel = new CustomerViewModel();
if (id != null)
{
IEnumerable<Vehicle> vehicles = db.Vehicles.Where(c => c.CustomerId == customer.Id);
List<Vehicle> vehiclesList = vehicles.OrderBy(m => m.MonthId).ThenBy(r => r.Register).ToList();
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
int pageSize = vehicles.Count(m => m.MonthId <= 3);
int pageNumber = (page ?? 1);
if (!String.IsNullOrEmpty(searchString))
{
vehiclesList = vehicles.Where(r => r.Register.Contains(searchString.ToUpper())
|| r.License.Contains(searchString.ToUpper())).ToList();
}
PagedList<Vehicle> pagedList = new PagedList<Vehicle>(vehiclesList, pageNumber,pageSize);
viewModel = new CustomerViewModel()
{
Vehicles = pagedList,
Customer = customer
};
}
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
if (customer == null)
{
return HttpNotFound();
}
return View(viewModel);
}
View Code:
#model Application.ViewModels.CustomerViewModel
#using PagedList;
#using PagedList.Mvc
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Fleet Details";
}
<div>
<h2>#Model.Customer.Name</h2>
#using (Html.BeginForm("Details", "Customers", FormMethod.Get))
{
<div class="input-group">
<div class="input-group-btn">
<div class="btn-toolbar">
#Html.TextBox("searchString", ViewBag.CurrentFilter as string, null, new {#class = "form-control", placeholder = "Find by Register/License", autofocus = "autofocus"})
<input class="btn-warning btn" type="submit" value="search"/>
</div>
</div>
</div>
}
<hr />
#if (!Model.Vehicles.Any())
{
<p>No Vehicles loaded</p>
<br />
}
else
{
<table class="table table-hover table-bordered">
<tr>
<th>#Html.DisplayName("Owner")</th>
<th>#Html.DisplayName("License")</th>
<th>#Html.DisplayName("Make")</th>
<th>#Html.DisplayName("Register")</th>
<th>#Html.DisplayName("MonthInt")</th>
<th>#Html.DisplayName("Month")</th>
</tr>
#foreach (var item in Model.Vehicles)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.OwnerName)</td>
<td>#Html.DisplayFor(modelItem => item.License)</td>
<td>#Html.DisplayFor(modelItem => item.Make)</td>
<td>#Html.DisplayFor(modelItem => item.Register)</td>
<td>#Html.DisplayFor(modelItem => item.MonthId)</td>
<td>#Html.DisplayFor(modelItem => item.MonthName)</td>
<td>
<div class="btn-toolbar">
#Html.ActionLink("Edit", "Edit", "Vehicles", new { id = item.VehicleId }, new { #class = "btn btn-primary" })
#Html.ActionLink("Details", "Details", "Vehicles", new { id = item.VehicleId }, new { #class = "btn btn-default" })
#Html.ActionLink("Delete", "Delete", "Vehicles", new { id = item.VehicleId }, new { #class = "btn btn-danger" })
</div>
</td>
</tr>
}
</table>
}
<div class="btn-toolbar">
#Html.ActionLink("Add Vehicle", "Create", "Vehicles", new { id = Model.Customer.Id }, new { #class = "btn-success btn" })
#Html.ActionLink("Edit Customer Name", "Edit", new { id = Model.Customer.Id }, new { #class = "btn btn-primary" })
#Html.ActionLink("Delete Customer", "Delete", new { id = Model.Customer.Id }, new { #class = "btn-danger btn" })
#Html.ActionLink("Back to List", "Index", null, new { #class = "btn-default btn" })
</div>
<br/>
Page #(Model.Vehicles.PageCount < Model.Vehicles.PageNumber ? 0 : Model.Vehicles.PageNumber) of #Model.Vehicles.PageCount
#Html.PagedListPager(Model.Vehicles, page => Url.Action("Details",
new { page, pageSize = #Model.Vehicles.PageSize }))
Showing #Model.Vehicles.FirstItemOnPage to #Model.Vehicles.LastItemOnPage
of #Model.Vehicles.TotalItemCount Vehicles
Example: Example 1
Example 2
Solution kind of just happened while trying other things. Current solution allows for each month to be on its own page. It might not be the best solution but it works.
Added custom class to group data:
public class Group<T, TK>
{
public TK Key;
public IEnumerable<T> Values;
}
Updated ViewModel:
public PagedList<Group<Vehicle, string>> VehiclesGroup { get; set; }
Updated Details Controller:
public ActionResult Details(int? id, string searchString, string currentFilter, int? page, int? item)
{
var customer = db.Customers.Find(id);
if (customer == null)
{
return HttpNotFound();
}
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var vehicles = from f in db.Vehicles
where f.CustomerId == customer.Id
select f;
var vehiclesList = vehicles.OrderBy(m => m.MonthId).ThenBy(r => r.Register).ToList();
var groupedVehicles = from v in vehiclesList
group v by v.MonthName
into g
select new Group<Vehicle, string> { Key = g.Key, Values = g };
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var pageSize = vehicles.Count(v => v.MonthId <= 0);
if (pageSize == 0)
{
pageSize = 1;
}
var pageNumber = (page ?? 1);
if (!string.IsNullOrEmpty(searchString))
{
vehicles = vehicles.Where(r => r.Register.Contains(searchString.ToUpper())
|| r.License.Contains(searchString.ToUpper())
|| r.Make.Contains(searchString.ToUpper())
|| r.OwnerName.Contains(searchString.ToUpper())
|| r.Vin.Contains(searchString.ToUpper())
|| r.MonthName.Contains(searchString.ToUpper()));
vehiclesList = vehicles.ToList();
groupedVehicles = from v in vehiclesList
group v by v.MonthName
into g
select new Group<Vehicle, string> { Key = g.Key, Values = g };
}
var pagedList = new PagedList<Group<Vehicle, string>>(groupedVehicles, pageNumber, pageSize);
var viewModel = new CustomerVehicleViewModel()
{
VehiclesGroup = pagedList,
Customer = customer
};
return View(viewModel);
}
Updated View:
#model Application.ViewModels.CustomerVehicleViewModel
#using PagedList.Mvc
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Fleet Details";
if (TempData["Error"] != null)
{
ViewBag.Error = TempData["Error"];
}
}
<h2>#Model.Customer.Name</h2>
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-6" style="margin-bottom: 1%">
#using (Html.BeginForm("Details", "Customers", FormMethod.Get))
{
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="input-group">
<div class="input-group">
<span class="input-group-addon"><span class="glyphicon glyphicon-search"></span></span>
#Html.TextBox("searchString", ViewBag.CurrentFilter as string, null, new { #class = "form-control", placeholder = "Search", autofocus = "autofocus", style = "margin-right:1%" })
</div>
<div class="input-group-btn">
<input class="btn-warning btn" type="submit" value="search" />
#Html.ActionLink("Reset", null, null, null, new { #class = "btn btn-info", style = "margin-left: 5%" })
</div>
</div>
}
</div>
<div class="col-md-6">
<div class="btn-toolbar">
#Html.ActionLink("Add Vehicle", "Create", "Vehicles", new { id = Model.Customer.Id }, new { #class = "btn-success btn" })
#Html.ActionLink("Edit Customer", "Edit", new { id = Model.Customer.Id }, new { #class = "btn btn-primary" })
#Html.ActionLink("Delete Customer", "Delete", new { id = Model.Customer.Id }, new { #class = "btn-danger btn" })
#Html.ActionLink("Back to List", "Index", null, new { #class = "btn-default btn" })
#Html.ActionLink("BRN/ID", "ViewFile", "Customers", new { cid = Model.Customer.Id, id = Model.Customer.FileId }, new { #class = "btn-info btn", target = "_blank" })
</div>
</div>
</div>
</div>
</div>
#Html.ValidationMessage("", $"{ViewBag.Error}", new { #class = "text-danger" })
<hr />
#if (!Model.VehiclesGroup.Any())
{
<p>No Vehicles loaded</p>
<br />
}
else
{
<table class="table table-hover table-bordered" id="table">
<thead>
<tr>
<th>#Html.DisplayName("Owner")</th>
<th>#Html.DisplayName("License")</th>
<th>#Html.DisplayName("Make")</th>
<th>#Html.DisplayName("Register")</th>
<th>#Html.DisplayName("VIN")</th>
<th>#Html.DisplayName("Month")</th>
<th class="remove">
<button id="btnPrint" class="btn btn-warning"><span class="glyphicon glyphicon-print" aria-hidden="true"></span> Print Table</button>
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.VehiclesGroup)
{
foreach (var i in item.Values)
{
<tr>
<td>#Html.DisplayFor(modelItem => i.OwnerName)</td>
<td>#Html.DisplayFor(modelItem => i.License)</td>
<td>#Html.DisplayFor(modelItem => i.Make)</td>
<td>#Html.DisplayFor(modelItem => i.Register)</td>
<td>#Html.DisplayFor(modelItem => i.Vin)</td>
<td>#Html.DisplayFor(modelItem => i.MonthName)</td>
<td class="remove">
<div class="btn-toolbar">
#Html.ActionLink("Edit", "Edit", "Vehicles", new { id = i.VehicleId }, new { #class = "btn btn-primary" })
#Html.ActionLink("Details", "Details", "Vehicles", new { id = i.VehicleId }, new { #class = "btn btn-default" })
#Html.ActionLink("Delete", "Delete", "Vehicles", new { id = i.VehicleId }, new { #class = "btn btn-danger" })
#Html.ActionLink("Scan", "ViewFile", "Vehicles", new { cId = i.CustomerId, id = i.VehicleId }, new { #class = "btn btn-info", target = "_blank" })
</div>
</td>
</tr>
}
<tr>
<td colspan="3">#item.Key</td>
<td colspan="3"></td>
</tr>
}
</tbody>
</table>
}
<br />
Page #(Model.VehiclesGroup.PageCount < Model.VehiclesGroup.PageNumber ? 0 : Model.VehiclesGroup.PageNumber) of #Model.VehiclesGroup.PageCount
#Html.PagedListPager(Model.VehiclesGroup, page => Url.Action("Details",
new
{
page,
currentFilter = ViewBag.CurrentFilter,
pageSize = #Model.VehiclesGroup.PageSize
}))
Total of #Model.VehiclesGroup.TotalItemCount Pages
Updated Display of month January/page 1
Page 1
Updated Display of month February/page 2
Page 2
Updated Display of Page 3
Page 3
Hope it helps someone, or if anyone has better ideas please share!

Paging issue in ASP.Net Mvc Application

I am developing an MVC application in which I use a DropdownList to select "vendor". When I select a vendor from the dropdown then the view shows products related to the selected vendor.
I use paging to display multiple pages of particular vendor's products.
My issue is when I select a vendor from dropdown, at change event it displays products on all pages properly. If I select 2nd page it shows products from 2nd page. But next time if I select another vendor from dropdown, it shows 2nd page of selected vendor. But what I want is to display first page of selected vendor initially.
Controller code as below
public ActionResult Index(int? page ,int VendorId = 0)
{
var pageNumber = (page ?? 1);
var pagesize = 2;
if (VendorId == 0)
{
VendorId = Convert.ToInt32(Session["InventoryVendorId"]);
}
VendorService vendorService = new VendorService();
SelectList SelectList = new SelectList(vendorService.GetAll().OrderBy(t => t.Name), "Id", "Name", VendorId);
ViewData["list"] = SelectList;
int id = Convert.ToInt32(Session["loggedEmpId"]);
CommonService.SetEmployeeId(id);
if (VendorId != 0)
{
Session["InventoryVendorId"] = VendorId;
ProductService ProductService = new ProductService();
var productList = ProductService.GetProductInventory().Where(x=>x.VendorId == VendorId);
return View(productList.ToPagedList(pageNumber, pagesize));
}
else
{
return View();
}
}
code for view as below
#model PagedList.IPagedList<StockWatch.DTO.ProductDTO>
#using PagedList.Mvc;
#using System.Web.UI.WebControls
#{
ViewBag.Title = "Index";
int VendorId = Convert.ToInt32(Session["InventoryVendorId"]);
}
<link href="~/Content/PagedList.css" rel="stylesheet" />
<div class="row-fluid">
<div id="vendorDropdownDiv4" class="span12 " style="margin-left:0px;margin-top:10px;">
<div class="span6" >
<div class="span4" style="margin-left:1px;" >
<label >Vendor</label>
</div>
<div class="span6" >
#Html.DropDownList("VendorId", ViewData["list"] as SelectList, "-- Select vendor --", new { #id = "vendorIdforInventory", #name = "VendorId" })
</div>
</div>
<div class="span3" style="text-align:right">
#* <input class="btn btn-primary" type="submit" value="Load" id="create"/>*#
#*<input class="btn btn-default" value="Cancel" style="width:45px;" onclick="window.location.href='#Url.Action("index") '"/>*#
</div>
</div>
</div>
<div id="Newindexview"></div>
#if(Model != null)
{
</div>
<div class="span12" style="margin-left:0px;">
<table>
<thead>
<tr >
<th style="width:250px;" >Product Name
</th>
<th style="width:180px; text-align:left;" >Product Code
</th>
<th style="border-right: solid #e8eef4 thick; width: 0px; text-align:right;">Avg. Weight
</th>
#{
foreach (var location in ViewBag.loc)
{
<th style="width:10px;text-align:right;">#location.Name</th>
}
}
</tr>
</thead>
<tbody>
#foreach (var p in Model)
{
<tr>
<td style="width:250px;">
#p.Name
</td>
<td style="width:180px;text-align:left;">
#p.ProductCode
</td>
<td style="border-right: solid #e8eef4 thick; width: 15px; text-align:right">
#p.AvgWeight
</td>
#foreach (var location in ViewBag.loc)
{
flag = false;
if(p.Inventory != null)
{
foreach (var loc in p.Inventory)
{
if (location.Name == loc.LocationName)
{
<td style="width:10px; text-align:right;">#loc.Quantity</td>
flag = true;
}
}
}
if (flag == false)
{
<td style="width:10px; text-align:right;">0</td>
}
}
</tr>
}
</tbody>
</table>
</div>
<div class="span12" style="margin-left:0px;">
<div class="span6" style="margin-left:0px;">
#Html.PagedListPager(Model, page => Url.Action("Index", new {page ,searchContent=searchcontent}))
</div>
</div>
</div>
}
and jquery code as below
$("#vendorIdforInventory").change(function () {
var vendorid = $('#vendorIdforInventory').val();
$.ajax({
url: '#Url.Action("Index", "Inventory")',
data: {
VendorId: vendorid
},
type: "POST",
success: function (data) {
location.reload();
$('#modeldiv1').empty();
$('#vendorDropdownDiv4').hide();
$('#Newindexview').html("");
$('#Newindexview').html(data);
}
});
});
How to solve this paging issue?
You need to pass the currentFilter from your view back into your controller (which you have with VendorID), and set the page accordingly. Details are in the ASP.NET tutorial on paging at http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application.
Look at how they've implemented filtering using the searchString and currentFilter variable, that's what will make sure that when a new string is entered (or selected from a drop down list in your case) that the paging responds accordingly.
Specifically, this is what I think you're missing in your code
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
...
int pageNumber = (page ?? 1);

Enable/Disable Validation of certain hidden textboxes in mvc 2

I have got [hide] and [unhide] input buttons , the hide button shows some text boxes while the hidden button hide some text boxes, What I want to do is to enable validation only for those boxes which are visible and disable validation for the boxes which are not visible to client. Currently I am validating on all the boxes, the post action also validates the text boxes which are hidden through jquery , below is the code :
View
<script type="text/javascript">
$(document).ready(function () {
var $startdates = $('#startDates');
var $endDates = $('#endDates');
var $showEvents = $('#showEvents');
$startdates.hide();
$endDates.hide();
$showEvents.hide();
$('#all').click(function () {
$startdates.show();
$endDates.show();
$('#showEvents').show();
$('#eventdids').hide();
$(this).hide();
return false;
});
$('#showEvents').click(function () {
$startdates.hide();
$endDates.hide();
$('#eventdids').show();
$('#all').show();
$(this).hide();
return false;
});
});
</script>
<tr id="startDates">
<td>
<div class="editor-label">
<%: Html.LabelFor(model => model.StartDate) %>
</div>
</td>
<td>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.StartDate) %>
<%: Html.ValidationMessageFor(model => model.StartDate) %>
</div>
</td>
</tr>
<tr id="endDates">
<td>
<div class="editor-label">
<%: Html.LabelFor(model => model.EndDate) %>
</div>
</td>
<td>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.EndDate) %>
<%: Html.ValidationMessageFor(model => model.EndDate) %>
</div>
</td>
</tr>
<tr id="eventdids">
<td>
<label>Events</label>
</td>
<td>
<% foreach (var item in (SelectList)ViewData["events"]) { %>
<input type="checkbox" name="Name" value="<%=item.Value %>" />
<label for="<%=item.Value%>"><%=item.Text%></label>
<br />
<% } %>
</td>
<td><input type="button" name="Select" id="all" style="width:auto" value="Hide" /></td>
</tr>
</table>
<input type="button" name="show" id="showEvents" style="width:auto" value="Show" />
<p>
<input type="submit" value="Create" />
</p>
Controller:
[HttpPost]
public ActionResult Create(FormCollection collection, int[] Name)
{
IVoucherRepository voucherResp = new VoucherRepository();
string empty = "";
if (Name != null)
{
for (int i = 0; i < Name.Length; i++)
{
empty += Convert.ToString(Name[i]) + ",";
}
}
else
{
ModelState.AddModelError("Venue", "Required");
}
if (Convert.ToBoolean(collection["pound"].ToLower().StartsWith("false")) && Convert.ToBoolean(collection["percentage"].ToLower().StartsWith("false")))
{
ModelState.AddModelError("","Please Select £ or % for discount");
}
if (collection["UsageQtyAvailable"] == null) { ModelState.AddModelError("UsageQtyLeft", "Required "); }
Voucher voucher = new Voucher();
if (TryUpdateModel(voucher) && ModelState.IsValid)
{
voucher.Status = true;
voucher.DateAdded = DateTime.Now;
voucher.DateModified = DateTime.Now;
if(Convert.ToBoolean(collection["pound"].ToLower().StartsWith("true")))
{
voucher.DiscountType = 1;
}
else if (Convert.ToBoolean(collection["percentage"].ToLower().StartsWith("true")))
{
voucher.DiscountType = 2;
}
voucher.VoucherType = 1; //Discount Code
voucher.UsageQtyLeft = Convert.ToInt32(collection["UsageQtyAvailable"]);
string removeComma = empty.Remove(empty.Length - 1,1);
voucher.EventIDs = removeComma;
voucherResp.Add(voucher);
voucherResp.Save();
return RedirectToAction("Index");
}
ITrackdayRepository trackdayResp = new TrackdayRepository();
IQueryable<Object> getAllEvents = trackdayResp.GetEventsSelectlist();
ViewData["events"] = new SelectList(getAllEvents.ToList(), "EventID", "Name");
return View();
}
You could check via jquery if the text boxes are hidden and remove them before submitting the form and subsequently only validate submitted form elements.
...
<input type="submit" value="Create" id="create" />
...
$("#create").click(function() {
$('#eventdids:hidden').remove();
$('#all:hidden').remove();
$("#formID").submit();
});
You can also remove validation for all hidden fields in a form with this little plugin:
(function($) {
$.fn.refreshValidator = function() {
var form = this;
// Get validation settings object
var settings = form.validate().settings;
// Remove validation for hidden elements
$(this).find(':hidden').each(function(){
var id = $(this).attr('id');
delete settings.rules[id];
delete settings.messages[id];
});
};
})(jQuery);
You can call it like this:
$('#yourFormId').refreshValidator();
It's more reusable this way.

Resources