mvc pagedlist date loses value on second page - c#

I have an Index page with various filtering options on it, all included within a PagedList. They all appear to be working fine, except for the dates.
When I first filter by date, they work fine however when I click on a page number at the bottom, the search criteria for my date is disappearing.
I can see that I can passing the search term in the paged list, and I can see this date hit my controller and the filtering happen but the ViewBag.filterStartDate and ViewBag.filterEndDate just aren't binding back to my textboxes for some reason.
Index.cshtml:
#using PagedList.Mvc
#model PagedList.IPagedList<Job>
#using (Html.BeginForm("Index", "Jobs", FormMethod.Get, new { #class = "form-inline", role = "form" }))
{
<div class="panel panel-default">
<!-- Default panel contents -->
<div class="panel-heading">Filter Search Results</div>
<div class="panel-body">
<ul class="list-group">
<li class="list-group-item">
#Html.Label("By Id: ", new { #class = "col-md-4 control-label" })
#Html.TextBox("filterId", ViewBag.filterId as string, new { #class = "form-control" })
</li>
<li class="list-group-item">
#Html.Label("By Address Line 1: ", new { #class = "col-md-4 control-label" })
#Html.TextBox("filterAddress1", ViewBag.filterAddress1 as string, new { #class = "form-control" })
</li>
<li class="list-group-item">
#Html.Label("By Username: ", new { #class = "col-md-4 control-label" })
#Html.TextBox("filterUsername", ViewBag.filterUsername as string, new { #class = "form-control" })
</li>
<li class="list-group-item">
#Html.Label("By Contract: ", new { #class = "col-md-4 control-label" })
#Html.DropDownList("filterContract", null, "-- Select One --",
new { #class = "form-control" })
</li>
<li class="list-group-item">
#Html.Label("Date Created Start: ", new { #class = "col-md-4 control-label" })
#Html.TextBox("filterStartDate", ViewBag.filterStartDate as string, new { #class = "form-control date", type = "date" })
</li>
<li class="list-group-item">
#Html.Label("Date Created End: ", new { #class = "col-md-4 control-label" })
#Html.TextBox("filterFinishDate", ViewBag.filterFinishDate as string, new { #class = "form-control date", type = "date" })
</li>
<li class="list-group-item">
#Html.Label("By App: ", new { #class = "col-md-4 control-label" })
#Html.DropDownList("filterApp", null, "-- Select One --",
new { #class = "form-control" })
</li>
</ul>
<input type="submit" value="Apply Filter" class="btn btn-default" />
</div>
<div id="items" style="padding: 15px;">
#Html.Partial("Jobs", Model)
</div>
</div>
}
Jobs.cshtml:
#using System.Web.UI.WebControls
#using PagedList.Mvc
#model PagedList.IPagedList<Job>
#Html.ActionLink("Create New", "Create", null, new { #style = "float: left" })
#Html.ActionLink("Import Jobs", "Import", null, new { #style = "padding-left: 15px" })
#Html.ValidationSummary(true)
<table class="table">
<tr>
<th class="mobileview">
#Html.DisplayName("JobId")
</th>
<th>
#Html.DisplayName("Description")
</th>
<th class="mobileview">
#Html.DisplayName("Address")
</th>
<th class="mobileview">
#Html.DisplayName("Priority")
</th>
<th>
#Html.DisplayName("Date Created")
</th>
<th>
#Html.DisplayName("Username")
</th>
</tr>
#foreach (var item in Model)
{
<tr class="formrow">
<td class="mobileview">
#Html.DisplayFor(modelItem => item.JobId)
</td>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td class="mobileview">
#Html.DisplayFor(modelItem => item.Address1)
</td>
<td class="mobileview">
#Html.DisplayFor(modelItem => item.Priority)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateCreated)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.UserName)
</td>
<td class="mobileview">
#Html.ActionLink("View Job", "Details", new { id = item.JobId })
</td>
<td class="mobileview">
#if (item.Data != null)
{
#Html.ActionLink("View Data", "Details", "AppForms", new { id = item.Data.Id }, null)
}
else
{
#Html.DisplayFor(modelItem => item.Status)
}
</td>
</tr>
}
</table>
<p>Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount</p>
#Html.PagedListPager(Model, page => Url.Action("Index", new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter, filterAddress1 = ViewBag.filterAddress1, filterId = ViewBag.filterId, filterUsername = ViewBag.filterUsername, filterStartDate = ViewBag.filterStartDate, filterFinishDate = ViewBag.filterFinishDate, filterApp = ViewBag.selectedApp, filterContract = ViewBag.selectedContract }), PagedListRenderOptions.Classic)
JobsController.cs:
public ActionResult Index(string sortOrder, string currentFilter, string filterId, string filterAddress1, int? page, String filterApp, String filterContract, DateTime? filterStartDate, DateTime? filterFinishDate, String filterUsername)
{
//...Other filtering
//Filter by date
if (filterStartDate != null)
{
jobs = jobs.Where(x => x.DateCreated >= filterStartDate);
//ViewBag.filterStartDate = filterStartDate.Value.Year + "-" + filterStartDate.Value.Month + "-" + filterStartDate.Value.Day;
ViewBag.filterStartDate = filterStartDate;
}
if (filterFinishDate != null)
{
//Make sure we're checking to the end of the end date (ie 01/01/2015 23:59:59)
filterFinishDate = filterFinishDate.Value.AddHours(23).AddMinutes(59).AddSeconds(59);
jobs = jobs.Where(x => x.DateCreated <= filterFinishDate);
//ViewBag.filterFinishDate = filterFinishDate.Value.Year + "-" + filterFinishDate.Value.Month + "-" + filterFinishDate.Value.Day;
ViewBag.filterFinishDate = filterFinishDate;
}
int pageSize = int.Parse(ConfigurationManager.AppSettings["MaxPageItemCount"]);
int pageNumber = page ?? 1;
return this.View(jobs.ToPagedList(pageNumber, pageSize));
}

#Html.TextBox() can pull values out of the ModelState or ViewData.
Try building the html for the date input manually like this:
<input type="date" name="filterStartDate" id="filterStartDate" class="form-control date" value="#ViewBag.filterStartDate.ToString("yyyy-MM-dd")"/>

Resolved the issue by manually creating the date inputs rather tahn relying on Razor to do it for me!
#if (ViewBag.filterStartDate != null)
{
<input type="date" name="filterStartDate" id="filterStartDate" value="#ViewBag.filterStartDate.ToString("yyyy-MM-dd")" />
}
else
{
<input type="date" name="filterStartDate" id="filterStartDate" value="" />
}

Related

How to use pagedlist with post method

I have a question about PagedList. I have a grid of data that I can filter using dropdownlist and checkbox. It works well. I use "PagedList", which allows me to display only 10 row per page in my grid of data. It works well when I don't use filter. When I select an item in my dropdownlist for example, the filter works well in the first page but if I click on the 2nd page the filter doesn't work anymore. To filter data, I use method Post and ViewModel. What can I do?
Thanks!
Here is my view:
#using (Html.BeginForm("Index", "Missions", FormMethod.Post))
{
<section>
<h3>Localisation</h3>
#*
<div class="form-group">
#Html.LabelFor(model => model.DirGeoSelected, "Direction geo", htmlAttributes: new { #class = "control-label col-md-8" })
<div class="col-md-4">
#Html.DropDownListFor(model => model.DirGeoSelected, Model.DirGeoList, htmlAttributes: new { onchange = "form.submit();", #class = "form-control" })
#Html.ValidationMessageFor(model => model.DirGeoSelected, "", new { #class = "text-danger" })
</div>
</div>
*#
<div class="form-group">
#Html.LabelFor(model => model.ProgrammeIdSelected, "Programme", htmlAttributes: new { #class = "control-label col-md-5" })
<div class="col-md-7">
#Html.DropDownListFor(model => model.ProgrammeIdSelected, Model.Programme, "All", htmlAttributes: new { onchange = "form.submit();", #class = "form-control" })
#Html.ValidationMessageFor(model => model.ProgrammeIdSelected, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CountryIdSelected, "Pays", htmlAttributes: new { #class = "control-label col-md-5" })
<div class="col-md-7">
#Html.DropDownListFor(model => model.CountryIdSelected, Model.Country, "All", htmlAttributes: new { onchange = "form.submit();", #class = "form-control"/*, data_url = Url.Action("GetCountries")*/ })
#Html.ValidationMessageFor(model => model.CountryIdSelected, "", new { #class = "text-danger" })
</div>
</div>
</section>
<section>
<h3>Personne</h3>
</section>
<section>
#*
<h3>Date</h3>
<div class="form-group">
<div class="col-md-8">
#Html.TextBox("SelectedDateStart", new {#class = "datepicker"})
</div>
</div>
<div class="form-group">
<div class="col-md-8">
#Html.TextBox("SelectedDateEnd", new { #class = "datepicker"})
</div>
</div>
*#
</section>
<section>
<h3>Type</h3>
<div class="col-md-12 form-check">
#Html.CheckBox("Support", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Mission Support", htmlAttributes: new { #class = "control-label" })
#Html.CheckBox("Autre", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Autre", htmlAttributes: new { #class = "control-label" })
</div>
</section>
<section>
<h3>Priority</h3>
<div class="col-md-12 form-check">
#Html.CheckBox("Support", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Mission Support", htmlAttributes: new { #class = "control-label" })
#Html.CheckBox("Autre", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Autre", htmlAttributes: new { #class = "control-label" })
</div>
</section>
<section>
<h3>Décision</h3>
<div class="col-md-12">
#Html.EditorFor(x => x.Decison)
</div>
</section>
<section>
<h3>Equipe</h3>
#*
<div class="form-group">
#Html.LabelFor(model => model.DirectionIdSelected, "Direction", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.DropDownListFor(model => model.DirectionIdSelected, Model.DirectionList, htmlAttributes: new { onchange = "form.submit();", #class = "form-control" })
#Html.ValidationMessageFor(model => model.DirectionIdSelected, "", new { #class = "text-danger" })
</div>
</div>
*#
</section>
}
</nav>
<div id="content" class="container">
<h2>Missions</h2>
#* #using (Html.BeginForm("Index", "Missions", FormMethod.Get))
{
#Html.TextBox("searching")
<input type="submit" value="submit" />
}
*#
<p class="newmission">
<input type="button" class="btn btn-info" value="Nouvelle Mission" onclick="location.href='#Url.Action("Create", "Missions")'" />
</p>
<table class="table table-bordered">
<tr>
<th class="col-md-2">
#Html.ActionLink("Pays", "Index",
new { SortOrder = Model.SortCountry})
</th>
<th class="col-md-1">
#Html.ActionLink("Date", "Index",
new { SortOrder = ViewBag.ListorderDate,
/*SelectedDesk = ViewBag.ListorderPays,
SelectedProgramme = ViewBag.ListorderDate,*/
})
</th>
<th class="col-md-2">
Personne
</th>
<th class="col-md-10">
Missions
</th>
<th class="col-md-10">
</th>
</tr>
#foreach (var item in Model.OnePageOfMissions)
{
<tr>
<td class="col-md-1">
#Html.DisplayFor(modelItem => item.decision)
</td>
<td class="col-md-2">
#Html.DisplayFor(modelItem => item.organization_hi_country.name_en)
</td>
<td class="col-md-1">
#Html.DisplayFor(modelItem => item.asked_date)
</td>
<td class="col-md-2"></td>
<td class="col-md-10">
<span class="typemission">Mission</span> #Html.DisplayFor(modelItem => item.list_type.name_en, new { #class = "typemission" }) : #Html.DisplayFor(modelItem => item.list_nature.name_en, new { #class = "typemission" })
<div>
<!-- les boutons d'actions -->
details
</div>
<!-- le contenu masqué -->
<section id="#Html.DisplayFor(modelItem => item.id)" class="collapse">
<div class="well">
<p><em>Statut: </em>#Html.DisplayFor(modelItem => item.list_statut.name_en)</p>
<p><em>Durée: </em>#Html.DisplayFor(modelItem => item.duration) jours</p>
<p><em>Flexibilité: </em>#Html.DisplayFor(modelItem => item.list_flexibility.name_en) </p>
<p><em>Priorité: </em>#Html.DisplayFor(modelItem => item.list_priority.name_en) </p>
<p><em>Commentaires: </em>#Html.DisplayFor(modelItem => item.comments) </p>
</div>
</section>
</td>
<td class="col-md-10">
#Html.ActionLink("Edit", "Create", new { id = item.id })
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
#Html.PagedListPager((IPagedList)Model.OnePageOfMissions, page => Url.Action("Index", new { searchItem = ViewBag.searchItem, page }))
</table>
Here is my controller:
namespace MissionsDF.Controllers
{
public class MissionsController : Controller
{
private Missions_devEntities db = new Missions_devEntities();
// GET: /Missions/
public ActionResult Index(string SortOrder, int? page)
{
IndexViewModel model = new IndexViewModel();
//Affichage de la liste des Programmes
model.Programme = GetProgrammes();
//Tri des pays:
model.SortCountry = String.IsNullOrEmpty(SortOrder) ? "ListorderPays_desc" : "";
model.missionsList = db.missions_supportmission.ToList();
switch (SortOrder)
{
case "ListorderPays_desc":
model.missionsList = model.missionsList.OrderByDescending(s => s.organization_hi_country.name_en);
break;
default:
model.missionsList = model.missionsList.OrderBy(s => s.organization_hi_country.name_en);
break;
}
//Pagination
var pageNumber = page ?? 1; // if no page was specified in the querystring, default to the first page (1)
var onePageOfMissions = model.missionsList.ToPagedList(pageNumber, 10); // will only contain 10 products max because of the pageSize(equel to 10)
model.OnePageOfMissions = onePageOfMissions;
//Ischecked
var allDecisions = db.list_decision.ToList();//returns List<list_decision>
var checkBoxListItems = new List<CheckBoxListItem>(); //nouvelle instance de la classe checkboxlist
foreach (var decison in allDecisions)
{//On assigne les valeurs "id", "display" et "is checked" à la variable checkboxlistitem
checkBoxListItems.Add(new CheckBoxListItem()
{
ID = decison.decision_id,
Display = decison.name_en,
IsChecked = false //On the add view, no decision are selected by default
});
}
model.Decison = checkBoxListItems;
return View(model);
}
private List<SelectListItem> GetProgrammes()
{
return db.organization_programme
.Select(x => new SelectListItem
{
Value = x.prog_id,
Text = x.name_en
})
.ToList();
}
//POST: /Missions/Index
[HttpPost]
public ActionResult Index(IndexViewModel model, int? page)
{
//Filtres sur Programme et Country
if (ModelState.IsValid)
{
var pageNumber = page ?? 1;
var selecteddecision = model.Decison.Where(x => x.IsChecked).Select(x => x.ID);
//Si selecteddecision n'est pas null
//Si Programme n'est pas null et que country est null
if (!(selecteddecision.IsAny()))
{
if (!String.IsNullOrEmpty(model.ProgrammeIdSelected) && String.IsNullOrEmpty(model.CountryIdSelected))
{
var onePageOfMissions = db.missions_supportmission
.Where(a => a.programme_id == model.ProgrammeIdSelected)
.OrderBy(a => a.programme_id)
.Select(s => s).ToPagedList(pageNumber, 10);
model.OnePageOfMissions = onePageOfMissions;
}
//Si Country est null
else if (!String.IsNullOrEmpty(model.CountryIdSelected))
{
model.OnePageOfMissions = db.missions_supportmission
.Where(a => a.country_id == model.CountryIdSelected)
.OrderBy(a => a.country_id)
.Select(s => s).ToPagedList(pageNumber, 10);
if (model.missionsList != null)
{
var onePageOfMissions = model.missionsList.ToPagedList(pageNumber, 10);
model.OnePageOfMissions = onePageOfMissions;
}
}
//Sinon on affiche tout
else
{
model.OnePageOfMissions = db.missions_supportmission
.OrderBy(a => a.programme_id)
.Select(s => s).ToPagedList(pageNumber, 10);
}
}
else
{
foreach (var item in selecteddecision)
{
//Si Programme n'est pas null et que country est null
if (!String.IsNullOrEmpty(model.ProgrammeIdSelected) && String.IsNullOrEmpty(model.CountryIdSelected))
{
model.OnePageOfMissions = db.missions_supportmission
.Where(a => a.programme_id == model.ProgrammeIdSelected)
.Where(a => a.decision == item)
.OrderBy(a => a.programme_id)
.Select(s => s).ToPagedList(pageNumber, 10);
var onePageOfMissions = model.missionsList.ToPagedList(pageNumber, 10);
model.OnePageOfMissions = onePageOfMissions;
}
//Si Country est null
else if (!String.IsNullOrEmpty(model.CountryIdSelected))
{
model.OnePageOfMissions = db.missions_supportmission
.Where(a => a.country_id == model.CountryIdSelected)
.Where(a => a.decision == item)
.OrderBy(a => a.country_id)
.Select(s => s).ToPagedList(pageNumber, 10);
var onePageOfMissions = model.missionsList.ToPagedList(pageNumber, 10);
model.OnePageOfMissions = onePageOfMissions;
}
//Sinon on affiche tout
else
{
model.OnePageOfMissions = db.missions_supportmission
.Where(a => a.decision == item)
.OrderBy(a => a.programme_id)
.Select(s => s).ToPagedList(pageNumber, 10);
}
}
}
}
var allDecisions = db.list_decision.ToList();//returns List<list_decision>
var checkBoxListItems = new List<CheckBoxListItem>(); //nouvelle instance de la classe checkboxlist
foreach (var decison in allDecisions)
{//On assigne les valeurs "id", "display" et "is checked" à la variable checkboxlistitem
checkBoxListItems.Add(new CheckBoxListItem()
{
ID = decison.decision_id,
Display = decison.name_en,
});
}
model.Decison = checkBoxListItems;
//Affichage en cascade liste de programmes + liste pays
model.Programme = GetProgrammes();
model.Country = db.organization_hi_country
.Where(a => a.prog_id == model.ProgrammeIdSelected)
.Select(x => new SelectListItem
{
Value = x.country_id,
Text = x.name_en
}).ToList();
return View(model);
}
1) If you are willing to revamp and modify your code both server side and client-side, I recommend following instructions mentioned at this tutorial
2) In case you want to use Post method then, following changes may help you:
In your server side code, wherever you are assigning an object to 'ViewBag.searchItem', try using TempData["searchItem"] in place of it. And when accessing it on View page, also use TempData["searchItem"] wherever you are accessing 'ViewBag.searchItem' with appropriate casting.
While I suppose your server side code is working, client side html may work as shown below, with form tag wrapped around entire HTML..
#using (Html.BeginForm("Index", "Missions", FormMethod.Post))
{
<section>
<h3>Localisation</h3>
#*
<div class="form-group">
#Html.LabelFor(model => model.DirGeoSelected, "Direction geo", htmlAttributes: new { #class = "control-label col-md-8" })
<div class="col-md-4">
#Html.DropDownListFor(model => model.DirGeoSelected, Model.DirGeoList, htmlAttributes: new { onchange = "form.submit();", #class = "form-control" })
#Html.ValidationMessageFor(model => model.DirGeoSelected, "", new { #class = "text-danger" })
</div>
</div>
*#
<div class="form-group">
#Html.LabelFor(model => model.ProgrammeIdSelected, "Programme", htmlAttributes: new { #class = "control-label col-md-5" })
<div class="col-md-7">
#Html.DropDownListFor(model => model.ProgrammeIdSelected, Model.Programme, "All", htmlAttributes: new { onchange = "form.submit();", #class = "form-control" })
#Html.ValidationMessageFor(model => model.ProgrammeIdSelected, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CountryIdSelected, "Pays", htmlAttributes: new { #class = "control-label col-md-5" })
<div class="col-md-7">
#Html.DropDownListFor(model => model.CountryIdSelected, Model.Country, "All", htmlAttributes: new { onchange = "form.submit();", #class = "form-control"/*, data_url = Url.Action("GetCountries")*/ })
#Html.ValidationMessageFor(model => model.CountryIdSelected, "", new { #class = "text-danger" })
</div>
</div>
</section>
<section>
<h3>Personne</h3>
</section>
<section>
#*
<h3>Date</h3>
<div class="form-group">
<div class="col-md-8">
#Html.TextBox("SelectedDateStart", new {#class = "datepicker"})
</div>
</div>
<div class="form-group">
<div class="col-md-8">
#Html.TextBox("SelectedDateEnd", new { #class = "datepicker"})
</div>
</div>
*#
</section>
<section>
<h3>Type</h3>
<div class="col-md-12 form-check">
#Html.CheckBox("Support", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Mission Support", htmlAttributes: new { #class = "control-label" })
#Html.CheckBox("Autre", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Autre", htmlAttributes: new { #class = "control-label" })
</div>
</section>
<section>
<h3>Priority</h3>
<div class="col-md-12 form-check">
#Html.CheckBox("Support", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Mission Support", htmlAttributes: new { #class = "control-label" })
#Html.CheckBox("Autre", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Autre", htmlAttributes: new { #class = "control-label" })
</div>
</section>
<section>
<h3>Décision</h3>
<div class="col-md-12">
#Html.EditorFor(x => x.Decison)
</div>
</section>
<section>
<h3>Equipe</h3>
#*
<div class="form-group">
#Html.LabelFor(model => model.DirectionIdSelected, "Direction", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.DropDownListFor(model => model.DirectionIdSelected, Model.DirectionList, htmlAttributes: new { onchange = "form.submit();", #class = "form-control" })
#Html.ValidationMessageFor(model => model.DirectionIdSelected, "", new { #class = "text-danger" })
</div>
</div>
*#
</section> <div id="content" class="container">
<h2>Missions</h2>
<p class="newmission">
<input type="button" class="btn btn-info" value="Nouvelle Mission" onclick="location.href='#Url.Action("Create", "Missions")'" />
</p>
<table class="table table-bordered">
<tr>
<th class="col-md-2">
#Html.ActionLink("Pays", "Index",
new { SortOrder = Model.SortCountry})
</th>
<th class="col-md-1">
#Html.ActionLink("Date", "Index",
new { SortOrder = ViewBag.ListorderDate,
/*SelectedDesk = ViewBag.ListorderPays,
SelectedProgramme = ViewBag.ListorderDate,*/
})
</th>
<th class="col-md-2">
Personne
</th>
<th class="col-md-10">
Missions
</th>
<th class="col-md-10">
</th>
</tr>
#foreach (var item in Model.OnePageOfMissions)
{
<tr>
<td class="col-md-1">
#Html.DisplayFor(modelItem => item.decision)
</td>
<td class="col-md-2">
#Html.DisplayFor(modelItem => item.organization_hi_country.name_en)
</td>
<td class="col-md-1">
#Html.DisplayFor(modelItem => item.asked_date)
</td>
<td class="col-md-2"></td>
<td class="col-md-10">
<span class="typemission">Mission</span> #Html.DisplayFor(modelItem => item.list_type.name_en, new { #class = "typemission" }) : #Html.DisplayFor(modelItem => item.list_nature.name_en, new { #class = "typemission" })
<div>
<!-- les boutons d'actions -->
details
</div>
<!-- le contenu masqué -->
<section id="#Html.DisplayFor(modelItem => item.id)" class="collapse">
<div class="well">
<p><em>Statut: </em>#Html.DisplayFor(modelItem => item.list_statut.name_en)</p>
<p><em>Durée: </em>#Html.DisplayFor(modelItem => item.duration) jours</p>
<p><em>Flexibilité: </em>#Html.DisplayFor(modelItem => item.list_flexibility.name_en) </p>
<p><em>Priorité: </em>#Html.DisplayFor(modelItem => item.list_priority.name_en) </p>
<p><em>Commentaires: </em>#Html.DisplayFor(modelItem => item.comments) </p>
</div>
</section>
</td>
<td class="col-md-10">
#Html.ActionLink("Edit", "Create", new { id = item.id })
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
#Html.PagedListPager((IPagedList)Model.OnePageOfMissions, page => Url.Action("Index", new { page }))
</table>}
Thanks, I found the solution. I decided to use only get method.
In my controller I have this:
public ActionResult Index(string SortOrder, int? page, string ProgrammeIdSelected)
{
IndexViewModel model = new IndexViewModel();
//Affichage de la liste des Programmes
model.Programme = GetProgrammes();
//Tri des pays:
model.SortCountry = String.IsNullOrEmpty(SortOrder) ? "ListorderPays_desc" : "";
model.ProgrammeIdSelected = ProgrammeIdSelected;
model.missionsList = db.missions_supportmission.ToList();
switch (SortOrder)
{
case "ListorderPays_desc":
model.missionsList = model.missionsList.OrderByDescending(s => s.organization_hi_country.name_en);
break;
default:
model.missionsList = model.missionsList.OrderBy(s => s.organization_hi_country.name_en);
break;
}
//Pagination
var pageNumber = page ?? 1; // if no page was specified in the querystring, default to the first page (1)
var onePageOfMissions = model.missionsList.ToPagedList(pageNumber, 10); // will only contain 10 products max because of the pageSize(equel to 10)
model.OnePageOfMissions = onePageOfMissions;
//Ischecked
var allDecisions = db.list_decision.ToList();//returns List<list_decision>
var checkBoxListItems = new List<CheckBoxListItem>(); //nouvelle instance de la classe checkboxlist
foreach (var decison in allDecisions)
{//On assigne les valeurs "id", "display" et "is checked" à la variable checkboxlistitem
checkBoxListItems.Add(new CheckBoxListItem()
{
ID = decison.decision_id,
Display = decison.name_en,
IsChecked = false //On the add view, no decision are selected by default
});
}
//Si Programme n'est pas null et que country est null
if (!String.IsNullOrEmpty(ProgrammeIdSelected))
{
model.OnePageOfMissions = db.missions_supportmission
.Where(a => a.programme_id == ProgrammeIdSelected)
.OrderBy(a => a.programme_id)
.Select(s => s).ToPagedList(pageNumber, 10);
}
return View(model);
}
An d in my View I have this:
#using (Html.BeginForm("Index", "Missions", FormMethod.Get))
{
<section>
<h3>Localisation</h3>
#*
<div class="form-group">
#Html.LabelFor(model => model.DirGeoSelected, "Direction geo", htmlAttributes: new { #class = "control-label col-md-8" })
<div class="col-md-4">
#Html.DropDownListFor(model => model.DirGeoSelected, Model.DirGeoList, htmlAttributes: new { onchange = "form.submit();", #class = "form-control" })
#Html.ValidationMessageFor(model => model.DirGeoSelected, "", new { #class = "text-danger" })
</div>
</div>
*#
<div class="form-group">
#Html.LabelFor(model => model.ProgrammeIdSelected, "Programme", htmlAttributes: new { #class = "control-label col-md-5" })
<div class="col-md-7">
#Html.DropDownListFor(model => model.ProgrammeIdSelected, Model.Programme, "All", htmlAttributes: new {onchange = "form.submit();", #class = "form-control"})
#Html.ValidationMessageFor(model => model.ProgrammeIdSelected, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.CountryIdSelected, "Pays", htmlAttributes: new { #class = "control-label col-md-5" })
<div class="col-md-7">
#Html.DropDownListFor(model => model.CountryIdSelected, Model.Country, "All", htmlAttributes: new { onchange = "form.submit();", #class = "form-control"/*, data_url = Url.Action("GetCountries")*/ })
#Html.ValidationMessageFor(model => model.CountryIdSelected, "", new { #class = "text-danger" })
</div>
</div>
</section>
<section>
<h3>Personne</h3>
</section>
<section>
#*
<h3>Date</h3>
<div class="form-group">
<div class="col-md-8">
#Html.TextBox("SelectedDateStart", new {#class = "datepicker"})
</div>
</div>
<div class="form-group">
<div class="col-md-8">
#Html.TextBox("SelectedDateEnd", new { #class = "datepicker"})
</div>
</div>
*#
</section>
<section>
<h3>Type</h3>
<div class="col-md-12 form-check">
#Html.CheckBox("Support", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Mission Support", htmlAttributes: new { #class = "control-label" })
#Html.CheckBox("Autre", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Autre", htmlAttributes: new { #class = "control-label" })
</div>
</section>
<section>
<h3>Priority</h3>
<div class="col-md-12 form-check">
#Html.CheckBox("Support", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Mission Support", htmlAttributes: new { #class = "control-label" })
#Html.CheckBox("Autre", true, new { onchange = "form.submit();", #class = "form-check-input" })
#Html.Label("Autre", htmlAttributes: new { #class = "control-label" })
</div>
</section>
<section>
<h3>Décision</h3>
<div class="col-md-12">
#Html.EditorFor(x => x.Decison)
</div>
</section>
<section>
<h3>Equipe</h3>
#*
<div class="form-group">
#Html.LabelFor(model => model.DirectionIdSelected, "Direction", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-8">
#Html.DropDownListFor(model => model.DirectionIdSelected, Model.DirectionList, htmlAttributes: new { onchange = "form.submit();", #class = "form-control" })
#Html.ValidationMessageFor(model => model.DirectionIdSelected, "", new { #class = "text-danger" })
</div>
</div>
*#
</section>
}
</nav>
<div id="content" class="container">
<h2>Missions</h2>
#* #using (Html.BeginForm("Index", "Missions", FormMethod.Get))
{
#Html.TextBox("searching")
<input type="submit" value="submit" />
}
*#
<p class="newmission">
<input type="button" class="btn btn-info" value="Nouvelle Mission" onclick="location.href='#Url.Action("Create", "Missions")'" />
</p>
<table class="table table-bordered">
<tr>
<th class="col-md-2">
#Html.ActionLink("Pays", "Index",
new { SortOrder = Model.SortCountry})
</th>
<th class="col-md-1">
#Html.ActionLink("Date", "Index",
new { SortOrder = ViewBag.ListorderDate,
/*SelectedDesk = ViewBag.ListorderPays,
SelectedProgramme = ViewBag.ListorderDate,*/
})
</th>
<th class="col-md-2">
Personne
</th>
<th class="col-md-10">
Missions
</th>
<th class="col-md-10">
</th>
</tr>
#foreach (var item in Model.OnePageOfMissions)
{
<tr>
<td class="col-md-1">
#Html.DisplayFor(modelItem => item.decision)
</td>
<td class="col-md-2">
#Html.DisplayFor(modelItem => item.organization_hi_country.name_en)
</td>
<td class="col-md-1">
#Html.DisplayFor(modelItem => item.asked_date)
</td>
<td class="col-md-2"></td>
<td class="col-md-10">
<span class="typemission">Mission</span> #Html.DisplayFor(modelItem => item.list_type.name_en, new { #class = "typemission" }) : #Html.DisplayFor(modelItem => item.list_nature.name_en, new { #class = "typemission" })
<div>
<!-- les boutons d'actions -->
details
</div>
<!-- le contenu masqué -->
<section id="#Html.DisplayFor(modelItem => item.id)" class="collapse">
<div class="well">
<p><em>Statut: </em>#Html.DisplayFor(modelItem => item.list_statut.name_en)</p>
<p><em>Durée: </em>#Html.DisplayFor(modelItem => item.duration) jours</p>
<p><em>Flexibilité: </em>#Html.DisplayFor(modelItem => item.list_flexibility.name_en) </p>
<p><em>Priorité: </em>#Html.DisplayFor(modelItem => item.list_priority.name_en) </p>
<p><em>Commentaires: </em>#Html.DisplayFor(modelItem => item.comments) </p>
</div>
</section>
</td>
<td class="col-md-10">
#Html.ActionLink("Edit", "Create", new { id = item.id })
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
#Html.PagedListPager((IPagedList)Model.OnePageOfMissions, page => Url.Action("Index", new { page, ProgrammeIdSelected = Model.ProgrammeIdSelected }))
</table>

I can't fill data by dropdownlist change event for dynamically created textboxes in asp.net mvc 5

I have got a problem as follows:
I have created a table with dynamic rows by clicking "add button".A row includes some textboxes and one dropdown list. When I select a value from dropdown list as a term to automatically fill for other textboxes by data I get from the server. Now I just can apply for the first row.I don't know how to apply for the new row when click "add button".Please help me how to solve this problem. Thanks a lot.
This is my webpage
This is my controller code:
using Phieu90.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace Phieu90.Controllers
{
public class XuLyPhieuController : Controller
{
XuLyPhieu90Entities1 db;
public XuLyPhieuController()
{
db = new XuLyPhieu90Entities1();
}
public ActionResult Index()
{
var lislinhkien = new SelectList(db.PA_LINHKIEN.ToList(), "ITEM_CODE", "ITEM_CODE");
ViewBag.LinhKien = lislinhkien;
List<PA_CHITIETPHIEU> listchitiet = new List<PA_CHITIETPHIEU> { new PA_CHITIETPHIEU { NHACUNGCAP = "", TENSP = "", MASP = "", MADUTOAN = "", SOLUONG = 0, DONVI = "", DONGIA = 0, SOTIEN = 0 } };
return View(listchitiet);
}
[HttpPost]
public JsonResult GetLinhKien(string Prefix)
{
var result = db.PA_LINHKIEN.SingleOrDefault(x => x.ITEM_CODE == Prefix);
return Json(result, JsonRequestBehavior.AllowGet);
}
}
}
This is my View:
<body>
<h2 style="text-align:center;margin-top:50px;margin-bottom:50px;">Bill Detail</h2>
#using (Html.BeginForm("PhieuMuaLinhKien", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div>Add New Row <i class="fas fa-plus-circle"></i></div>
<table id="dataTable" border="0" cellpadding="0" cellspacing="0" class="table table-bordered">
<tr>
<th class="title">Bill ID</th>
<th class="title">Supplier</th>
<th class="title">Item name</th>
<th class="title">Item code</th>
<th class="title">Reference code</th>
<th class="title">Quantity</th>
<th class="title">Unit</th>
<th class="title">Price</th>
<th class="title">Sum</th>
<th class="title">Delete</th>
</tr>
#if (Model != null && Model.Count > 0)
{
int j = 0;
foreach (var i in Model)
{
<tr style="border:1px solid black">
<td class="title">#Html.TextBoxFor(a => a[j].MACHITIET, new { #class = "form-control", #style = "width:120px;margin-left:12px;", #required = "required" })</td>
<td class="title">#Html.TextBoxFor(a => a[j].NHACUNGCAP, new { #class = "form-control", #style = "width:120px;margin-left:12px;", #required = "required", #id = "txtncc" })</td>
<td class="title">#Html.TextBoxFor(a => a[j].TENSP, new { #class = "form-control", #style = "width:120px;margin-left:12px;", #required = "required",#id= "txttensp" })</td>
#using (Html.BeginForm())
{
#*<td class="title">#Html.TextBoxFor(a => a[j].MASP, new { #class = "form-control view-data", #style = "width:120px;margin-left:12px;", #required = "required"})</td>*#
<td>#Html.DropDownListFor(a => a[j].MASP, ViewBag.LinhKien as SelectList, "--*--", new { #class = "form-control view-data", #style = "width:120px;margin-left:12px;", #required = "required",#id="ddllinhkien" })</td>
}
<td class="title">#Html.TextBoxFor(a => a[j].MADUTOAN, new { #class = "form-control", #style = "width:120px;margin-left:12px;", #required = "required" })</td>
<td class="title">#Html.TextBoxFor(a => a[j].SOLUONG, new { #class = "form-control", #style = "width:120px;margin-left:12px;", #required = "required" })</td>
<td class="title">#Html.TextBoxFor(a => a[j].DONVI, new { #class = "form-control", #style = "width:120px;margin-left:12px;", #required = "required" })</td>
<td class="title">#Html.TextBoxFor(a => a[j].DONGIA, new { #class = "form-control", #style = "width:120px;margin-left:12px;", #required = "required", #id = "txtdongia" })</td>
<td class="title">#Html.TextBoxFor(a => a[j].SOTIEN, new { #class = "form-control", #style = "width:120px;margin-left:12px;", #required = "required" })</td>
<td>
#if (j > 0)
{
Remove <i class="fas fa-trash"></i>
}
</td>
</tr>
j++;
}
}
</table>
}
<div style="margin-left:660px;margin-top:30px;">
<button type="submit" class="btn btn-primary" id="btnSubmit" style="">Save <i class="fas fa-save"></i></button>
</div>
enter code here
<script type="text/javascript">
$(document).ready(function () {
//1. Add new row
$("#addNew").click(function (e) {
e.preventDefault();
var $tableBody = $("#dataTable");
var $trLast = $tableBody.find("tr:last");
var $trNew = $trLast.clone().insertAfter($trLast);
var suffix = $trNew.find(':input:first').attr('name').match(/\d+/);
$trNew.find("td:last").html('<a href="#" class="btn btn-block btn-
danger remove">Xóa <i class="fas fa-trash"></i></a>');
$.each($trNew.find(':input'), function (i, val) {
// Replaced Name
var oldN = $(this).attr('name');
var newN = oldN.replace('[' + suffix + ']', '[' +
(parseInt(suffix) + 1) + ']');
$(this).attr('name', newN);
$(this).attr('id', newN);
//Replaced value
var type = $(this).attr('type');
if (type.toLowerCase() == "text") {
$(this).attr('value', '');
}
$(this).removeClass("input-validation-error");
});
$trLast.after($trNew);
var form = $("form")
.removeData("validator")
.removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse(form);
});
//2. Remove
//$('a.remove').on("click", function (e) {
// e.preventDefault();
// $(this).parent().parent().remove();
//});
$("#dataTable").on("click", ".remove", function () {
$(this).closest('tr').remove();
});
$('.view-data').change(function () {
var malk = $(this).val();
$.ajax({
url: "/XuLyPhieu/GetLinhKien",
type: "POST",
dataType: "json",
data: { Prefix: malk },
success: function (data) {
//do something
})
}
})
})
});

