Paging issue in ASP.Net Mvc Application - asp.net-mvc

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

Related

Date Fields losing dates when paging MVC

I have an MVC view with a fromDate and a toDate along with a bootstrap datepicker.
The date fields display initally like '15 June 2017'
However, when I do a search, page 1 displays correctly but when i go to any other page the dates reset and show as '06 January 2000'.
Any help would be most appreciated.
Thank you.
Controller:
using PagedList;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using WebApplication5.Models;
namespace WebApplication5.Controllers
{
public class testController : Controller
{
private JobSubmissionEntities1 db = new JobSubmissionEntities1();
public ViewResult Index(string currentFilter, string searchString, DateTime? fromDate, DateTime? toDate, int? page)
{
if (!fromDate.HasValue) fromDate = DateTime.Now.Date.AddDays(-1);
if (!toDate.HasValue) toDate = DateTime.Now.AddDays(5);
if (toDate < fromDate) toDate = DateTime.Now.AddDays(5);
ViewBag.fromDate = fromDate;
ViewBag.toDate = toDate;
//IF searchString is Empty
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter; fromDate = ViewBag.fromDate; toDate = ViewBag.toDate;
}
ViewBag.CurrentFilter = searchString;
var JobDetails = from s in db.JobDetails
select s;
//if searchString IS NOT empty
if (!String.IsNullOrEmpty(searchString))
{
JobDetails = JobDetails.Where(s =>
(s.JobNo.Equals(searchString) &&
s.SubmissionDate >= fromDate && s.SubmissionDate < toDate));
}
else
{
JobDetails = JobDetails.Where(s => (
s.SubmissionDate >= fromDate && s.SubmissionDate < toDate));
}
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(JobDetails.OrderBy(i => i.JobNo).ToPagedList(pageNumber, pageSize));
}
}
}
View:
#model PagedList.IPagedList<WebApplication5.Models.JobDetail>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
Layout = "~/Views/Shared/_Layout_Wide.cshtml";
}
ViewBag.Title = "Index";
}
#section DatePicker {
<link href="~/Content/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/bootstrap-datetimepicker.min.css" rel="stylesheet" />
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/moment-with-locales.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<script src="~/Scripts/bootstrap-datetimepicker.min.js"></script>
}
<h2>Index</h2>
#{
var fromDate = (DateTime)ViewBag.fromDate;
var toDate = (DateTime)ViewBag.toDate;
}
#using (Html.BeginForm("Index", "Test", FormMethod.Get))
{
/***FromDate***/
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
<div class='input-group date' id='fromDate'>
<div>#Html.TextBox("fromDate", string.Format("{0:dd MMM yyy}", fromDate), new { #class = "form-control", } )</div>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
/***toDate***/
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
<div class='input-group date' id='toDate'>
<div>#Html.TextBox("toDate", string.Format("{0:dd MMM yyy}", toDate), new { #class = "form-control", } )</div>
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
</div>
</div>
</div>
</div>
/***searchString***/
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
#Html.Editor("SearchString", ViewBag.CurrentFilter as string, new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
</div>
</div>
/***Submit***/
<div class="container">
<div class="row">
<div class='col-sm-3'>
<div class="form-group">
<input type="submit" class="btn btn-success" value="Search" />
</div>
</div>
</div>
</div>
<hr />
}
<table class="table-bordered">
<tr style="background-color:black">
<th>
#Html.ActionLink("Job No", "Index", new { style = "color:white" })
</th>
<th>
#Html.ActionLink("Submission Date", "Index", null, new { style = "color:white" })
</th>
<th>
#Html.ActionLink("Job Title", "Index", null, new { style = "color:white" })
</th>
<th>
#Html.ActionLink("Article", "Index", null, new { style = "color:white" })
</th>
<th>
#Html.ActionLink("Status", "Index", null, new { style = "color:white" })
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
//Highlight Rows Green, Yellow or Red Dependant on Status - Yellow means job has not finished processing
string statusCheck = (item.Status);
string style = "";
if (statusCheck.Contains("Status message 0003:Job finished"))
{
style = "background-color:#e6fff2";
}
else if (statusCheck.Equals("0"))
{
style = "background-color:#ffffcc";
}
else
{
style = "background-color:#ff8080";
}
<tr style="#style">
<td>
#Html.DisplayFor(modelItem => item.JobNo)
</td>
<td>
#Html.DisplayFor(modelItem => item.SubmissionDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.JobDesc)
</td>
<td>
#Html.DisplayFor(modelItem => item.Article)
</td>
<td>
#Html.DisplayFor(modelItem => item.Status)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.SubmissionID }) |
#Html.ActionLink("Details", "Details", new { id = item.SubmissionID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.SubmissionID })
</td>
</tr>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, fromDate = ViewBag.fromDate, toDate = toDate }))
#section scripts{
<script type="text/javascript">
$(function () {
$('#fromDate').datetimepicker({
format: 'DD MMMM YYYY',
});
});
</script>
<script type="text/javascript">
$(function () {
$('#toDate').datetimepicker({
format: 'DD MMMM YYYY'
});
});
</script>
}
#Html.TextBox() can pull values out of the ModelState or ViewData.
so you can bind the date values to your text box manually
Kindly refer this link:https://stackoverflow.com/a/29369965/3397630 for an accepted solution which is similar to your problem.
Hope it will be helpful
thanks
Karthik

