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
Related
This My Parent View In this i am calling partialview(_CityList.cshtml).
#model MedicalOrbit.City
#{
ViewBag.Title = "CreateCity";
}
<h2>Add City</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div id="Maindiv" class="col-lg-7">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>City Details</h5>
<div class="ibox-tools">
<a class="collapse-link">
<i class="fa fa-chevron-up"></i>
</a>
</div>
</div>
<div class="ibox-content">
<div class="row">
<div class="col-sm-6 b-r">
#*<hr />*#
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
<label>City Name:</label>
#*#Html.LabelFor(model => model.CityName, htmlAttributes: new { #class = "control-label col-md-2" })*#
<br>
<div >
#Html.EditorFor(model => model.CityName, new { htmlAttributes = new { #class = "form-control", placeholder = "Enter City" } })
#Html.ValidationMessageFor(model => model.CityName, "", new { #class = "text-danger" })
</div>
</div>
<br>
<div>
<input type="submit" value="Create" class="btn btn-w-m btn-primary" />
<input type="submit" value="Cancel" class="btn btn-w-m btn-success" />
</div>
</div>
<div>
<div id="CityList" class="col-sm-6">
#*#Html.Partial("_CityList");*#
#Html.Action("CityList", "City")
</div>
</div>
</div>
</div>
</div>
</div>
}
<div id="Editdiv">
#Html.Action("EditCity", "City")
</div>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="~/Scripts/jquery-1.7.1.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
Partial View(_CityList.cshtml)
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.CityName)
</th>
<th>Action</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.CityName)
</td>
<td>
#*#Html.ActionLink("Edit", "Edit", new { id = item.CityID })*#
#Ajax.ActionLink("Edit City", "EditCity", "City", new AjaxOptions()
{
UpdateTargetId = "Maindiv",
InsertionMode = InsertionMode.ReplaceWith
})|
#Html.ActionLink("Details", "Details", new { id = item.CityID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.CityID }) |
#Html.ActionLink("Area", "Area", new { #class = "btn btn-warning btn-circle btn-lg fa fa-times", id = item.CityID })
</td>
</tr>
}
</table>
following is my Controller Code
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Data.Entity.Validation;
using System.Diagnostics;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MedicalOrbit.Controllers
{
public class CityController : Controller
{
MediOrbitDatabaseEntities db = new MediOrbitDatabaseEntities();
// GET: City
public ActionResult Index()
{
return View();
}
public ActionResult CityList()
{
return PartialView("_CityList", db.Cities.Where(x => x.status == false).ToList());
}
public ActionResult CreateCity()
{
return View();
}
// POST: City/CreateCity
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult CreateCity(City city)
{
// TODO: Add insert logic here
if (ModelState.IsValid)
{
city.Users = "ashwini";
city.DateTime = DateTime.UtcNow;
city.status = false;
db.Cities.Add(city);
db.SaveChanges();
return RedirectToAction("CreateCity");
}
return View(city);
}
public ActionResult EditCity(int? id)
{
City city = db.Cities.Where(x => x.CityID == id).FirstOrDefault();
if (city == null)
{
return HttpNotFound();
}
return View(city);
}
// POST: /Admin/City/Edit
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EditCity(City city)
{
if (ModelState.IsValid)
{
city.Users = "Ashwini";
city.DateTime = DateTime.UtcNow;
city.status = false;
db.Entry(city).State = EntityState.Modified;
db.SaveChanges();
RedirectToAction("CreateCity");
}
return PartialView("_EditCity",city);
}
}
}
Now what i want is in _CityList.cshtml partial view when user clicks the edit actionlink then main parent view should be replace with another partial view(_EditCity.cshmtl).how i can achieve this.i m not experience in mvc so plz help me.
I am showing you how to do partial views. Hopefully, you will have enough take away to utilize partial views within partial views, if you want.
There might be extra code to help you.
View:
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>IndexValid4</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript">
$(function () {
$('#LOCATION_NUMBER').click(function () {
var store = $('#storeNbr').val();
this.href = this.href.split("?")[0];
this.href = this.href + '?LOCATION_NUMBER=' + encodeURIComponent(store);
});
})
</script>
</head>
<body>
<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">My Modal</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<label class="btnIEFix">You can also, Click in Grey Area Outside Modal To Close</label>
<button title="You can also, Click in Grey Area Outside Modal To Close" type="button" class="btn btn-secondary bootBtnMargin" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
#Html.HiddenFor(r => r.storeNbr, new { id = "storeNbr" })
#*https://stackoverflow.com/questions/5838273/actionlink-routevalue-from-a-textbox*#
#Ajax.ActionLink(
"Trigger Ajax",
"ReleaseVersion",
null,
new AjaxOptions
{
UpdateTargetId = "result",
InsertionMode = InsertionMode.Replace,
HttpMethod = "GET"
},
new
{
id = "LOCATION_NUMBER"})
<div id="result"></div>
</body>
</html>
Controller:
public class HomeController : Controller
{
public PartialViewResult ReleaseVersion(string LOCATION_NUMBER = "")
{
return PartialView("_ReleaseVersion"); //, model
}
public ActionResult IndexValid4()
{
var storeViewModel = new StoreViewModel { storeNbr = 5 };
return View(storeViewModel);
}
_ReleaseVersion partial view in shared folder:
release version partial view
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);
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?
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>
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.