Multiple Models Update POST method does not work in MVC

I've this Update ActionResult and It does not work as it should be because it does not get the Id values from PartialView on button click as of that on saveChange code breaks
Here is my Method and Let me explain the method:
This method is receiving two models at the same time One is from the Main View and the second from PartialView and the model in PartialView is of type List. In case of save they work perfect but not in the case of update
[HttpPost]
public ActionResult ManpowerEdit(ViewModelsManpowerEdit model, int projectId)
{
db.Configuration.ProxyCreationEnabled = false;
var manpower = db.PMCManpowerRequests.Find(model.ModelManpowerRequestEdit.Id);
int id = model.ModelManpowerRequestEdit.Id;
manpower.ProjectId = projectId;
manpower.JobNo = model.ModelManpowerRequestEdit.JobNo;
manpower.RequestDate = model.ModelManpowerRequestEdit.RequestDate;
db.Entry(manpower).State = EntityState.Modified;
db.SaveChanges();
foreach (var result in model.ModelManpowerRequestEditResults)
{
db.PMCManpowerRequestDetails.AddOrUpdate(
new PMCManpowerRequestDetail()
{
ManpowerRequestId = model.ModelManpowerRequestEdit.Id,
ManpowerId = result.ManpowerId,
Planned = result.Planned,
Actual = result.Actual,
Remarks = result.Remarks
});
}
db.SaveChanges();
return RedirectToAction("Index", "PmcManpowerRequestDetail");
}
and this is my PartialView
#model ProjectManagementSystem.ViewModel.ViewModelsManpowerEdit
<table class="table table-responsive table-striped">
<tr class="row">
<th> Manpower Type</th>
<th> Planned</th>
<th> Actual</th>
<th> Remarks</th>
</tr>
#for (int i = 0; i < Model.ModelManpowerRequestEditResults.Count; i++)
{
<tr class="row">
<td>
#Html.EditorFor(m => m.ModelManpowerRequestEditResults[i].ManpowerType,
new { htmlAttributes = new { #readonly = "readonly", #class = "form-control" } })
#Html.HiddenFor(m => m.ModelManpowerRequestEditResults[i].Id)
</td>
<td>
#Html.EditorFor(m => m.ModelManpowerRequestEditResults[i].Planned,
new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.EditorFor(m => m.ModelManpowerRequestEditResults[i].Actual,
new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.TextBoxFor(m => m.ModelManpowerRequestEditResults[i].Remarks,
new { type = "text", #class = "form-control" })
</td>
</tr>
}
</table>
and Down Here is my Main View
#model ProjectManagementSystem.ViewModel.ViewModelsManpowerEdit
<style>
h2 {
color: #b48608;
font-family: 'Droid serif', serif;
font-size: 36px;
font-weight: 400;
font-style: italic;
line-height: 44px;
margin: 0 0 12px;
text-align: center;
}
</style>
<h2>Edit Manpower Request</h2>
#using (Html.BeginForm("ManpowerEdit", "PmcManpowerRequestDetail", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.HiddenFor(model => model.ModelManpowerRequestEdit.Id)
<div class="form-group">
<label class="control-label col-md-2"> Project Name </label>
<div class="col-md-10">
#Html.DropDownList("projectId", (SelectList)ViewBag.project, new { #class = "form-control" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.ModelManpowerRequestEdit.JobNo, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(m => m.ModelManpowerRequestEdit.JobNo, new { htmlAttributes = new { #class = "form-control jobNo" } })
<div id="divStatus"></div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.ModelManpowerRequestEdit.RequestDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.ModelManpowerRequestEdit.RequestDate, new { type = "text", #class = "form-control datepicker" })
</div>
</div>
#Html.Partial("_ManpowerEditPartial")
<div class="form-group">
<input type="submit" id="Save" value="Update" class="btn btn-success" />
</div>
My view models public class ViewModelsManpowerEdit
{
public PmcManpowerRequestViewModel ModelManpowerRequestEdit { get; set; }
public List<ManpowerRequestEdit_Result> ModelManpowerRequestEditResults { get; set; }
}
All I can see after reading your comments is the Id's are null so I will suggest add the respected Id's in Hidden Fields in their respected Views and Partial Views
For example: as you haven't provided any model all I can do is predict
#Html.HiddenFor(m => m.ModelManpowerRequestEditResults[i].ManpowerId)
#Html.HiddenFor(m => m.ModelManpowerRequestEditResults[i].Id)
#Html.HiddenFor(m => m.ModelManpowerRequestEditResults[i].ManpowerrewuestId)
Because you said ManpowerId and Id and ManpowerrewuestId

Get all Form Collection values where Checkbox checked

View is as below:
#using (Html.BeginForm("AddCreditLeave", "AdminLeaveCredit"))
{
<div id="Container">
<table>
<tr style="background-color:#A9DDFF;color:Black;">
<td>Select</td>
<td>Staff Code</td>
<td>Name</td>
<td>Designation</td>
<td>AL</td>
<td>CL</td>
</tr>
#foreach (var person in Model.Empdetailslist)
{
<tr>
<td>
<input type="checkbox" name="sid" value="#person.staffcode" id="chk" />
</td>
<td>#Html.TextBoxFor(m => person.staffcode, new { #class = "ReadOnly", #readonly = "readonly", style = "width:180px; text-align:center" })</td>
<td>#Html.TextBoxFor(m => person.name, new { #class = "ReadOnly", #readonly = "readonly", style = "width:180px; text-align:center" })</td>
<td>#Html.TextBoxFor(m => person.designation, new { #class = "ReadOnly", #readonly = "readonly", style = "width:180px; text-align:center" })</td>
<td>#Html.TextBoxFor(m => person.ALLeave, new { style = "width:180px; text-align:center" })</td>
<td>#Html.TextBoxFor(m => person.CLLeave, new { style = "width:180px; text-align:center" })</td>
</tr>
}
</table>
}
First column is a Checkbox and I am showing ten rows.
Second column is a TextBox.
There is a Save button. On click of Save button, I want to pick values of second column from the Form Collection where Checkbox is checked.
How to do this?
This is how I would do this with a simplified example.
Working Fiddle
Model
public class AModel
{
public string Name { get; set; }
public string staffcode { get; set; }
public bool Checked { get; set; }
}
Note the Checked property
View for loop
#for(var i = 0; i < Model.Empdetailslist.Count; i++)
{
<tr>
<td>
#Html.HiddenFor(m => Model.Empdetailslist[i].Name)
#Html.HiddenFor(m => Model.Empdetailslist[i].staffcode)
#Html.CheckBoxFor(m = Model.Empdetailslist[i].Checked)
</td>
<td>
#Model[i].Name
</td>
</tr>
}
Note the for loop instead of foreach to enable model binding and the hidden fields to allow the values to be posted back to the controller
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx/
Controller post
[HttpPost]
public ActionResult AddCreditLeave(YourModel model)
{
// property will be populated in model.Empdetailslist
return View(list);
}
Edit your View like this,
#using (Html.BeginForm("AddCreditLeave", "AdminLeaveCredit"))
{
<div id="Container">
<table>
<tr style="background-color:#A9DDFF;color:Black;">
<td>Select</td>
<td>Staff Code</td>
<td>Name</td>
<td>Designation</td>
<td>AL</td>
<td>CL</td>
</tr>
#foreach (var person in Model.Empdetailslist)
{
<tr>
<td>
<input type="checkbox" name="sid" value="#person.staffcode" id="#person.id" />
</td>
<td>#Html.TextBoxFor(m => person.staffcode, new { #class = "ReadOnly", #readonly = "readonly", style = "width:180px; text-align:center", id="staffcode_#person.id" })</td>
<td>#Html.TextBoxFor(m => person.name, new { #class = "ReadOnly", #readonly = "readonly", style = "width:180px; text-align:center", id="name_#person.id" })</td>
<td>#Html.TextBoxFor(m => person.designation, new { #class = "ReadOnly", #readonly = "readonly", style = "width:180px; text-align:center", id="designation_#person.id" })</td>
<td>#Html.TextBoxFor(m => person.ALLeave, new { style = "width:180px; text-align:center", id="ALLeave_#person.id" })</td>
<td>#Html.TextBoxFor(m => person.CLLeave, new { style = "width:180px; text-align:center", id="CLLeave_#person.id" })</td>
</tr>
}
</table>
<input type="button" onclick="SavePersons();" />
}
Use this code to get all selected person objects in an array.
<script type="text/javascript">
function SavePersons() {
var chkArr = document.getElementsByName('sid');
var selectedPersonsArr = new Array();
for(var i=0; i<chkArr.length; i++) {
if(chkArr[i].checked == true) {
var tmpPerson = new Object();
tmpPerson.id = chkArr[i].id;
tmpPerson.staffcode = document.getElementById('staffcode'+chkArr[i].id).value;
tmpPerson.name = document.getElementById('name'+chkArr[i].id).value;
tmpPerson.designation = document.getElementById('designation'+chkArr[i].id).value;
tmpPerson.ALLeave = document.getElementById('ALLeave'+chkArr[i].id).value;
tmpPerson.CLLeave = document.getElementById('CLLeave'+chkArr[i].id).value;
selectedArr.push(tmpPerson);
}
}
// Now array 'selectedPersonsArr' contains all selected Person objects
// here you can send these objects to your controller through AJAX
}
</script>
Hope it helps, thanks.

HTML Table data not updating in model

I have a ViewModel that contains two lists of Conditions - BuyConditions and SellConditions - plus a couple of attributes - Name etc. The lists are displayed using tables in the view. jQuery allows the tables to be manipulated - adding Conditions to the tables (from Buy Condition / Sell Condition DDL's) and removing Conditions from the tables.
My problem is that the Condition lists are not updated in the model when it is posted back to the controller.
Something that may point to the issue is that when the model is returned to the view (due to ModelStat.IsValid failing), the data in the Markets DDL still exists, but the data in the Buy and Sell Condition DDL's doesn't.
I can't find an example on the net to figure out where I'm going wrong. Anyone done this before?
ViewModel:
public class StrategyViewModel
{
public string ID { get; set; }
[Display(Name = "Strategy Name")]
public string StrategyName { get; set; }
[Display(Name = "Market")]
public string SelectedMarketID { get; set; }
[Display(Name = "Asset Type")]
public string SelectedShareTypeID { get; set; }
[Display(Name = "Share")]
public string SelectedShareID { get; set; }
public bool Active { get; set; }
public IEnumerable<Market> Markets { get; set; } // top level of three cascading DDL's - the other two populated via JQuery
public IEnumerable<Condition> BuyConditionList { get; set; } // used to populate DDL
public IEnumerable<Condition> SellConditionList { get; set; } // used to populate DDL
public List<BuyCondition> BuyConditions { get; set; } // list of Buy Conditions
public List<SellCondition> SellConditions { get; set; } // list of Sell Conditions
AppRepository repository = new AppRepository();
public StrategyViewModel()
{
// populate lists
Markets = ListUtils.AddDefaultOptionToMarketList( repository.GetMarkets(), -1, "Select a Market" ).AsEnumerable();
BuyConditionList = repository.GetConditions();
SellConditionList = repository.GetConditions();
BuyConditions = new List<BuyCondition>();
SellConditions = new List<SellCondition>();
}
}
Controller:
public ActionResult Create()
{
StrategyViewModel model = new StrategyViewModel();
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "User, Admin")]
public ActionResult Create(StrategyViewModel model)
{
// for debugging
var errorList = ModelState.Values.SelectMany(v => v.Errors);
if (ModelState.IsValid)
{
var user = repository.GetCurrentUser(User.Identity.GetUserId());
var strategy = new Strategy();
strategy.StrategyName = model.StrategyName;
strategy.ShareID = Convert.ToInt32(model.SelectedShareID);
strategy.BuyConditions = model.BuyConditions.ToList();
strategy.SellConditions = model.SellConditions.ToList();
strategy.Active = model.Active;
int strategyID = repository.AddStrategy(user, strategy);
return RedirectToAction("Index");
}
return View(model);
}
View:
#model ShareTrigger.Models.StrategyViewModel
#{
ViewBag.Title = "Create";
}
#{Html.EnableUnobtrusiveJavaScript(true);}
<script type="text/javascript">
$(document).ready(function () {
$(function () {
$('#SelectedMarketID').change(function () {
var selectedMarketID = $(this).val();
$.getJSON('#Url.Action("ShareTypes")', { marketId: selectedMarketID }, function (shareTypes) {
var shareTypesSelect = $('#SelectedShareTypeID');
shareTypesSelect.empty();
$.each(shareTypes, function (index, shareType) {
shareTypesSelect.append($('<option/>').attr('value', shareType.Value).text(shareType.Text));
});
$('#SelectedShareTypeID').trigger("change");
});
});
$('#SelectedShareTypeID').change(function () {
var selectedShareTypeId = $(this).val();
var selectedMarketID = $('#SelectedMarketID').val();
$.getJSON('#Url.Action("Shares")', { shareTypeId: selectedShareTypeId, marketID: selectedMarketID }, function (shares) {
var sharesSelect = $('#SelectedShareID');
sharesSelect.empty();
$.each(shares, function (index, share) {
sharesSelect.append($('<option/>').attr('value', share.Value).text(share.Text));
});
});
});
});
$('#AddBuyCondition').click(function () {
var conditionID = +$("#BuyConditionList").val();
if (conditionID != -2) {
conditionID = +$("#BuyConditionList").val();
var conditionText = $("#BuyConditionList").find('option:selected').text();
$("tr:contains('Add')").remove();
$('#BCDropDownRow').before('<tr class="bcrow"><td class="BuyConditionCell" data-conditionID="' + conditionID + '"><input data-val="true" data-val-number="The field ConditionID must be a number." data-val-required="The ConditionID field is required." id="item_ConditionID" name="item.ConditionID" type="hidden" value="' + conditionID + '">' + conditionText + '</td><td><button class="RemoveBuyCondition type="button" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-minus"></span></button></td></tr>');
$("#BuyConditionList").find('option:selected').remove();
var rows = $('#BuyConditionList option').size();
if (rows == 0) { $("#BuyConditionList").append('<option value="-2">No more conditions to select</option>'); }
}
});
$('#BuyConditionsTable').on('click', '.RemoveBuyCondition', function () {
var conditionID = +$(this).parent().parent().find('.BuyConditionCell').data('conditionid');
var conditionText = $(this).parent().parent().find('.BuyConditionCell').text();
$(this).closest('.bcrow').remove();
$('#BuyConditionList option[value="-2"]').remove();
$("#BuyConditionList").append('<option value="' + conditionID + '">' + conditionText + '</option>');
var options = $('#BuyConditionList option');
var arr = options.map(function (_, o) { return { t: $(o).text(), v: o.value }; }).get();
arr.sort(function (o1, o2) { return o1.t > o2.t ? 1 : o1.t < o2.t ? -1 : 0; });
options.each(function (i, o) {
o.value = arr[i].v;
$(o).text(arr[i].t);
});
});
$('#AddSellCondition').click(function () {
var conditionID = +$("#SellConditionList").val();
if (conditionID != -2) {
conditionID = +$("#SellConditionList").val();
var conditionText = $("#SellConditionList").find('option:selected').text();
$("tr:contains('Add')").remove();
$('#SCDropDownRow').before('<tr class="scrow"><td class="SellConditionCell" data-conditionID="' + conditionID + '"><input id="item_ConditionID" name="item.ConditionID" type="hidden" value="' + conditionID + '">' + conditionText + '</td><td><button class="RemoveSellCondition type="button" class="btn btn-default btn-xs"><span class="glyphicon glyphicon-minus"></span></button></td></tr>');
$("#SellConditionList").find('option:selected').remove();
var rows = $('#SellConditionList option').size();
if (rows == 0) { $("#SellConditionList").append('<option value="-2">No more conditions to select</option>'); }
}
});
$('#SellConditionsTable').on('click', '.RemoveSellCondition', function () {
var conditionID = +$(this).parent().parent().find('.SellConditionCell').data('conditionid');
var conditionText = $(this).parent().parent().find('.SellConditionCell').text();
$(this).closest('.scrow').remove();
$('#SellConditionList option[value="-2"]').remove();
$("#SellConditionList").append('<option value="' + conditionID + '">' + conditionText + '</option>');
var options = $('#SellConditionList option');
var arr = options.map(function (_, o) { return { t: $(o).text(), v: o.value }; }).get();
arr.sort(function (o1, o2) { return o1.t > o2.t ? 1 : o1.t < o2.t ? -1 : 0; });
options.each(function (i, o) {
o.value = arr[i].v;
$(o).text(arr[i].t);
});
});
});
</script>
<h2>Create Strategy</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.StrategyName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.StrategyName)
#Html.ValidationMessageFor(model => model.StrategyName)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedMarketID, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(x => x.SelectedMarketID, new SelectList(Model.Markets, "MarketId", "MarketCode"))
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedShareTypeID, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(x => x.SelectedShareTypeID, Enumerable.Empty<SelectListItem>(), "Select an Asset Type")
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedMarketID, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(x => x.SelectedShareID, Enumerable.Empty<SelectListItem>(), "Select a Share")
</div>
</div>
<div>
</div>
<div class="col-md-10">
<table class="table" id="BuyConditionsTable">
<tr>
<th>
#Html.DisplayName("Buy Conditions")
</th>
<th></th>
</tr>
#foreach (var item in Model.BuyConditions)
{
<tr>
<td>
#Html.HiddenFor(modelItem => item.ConditionID)
#Html.DisplayFor(modelItem => item.ConditionName)
</td>
<td></td>
</tr>
}
<tr id="BCDropDownRow">
<td>
<button id="AddBuyCondition" type="button" class="btn btn-default btn-xs">
<span class="glyphicon glyphicon-plus"></span>
</button>
#Html.DropDownListFor(x => x.BuyConditionList, new SelectList(Model.BuyConditionList, "ConditionID", "ConditionName"))
</td>
<td></td>
</tr>
</table>
</div>
<div>
</div>
<div class="col-md-10">
<table class="table" id="SellConditionsTable">
<tr>
<th>
#Html.DisplayName("Sell Conditions")
</th>
<th></th>
</tr>
#foreach (var item in Model.SellConditions)
{
<tr>
<td>
#Html.HiddenFor(modelItem => item.ConditionID)
#Html.DisplayFor(modelItem => item.ConditionName)
</td>
<td></td>
</tr>
}
<tr id="SCDropDownRow">
<td>
<button id="AddSellCondition" type="button" class="btn btn-default btn-xs">
<span class="glyphicon glyphicon-plus"></span>
</button>
#Html.DropDownListFor(x => x.SellConditionList, new SelectList(Model.SellConditionList, "ConditionID", "ConditionName"))
</td>
<td></td>
</tr>
</table>
</div>
<div class="form-group">
<div class="col-md-offset-9 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
}
The reason you're getting BuyConditions and SellConditions empty because of the following code
#Html.HiddenFor(modelItem => item.ConditionID)
This will render ALL as
<input type="hidden" id="item_ConditionID" name="item.ConditionID" />
It can't be resolved in the controller action Create due to the wrong naming.
Instead, it should have been
#Html.HiddenFor(x => x.SellConditions[index].ConditionID)
This will render the control as (if index is 0)
<input type="hidden" id="SellConditions_0__ConditionID" name="SellConditions[0].ConditionID" />
Therefore, the foreach block should be as follow
#foreach (int index = 0; index < Model.SellConditions.Count; index++)
{
<tr>
<td>
#Html.HiddenFor(x => x.SellConditions[index].ConditionID)
#Html.DisplayFor(x => x.SellConditions[index].ConditionName)
</td>
<td></td>
</tr>
}
And the same rule for BuyConditions too.

Categories

Resources