MVC4 Filtering with checkboxes

I have created create function in my controller which display all genres in checkoxes like this:
Controller:
public ActionResult Create()
{
var db = new MainDatabaseEntities();
var viewModel = new ANIME
{
GENRES = db.GENRES.Select(c => new { ID_GE = c.ID_GE, GENRE = c.GENRE, isSelected = false }).ToList().Select(g => new GENRES
{
ID_GE = g.ID_GE,
GENRE = g.GENRE,
isSelected = false
}).ToList()
};
return View(viewModel);
}
View:
#model AnimeWeb.Models.ANIME
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<table>
<tr>
<td class="lefttablecontent" id="top">
<div class="editor-label">
#Html.HiddenFor(model => model.ID_AN)
</div>
<div class="editor-label">
Original title
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TITLE_OR)
#Html.ValidationMessageFor(model => model.TITLE_OR)
</div>
<div class="editor-label">
English title
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TITLE_EN)
#Html.ValidationMessageFor(model => model.TITLE_EN)
</div>
<div class="editor-label">
Genres
</div>
<div class="editor-list">
#Html.EditorFor(model => model.GENRES)
#Html.ValidationMessageFor(model => model.GENRES)
</div>
</td>
<td class="righttablecontent" id="top">
<p>
<input type="submit" value="Create" />
</p>
</td>
</tr>
</table>
}
}
EditorTemplate for Genres:
#model AnimeWeb.Models.GENRES
#Html.HiddenFor(model => model.ID_GE)
#Html.HiddenFor(model => model.GENRE)
<table>
<tr>
<td class=" right">
#Html.EditorFor(model => model.isSelected)
</td>
<td>
#Html.LabelFor(model => model.isSelected, Model.GENRE)
</td>
</tr>
</table>
Now I would like to display the same template with all genres and use it for filtering in index, but I'm not sure how to do this.
Controller:
public ActionResult Index(string sortOrder, string currentFilter, int? page)
{
using (var db = new MainDatabaseEntities())
{
ViewBag.CurrentSort = sortOrder;
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var anime = from s in db.ANIME.Include("GENRES")
select s;
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(anime.ToPagedList(pageNumber, pageSize));
}
}
View:
#model PagedList.IPagedList<AnimeWeb.Models.ANIME>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Index";
}
<p>
#if (Roles.IsUserInRole("Administrator"))
{
#Html.ActionLink("Create New", "Create")
}
</p>
#foreach (var item in Model) //
{ //
#Html.EditorFor(modelItem => item.GENRES); // I'm not sure about this line
} //
<table>
<tr>
<th>
Anime
</th>
<th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.ActionLink(item.TITLE_OR, "Details", new { id = item.ID_AN })
</td>
</tr>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
When I try to display it with #Html.EditorFor(modelItem => item.GENRES) it displays only genres that are selected within each anime but I need all genres to filter with them. I'm not even sure is this a good way to make it. Any suggestions?

Partial View with self updating

I'm learning ASP.NET MVC and I've encountered a problem in my practice project (MVC Music Store). I have made a partial view to search for an artist. I expect the partial view to take no arguments and work on its own.
Partial view in the right half part
I have a view specific model for the Artist Search Partial View. The model is as follows:
public class ArtistSearch
{
public string SearchString { get; set; }
public List<Artist> SearchResult { get; set; }
public ArtistSearch()
{
SearchResult=new List<Artist>();
}
}
Controller code is as follows:
public ActionResult Search(string query)
{
ArtistSearch asResult = new ArtistSearch();
if (query != null)
{
var temp = from a in db.Artists
where a.Name.Contains(query)
select a;
asResult.SearchResult = temp.ToList();
asResult.SearchString = query;
}
return PartialView(asResult);
}
The Partial View is as follows:
#model MvcMusicStore.Models.ArtistSearch
<div class="big-search-box">
<form action="#Url.Action("Search","Artist")" method="post" role="form">
<div class="input-group">
#Html.TextBox("query", #Model.SearchString, new { #class = "form-control nrb input-lg", placeholder = "Input your search query..." })
<div class="input-group-btn">
<input type="submit" name="Send" value="Search" class="btn btn-primary btn-iconed btn-lg" />
</div>
</div>
</form>
</div>
<div class="big-search-result-info clearfix">
<div class="pull-left">Showing results for <strong>#Model.SearchString</strong>.</div>
<div class="pull-right"><strong>#Model.SearchResult.Count</strong> artist(s) found.</div>
</div>
<table>
#foreach (var item in #Model.SearchResult)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a href="#item.Id" >
<img src=#item.PhotoURL alt=#item.Name style="width:100px;height:70px;">
</a>
</td>
</tr>
}
</table>
I wish to place this partial view anywhere on the site. Lets say i placed it(using RenderAction) on Artist/Index Controllers View page.
The simple functionality that I'm trying to achieve is that when i click on search it should self update the partial view with search results. Right now it is transferring me to Artist/Search page.
Thanks for the patience.
Try to use Ajax.BeginForm, below is an example:
Action
public ActionResult Search(string query)
{
ArtistSearch asResult = new ArtistSearch();
if (query != null)
{
var temp = from a in db.Artists
where a.Name.Contains(query)
select a;
asResult.SearchResult = temp.ToList();
asResult.SearchString = query;
}
return PartialView("MyParitalView",asResult);
}
View
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
#using (Ajax.BeginForm("Search", "Home", new AjaxOptions { UpdateTargetId = "result" }))
{
<div class="input-group">
#Html.TextBox("query", #Model.SearchString, new { #class = "form-control nrb input-lg", placeholder = "Input your search query..." })
<div class="input-group-btn">
<input type="submit" name="Send" value="Search" class="btn btn-primary btn-iconed btn-lg" />
</div>
</div>
}
<div id="result"></div>
Parital View : MyParitalView
#model MvcMusicStore.Models.ArtistSearch
<div class="big-search-result-info clearfix">
<div class="pull-left">Showing results for <strong>#Model.SearchString</strong>.</div>
<div class="pull-right"><strong>#Model.SearchResult.Count</strong> artist(s) found.</div>
</div>
<table>
#foreach (var item in #Model.SearchResult)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<a href="#item.Id">
<img src=#item.PhotoURL alt=#item.Name style="width:100px;height:70px;">
</a>
</td>
</tr>
}
</table>

error when update data to database using checkbox

i try to update my database using checkbox, when i delete data, my code is work. but when i update to add some value to database, i got some error.
**
Cannot insert explicit value for identity column in table 'HotelRoomFacility' when IDENTITY_INSERT is set to OFF.
**
this my code
my service
public void UpdateFacilityInHotel(List<int> FacilityIDs, int RoomTypeID)
{
List<HotelRoomFacility> hotelRoomFacilities = _HotelRoomFacility.AsQueryable().Where(f => f.RoomTypeID == RoomTypeID).ToList();
foreach (int newFacility in FacilityIDs)
{
if (hotelRoomFacilities.Where(h => h.RoomFacilityID == newFacility).Count() == 0)
{
HotelRoomFacility facility = new HotelRoomFacility
{
RoomFacilityID = newFacility,
RoomTypeID = RoomTypeID
};
_HotelRoomFacility.Add(facility);
}
}
foreach (HotelRoomFacility facility in hotelRoomFacilities)
{
if (FacilityIDs.Contains(facility.RoomFacilityID) == false)
_HotelRoomFacility.Delete(facility);
}
_HotelFacilityRepository.CommitChanges();
}
my controller
public ActionResult EditRoom(int RoomTypeID)
{
ViewBag.hotel = _hotelService.GetByID(_HotelID).HotelName;
//var roomType = _hotelService.ShowRoomByID(RoomTypeID);
//return View(roomType);
List<EditRoomTypeViewModel> editRoomTypeViewModel = _showRoomByIDService.ShowRoomByID(RoomTypeID);
return View(editRoomTypeViewModel.FirstOrDefault());
}
[HttpPost]
public ActionResult EditRoom(EditRoomTypeViewModel typeRoom, FormCollection forms)
{
List<string> IDs = forms["FacilityIDs"].Split(',').ToList();
List<int> FacilityIDs = new List<int>();
foreach (string ID in IDs)
{
FacilityIDs.Add(Convert.ToInt32(ID));
}
_showRoomByIDService.UpdateFacilityInHotel(FacilityIDs, _HotelID);
return EditRoom(_HotelID);
var x = _hotelService.UpdateRoom(typeRoom.RoomTypeID, typeRoom.RoomTypeName, typeRoom.RoomTypeDescription);
if (x != null)
{
return RedirectToAction("Room");
}
return View(typeRoom);
}
my view
#model XNet.Repository.Model.EditRoomTypeViewModel
#{
ViewBag.Title = "addRoom";
}
<h2>Edit Room</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Isikan Data</legend>
<div>
#Html.Label("Hotel Name")
</div>
<div>
#ViewBag.hotel
</div>
<br />
<div>
#Html.HiddenFor(model => model.RoomTypeID)
</div>
<br />
<div>
#Html.Label("Room Type Name")
</div>
<div>
#Html.EditorFor(model => model.RoomTypeName)
#Html.ValidationMessageFor(model => model.RoomTypeName)
</div>
<br />
<div>
#Html.Label("Room Type Description")
</div>
<div>
#Html.TextAreaFor(model => model.RoomTypeDescription)
#Html.ValidationMessageFor(model => model.RoomTypeDescription)
</div>
<br />
<table>
<thead>
<tr>
<th>Facility Name</th>
<th> is available</th>
</tr>
</thead>
<tbody>
#foreach (var facility in Model.facilitiesInRoom)
{
<tr>
<td>
#(facility.RoomFacilityName)
</td>
<td style="text-align:center;">
<input type="checkbox" #(facility.RoomFacilityAvailable ? " checked=checked" : null) name="FacilityIDs" value="#facility.RoomFacilityID" />
</td>
</tr>
}
</tbody>
</table>
<br />
<p>
<input type="submit" value="Save" />
<input style="width:100px;" type="button" title="EditHotelDetail" value="Back to Detail" onclick="location.href='#Url.Action("Index", "Hotel") '" />
</p>
</fieldset>
}
Here is the database diagram

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