I made a HttpPost :
[HttpPost]
public IActionResult PokemonDetails(int PokemonId)
{
return PartialView("_PokemonDetails");
}
I want to find all the data from the Id in the http.
the datas are in my controller :
public IActionResult Index()
{
#region ListeDesPokemons
var pokemonList = new List<PokemonModel>();
var Id = 1;
var Img = 1;
pokemonList.Add(new PokemonModel() { Id = Id++, Name = "Bulbizarre", UsName = "Bulbasaur(us)", JpName = "フシギダネ(jp)", Type1 = "Plante", Type2 = "Poison", Rate = 45, Image = "https://eternia.fr/public/media/pokedex/artworks/00" + Img++ + ".png" });
pokemonList.Add(new PokemonModel() { Id = Id++, Name = "Herbizarre", UsName = "Ivysaur(us)", JpName = "フシギソウ(jp)", Type1 = "Plante", Type2 = "Poison", Rate = 45, Image = "https://eternia.fr/public/media/pokedex/artworks/00" + Img++ + ".png" });
#endregion
var model = new PokemonViewModel();
model.Pokemons = pokemonList;
ViewBag.TotalPokemon1G = pokemonList.Count;
return View(model);
}
find good data from id thank you.
I do not have entity yet.
You could use TempData to pass data across different requests .TempData is used to pass data from current request to subsequent request (means redirecting from one page to another). It’s life is very short and lies only till the target view is fully loaded. But you can persist data in TempData by calling Keep() method.
Here is a simple working demo
Model:
public class PokemonModel
{
public int Id { get; set; }
public string Name { get; set; }
public string UsName { get; set; }
public string JpName { get; set; }
public string Type1 { get; set; }
public string Type2 { get; set; }
public int Rate { get; set; }
public string Image { get; set; }
}
public class PokemonViewModel
{
public List<PokemonModel> Pokemons { get; set; }
}
Controller:
public IActionResult PokemonList()
{
#region ListeDesPokemons
var pokemonList = new List<PokemonModel>();
var Id = 1;
var Img = 1;
pokemonList.Add(new PokemonModel() { Id = Id++, Name = "Bulbizarre", UsName = "Bulbasaur(us)", JpName = "フシギダネ(jp)", Type1 = "Plante", Type2 = "Poison", Rate = 45, Image = "https://eternia.fr/public/media/pokedex/artworks/00" + Img++ + ".png" });
pokemonList.Add(new PokemonModel() { Id = Id++, Name = "Herbizarre", UsName = "Ivysaur(us)", JpName = "フシギソウ(jp)", Type1 = "Plante", Type2 = "Poison", Rate = 45, Image = "https://eternia.fr/public/media/pokedex/artworks/00" + Img++ + ".png" });
#endregion
var model = new PokemonViewModel();
model.Pokemons = pokemonList;
var json = JsonConvert.SerializeObject(pokemonList);
TempData["pokemonJson"] = json;
ViewBag.TotalPokemon1G = pokemonList.Count;
return View(model);
}
[HttpPost]
public IActionResult PokemonDetails(int PokemonId)
{
var pokemonJson = TempData["pokemonJson"].ToString();
TempData.Keep("pokemonJson");
var pokemonList = JsonConvert.DeserializeObject<List<PokemonModel>>(pokemonJson);
var pokemon = pokemonList.SingleOrDefault(p => p.Id == PokemonId);
return PartialView("_PokemonDetails",pokemon);
}
View:
#model WebApplication1.Models.PokemonViewModel
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Pokemons[0].Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Pokemons[0].JpName)
</th>
<th>
#Html.DisplayNameFor(model => model.Pokemons[0].UsName)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Pokemons)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.JpName)
</td>
<td>
#Html.DisplayFor(modelItem => item.UsName)
</td>
<td>
<input hidden asp-for="#item.Id" />
PokemonDetails
</td>
</tr>
}
</tbody>
</table>
<div id="pokemon"></div>
#section Scripts{
<script type="text/javascript">
$(".btnclick").click(function () {
var id = $(this).closest("td").find("input").val();
$.ajax({
type: "post",
url: "/Home/PokemonDetails?PokemonId=" + id,
success: function (result) {
$("#pokemon").html(result);
}
});
});
</script>
}
PartialView
#model WebApplication1.Models.PokemonModel
<div>
<hr />
<dl class="dl-horizontal">
<dt>
#Html.DisplayNameFor(model => model.Id)
</dt>
<dd>
#Html.DisplayFor(model => model.Id)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Name)
</dt>
<dd>
#Html.DisplayFor(model => model.Name)
</dd>
<dt>
#Html.DisplayNameFor(model => model.JpName)
</dt>
<dd>
#Html.DisplayFor(model => model.JpName)
</dd>
<dt>
#Html.DisplayNameFor(model => model.UsName)
</dt>
<dd>
#Html.DisplayFor(model => model.UsName)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Type1)
</dt>
<dd>
#Html.DisplayFor(model => model.Type1)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Type2)
</dt>
<dd>
#Html.DisplayFor(model => model.Type2)
</dd>
<dt>
#Html.DisplayNameFor(model => model.Rate)
</dt>
<dd>
#Html.DisplayFor(model => model.Rate)
</dd>
</dl>
</div>
You can use LINQ to query the list for the Id you want.
int PokemonId = 2; // input from http post
var result = pokemonList.FirstOrDefault(p => p.Id == PokemonId);
Ok I made it here is the answer.
My controller:
public IActionResult Index()
{
#region ListeDesPokemons
var pokemonList = new List<PokemonModel>();
var Id = 1;
var Img = 1;
pokemonList.Add(new PokemonModel() { Id = Id++, Name = "Bulbizarre", UsName = "Bulbasaur(us)", JpName = "フシギダネ(jp)", Type1 = "Plante", Type2 = "Poison", Rate = 45, Image = "https://eternia.fr/public/media/pokedex/artworks/00" + Img++ + ".png" });
pokemonList.Add(new PokemonModel() { Id = Id++, Name = "Herbizarre", UsName = "Ivysaur(us)", JpName = "フシギソウ(jp)", Type1 = "Plante", Type2 = "Poison", Rate = 45, Image = "https://eternia.fr/public/media/pokedex/artworks/00" + Img++ + ".png" });
var model = new PokemonViewModel();
model.Pokemons = pokemonList;
var json = JsonConvert.SerializeObject(pokemonList);
TempData["pokemonListJson"] = json;
TempData.Keep("PokemonListJson");
ViewBag.TotalPokemon1G = pokemonList.Count;
return View(model);
}
[HttpPost]
public IActionResult PokemonDetails(int pokemonId)
{
if (TempData["pokemonListJson"] != null)
{
if (string.IsNullOrEmpty(TempData["pokemonListJson"].ToString()))
{
return null;
}
}
var pokemonListJson = TempData["pokemonListJson"].ToString();
TempData.Keep("PokemonListJson");
var pokemonList = JsonConvert.DeserializeObject<List<PokemonModel>>(pokemonListJson);
var selectedPokemon = pokemonList.SingleOrDefault(p => p.Id == pokemonId);
if (selectedPokemon != null)
{
return PartialView("_PokemonDetails", selectedPokemon);
}
return null;
}
My partial View:
#model PokemonModel
<div id="taillDescriptionModal" class="modal-dialog modal-dialog-scrollable mw-100 m-auto" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 id="modalLabelStack2" class="modal-title font-weight-bold float-left">n° #Html.DisplayFor(model => model.Id)</h5>
<div id="nomPokemonStack2" class="ml-auto">
<h5 id="Name">#Html.DisplayFor(model => model.Name)</h5> <h5 id="UsName">#Html.DisplayFor(model => model.UsName)</h5> <h5 id="JpName">#Html.DisplayFor(model => model.JpName)</h5>
</div>
<button type="button" class="close" data-dismiss="modal" aria-label="close">
<span class="text-danger" aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col overflow-hidden">
<img class="img-fluid rounded-lg" src="#Html.DisplayFor(model => model.Image)" alt="pokemon.Name" />
</div>
<div class="col">
<span>Type : </span>
<div class="col text-white">
<span class="#Html.DisplayFor(model => model.Type1) badge">#Html.DisplayFor(model => model.Type1)</span>
<span class="#Html.DisplayFor(model => model.Type2) badge">#Html.DisplayFor(model => model.Type2)</span>
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Fermer</button>
<button type="submit" class="btn btn-success" onclick="afficheIdSurIndex(#Html.DisplayFor(model => model.Rate))"> Choisir</button>
</div>
</div>
</div>
<script>
function afficheIdSurIndex(selectedPokemonRate) {
$.ajax({
url: '/Pokedex/Calcul/',
type: 'POST',
dataType: "html",
data: { "selectedPokemonRate": selectedPokemonRate },
success: function () {
//enlever la classe pour afficher le contenu de la div
$('#Test').removeClass('text-hide');
//$('#Test').addClass('text-show');
var rateTxt = 'Taux de Capture du pokémon sélectionné : ' + selectedPokemonRate
//vider le contenu de la div
$("#Test").empty();
//écrire dans la div
$("#Test").append(rateTxt);
//fermer les modals
$('#pokemonDetails').modal('hide');
$('#choixPokemon').modal('hide');
}
})
}
</script>
My Index page:
#model PokemonViewModel
#{
ViewData["Title"] = "Pokedex";
Layout = "~/Views/Shared/_LayoutPokemon.cshtml";
<script src="~/lib/jquery/dist/jquery.min.js"></script>
}
<h1>Pokedex</h1>
<!-- Button choix Pokémon modal -->
<div class="container">
<button type="button" class="btn btn-primary mb-2" data-toggle="modal" data-target="#choixPokemon">
Pokemon 1G
</button>
</div>
<!-- Modal choix Pokémon -->
<div id="choixPokemon" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="choixPokemonModalLabel" aria-hidden="true">
<div id="modalWitdh" class="modal-dialog modal-dialog-scrollable mw-100 m-auto" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 id="choixPokemonModalLabel" class="modal-title">Pokédex première génération, #ViewBag.TotalPokemon1G Pokémons </h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body text-center">
<div class="row">
#foreach (var pokemon in Model.Pokemons)
{
<div class="col">
<button type="submit" class="btn" onclick="getInfo(#pokemon.Id)">
<div class="card text-center rounded-lg">
<div id="tailleCard" class="card-body">
<h5 id="cardTitle" class="card-title">n°#pokemon.Id <br /> #pokemon.Name</h5>
<img id="tailleImg" src="#pokemon.Image" alt="#pokemon.Name" />
</div>
</div>
</button>
</div>
}
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Fermer</button>
</div>
</div>
</div>
</div>
<!-- Modal Description du pokémon choisi -->
<div id="pokemonDetails" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="descriptionPokemonModalLabel" aria-hidden="true">
#*Contenue dans vu partiel _PokemonDetails*#
</div>
#*Div de collection des donnés du pokémon selectionné dans le deuxième modal.(données provenant de la vue partiel _PokemonDetails) *#
<div class="row">
<div class="col">
<h6 id="Test" class="text-hide"></h6>
</div>
</div>
#*button script pour collecter les données du pokémon sélectionné dans le 1er modal*#
<script>
function getInfo(pokemonId) {
event.preventDefault;
console.log(pokemonId);
$.ajax({
url: '/Pokedex/PokemonDetails/',
type: 'POST',
dataType: "html",
data: { "pokemonId": pokemonId },
success: function (response) {
$("#pokemonDetails").html(response);
$('#pokemonDetails').modal('show');
}
})
}
</script>
In the startup page I need to add:
services.AddMemoryCache();
services.AddSession();
services.AddMvc().AddSessionStateTempDataProvider();
I put everything here for help anyone who need help.
add a breakpoint in action PokemonDetails:
[HttpPost]
public IActionResult PokemonDetails(int pokemonId)
{ // add break point here
when the break point is hit here, did you get pokemonId ?
Related
I have been trying to create a the ability to add/edit records through the use of a modal in .net core.
I have been trying tutorials such as
https://www.youtube.com/watch?v=QmNtbnUfns8
https://www.mindstick.com/Articles/12723/crud-operation-modal-popup-uses-bootstrap-in-mvc
Neither of these are working for as they are as .net. The modal isnt showing up.
ViewClients.cshtml
#model IEnumerable<Evol.Models.Clients>
#{
ViewData["Title"] = "Clients";
Layout = "~/Views/Shared/_Layout.cshtml";
<div class="card">
<div class="card-header card-header-text card-header-rose">
<div class="card-text">
<h4 class="card-title">Clients</h4>
<p class="card-category"></p>
</div>
</div>
<div class="card-body table-responsive">
<div class="table-responsive">
<table class="table table-hover" id="dataTable" width="100%" cellspacing="0">
<thead class="text-gray">
<tr>
<th>
#Html.DisplayNameFor(model => model.ClientName)
</th>
<th>
Actions
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(model => item.ClientName)
</td>
<td class="text-right">
<i class="material-icons">edit</i>
<button type="button" rel="tooltip" title="Remove" class="btn btn-
danger btn-link btn-sm">
<i class="material-icons">close</i>
</button>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
</div>
<div class="modal fade" id="myModal1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
×
<h3 class="modal-title">AddEdit Employee</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
</div>
</div>
</div>
</div>
<script>
var EditClient = function (ClientID) {
var url = "/Client/EditClient?ClientID=" + ClientID;
$("#myModalBodyDiv1").load(url, function () {
$("#myModal1").modal("show");
})
}
EditClient.cshmtl (partial view)
#model Evol.Models.Clients
<form id="myForm">
#Html.HiddenFor(m => m.ClientID)
#Html.TextBoxFor(model => model.ClientName, new { #class = "form-control", #placeholder = "Name" })
<a href="#" id="btnSubmit" class="btn btn-success btn-block">
#if (Model.ClientID > 0)
{
<span>Update</span>
}
else
{
<span>Save</span>
}
</a>
</form>
Add Client
<script>
$(document).ready(function () {
$("#btnSubmit").click(function () {
$("#loaderDiv").show();
var myformdata = $("#myForm").serialize();
alert("Success")
$.ajax({
type: "POST",
url: "/Client/ViewClients",
data: myformdata,
success: function () {
$("#loaderDiv").hide();
$("#myModal1").modal("hide");
}
})
})
})
ClientContoller
public IActionResult EditClient(int ClientID)
{
Clients client = new Clients();
if(ClientID > 0)
{
var user = _context.ClientTable.SingleOrDefault(x => x.ClientID == clientID);
client.ClientID = user.ClientID;
client.ClientName = user.ClientName;
}
return PartialView("EditClient", client);
}
}
Did You Created DbContext Class In Your Project?
CRUD Operations In ASP.NET Core Using Entity Framework Core Code First
EF Core DbContext Class Sample
below code just sample for show data and edit or add data to table.
[HttpGet]
public IActionResult AddEditCustomer(long? id)
{
CustomerViewModel model = new CustomerViewModel();
if (id.HasValue)
{
Customer customer = context.Set<Customer>().SingleOrDefault(c => c.Id == id.Value);
if (customer != null)
{
model.Id = customer.Id;
model.FirstName = customer.FirstName;
model.LastName = customer.LastName;
model.MobileNo = customer.MobileNo;
model.Email = customer.Email;
}
}
return PartialView("~/Views/Customer/_AddEditCustomer.cshtml", model);
}
[HttpPost]
public ActionResult AddEditCustomer(long? id, CustomerViewModel model)
{
try
{
if (ModelState.IsValid)
{
bool isNew = !id.HasValue;
Customer customer = isNew ? new Customer
{
AddedDate = DateTime.UtcNow
} : context.Set<Customer>().SingleOrDefault(s => s.Id == id.Value);
customer.FirstName = model.FirstName;
customer.LastName = model.LastName;
customer.MobileNo = model.MobileNo;
customer.Email = model.Email;
customer.IPAddress = Request.HttpContext.Connection.RemoteIpAddress.ToString();
customer.ModifiedDate = DateTime.UtcNow;
if (isNew)
{
context.Add(customer);
}
context.SaveChanges();
}
}
catch (Exception ex)
{
throw ex;
}
return RedirectToAction("Index");
}
This is because you are missing the HTTP Post attribute PLEASE SEE the docs here
https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-3.1
[HTTPPOST]
public IActionResult EditClient(int ClientID)
{
Clients client = new Clients();
if(ClientID > 0)
{
var user = _context.ClientTable.SingleOrDefault(x => x.ClientID == clientID);
client.ClientID = user.ClientID;
client.ClientName = user.ClientName;
}
return PartialView("EditClient", client);
}
}
I have issue while working with MVC.
while running application for the first time I am getting 20 results.On filter I am getting 4 results.I am able to see those 4 result in Model while debugging but on view its not getting updated. I tried ViewData and ViewBag also but the result is Same.
Can anyone help me out?
Following is My IncentiveGroupConroller.cs
public ActionResult IncentiveGroupIndex(int? page)
{
int pageIndex = page.HasValue ? Convert.ToInt32(page) : 1;
IPagedList<IncentiveGroup> PAGEDGROUP = null;
List<IncentiveGroup> IncentiveGroups = new List<IncentiveGroup>();
DataSet ds = new DataSet();
ds = SQLDatabaseOperations.ExecuteDataset(ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString(), CommandType.StoredProcedure, "GetIncentiveGroups");
DataTable dt = new DataTable();
dt = ds.Tables[0];
foreach (DataRow dr in dt.Rows)
{
IncentiveGroups.Add(new IncentiveGroup(dr));
}
ViewBag.IncentiveGroups = IncentiveGroups;
PAGEDGROUP = IncentiveGroups.ToPagedList(pageIndex, 10);
return View(PAGEDGROUP);
}
[HttpPost]
public ActionResult Filter(IncentiveGroup oIncentiveGroup)
{
IPagedList<IncentiveGroup> PagedIncenticeGroups = null;
List<IncentiveGroup> IncentiveGroups = new List<IncentiveGroup>();
DataSet ds = new DataSet();
ds = SQLDatabaseOperations.ExecuteDataset(ConfigurationManager.ConnectionStrings["DefaultConnection"].ToString(), CommandType.StoredProcedure, "FilterIncentiveGroups", oIncentiveGroup.IncentiveGroupCode, oIncentiveGroup.IncentiveGroupName, oIncentiveGroup.IncentiveGroupShortName, oIncentiveGroup.IncentiveGroupStatus);
DataTable dt = new DataTable();
dt = ds.Tables[0];
foreach (DataRow dr in dt.Rows)
{
IncentiveGroups.Add(new IncentiveGroup(dr));
}
ViewBag.IncentiveGroups = IncentiveGroups;
PagedIncenticeGroups = IncentiveGroups.ToPagedList(1, IncentiveGroups.Count);
return View("IncentiveGroupIndex", PagedIncenticeGroups);
// return RedirectToAction("IncentiveGroupIndex", PagedIncenticeGroups);
}
Follwling ajax call is made for controller
function filterIncentiveGroup() {
var setIncentiveGroupStatus = $('input[name=IncentiveGroupStatus]:checked').val();
var Test = {
IncentiveGroupCode: $('#IncentiveGroupCode').val(),
IncentiveGroupName: $('#IncentiveGroupName').val(),
IncentiveGroupShortName: $('#IncentiveGroupShortName').val(),
IncentiveGroupStatus: setIncentiveGroupStatus,
};
$.ajax({
url: "/IncentiveGroup/Filter",
data: JSON.stringify(Test),
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "html",
success: function (data) {
$('#myModal').modal('hide');
alert("Success");
},
error: function (errormessage) {
$('#myModal').modal('hide');
alert(errormessage.responseText);
}
});
};
Following is my IncentiveGroupIndex.cshtml
#using PagedList.Mvc
#model PagedList.IPagedList<MPISMVC.Models.IncentiveGroup>
#{
ViewBag.Title = "Incentive Group";
}
#*<h2>IncentiveGroupIndex</h2>*#
<div class="container-fluid" style="padding-top: 100px">
<div class="panel panel-primary">
<div class="panel-heading">Manage Incentive Group</div>
<div class="panel-body">
<div class="row">
<div class="col-md-4">
<button type="button" id="create" class="btn btn-success"><span class="glyphicon glyphicon-plus"></span>Add</button>
<button type="button" id="filter" class="btn btn-dafault"><span class="glyphicon glyphicon-filter"></span>Filter</button>
</div>
<div class="col-md-7">
<div class="pagination">
#* Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount *# #Html.PagedListPager(Model, page => Url.Action("IncentiveGroupIndex", new { page }), new PagedListRenderOptions { DisplayEllipsesWhenNotShowingAllPageNumbers = true, MaximumPageNumbersToDisplay = 5, LinkToFirstPageFormat = "First", LinkToPreviousPageFormat = "Previous", LinkToNextPageFormat = "Next", LinkToLastPageFormat = "Last" })
</div>
</div>
<div class="col-md-1">
#*#Html.DropDownList("PageSize", new SelectList(new Dictionary<string, int> { { "10", 10 }, { "20", 20 },{ "50", 50 }, { "100", 100 } }, "Key", "Value", Model.PageSize), new { #class = "form-control" })*#
</div>
</div>
<div class="row">
<div class="col-md-12">
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model[0].IncentiveGroupCode)
</th>
<th>
#Html.DisplayNameFor(model => model[0].IncentiveGroupName)
</th>
<th>
#Html.DisplayNameFor(model => model[0].IncentiveGroupShortName)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.IncentiveGroupCode)
</td>
<td>
#Html.DisplayFor(modelItem => item.IncentiveGroupName)
</td>
<td>
#Html.DisplayFor(modelItem => item.IncentiveGroupShortName)
</td>
<td>
<button type="button" id="View" class="btn btn-sm btn-info" data-toggle="tooltip" title="View" onclick="details('#item.IncentiveGroupCode','View');"><span class="glyphicon glyphicon-eye-open"></span></button>
<button type="button" id="Edit" class="btn btn-sm btn-primary" data-toggle="tooltip" title="Edit" onclick="details('#item.IncentiveGroupCode','Edit');"><span class="glyphicon glyphicon-pencil"></span></button>
#*<button type="button" id="Delete" class="btn btn-sm btn-danger" data-toggle="tooltip" title="Delete" onclick="remove('#item.IncentiveGroupCode');"><span class="glyphicon glyphicon-trash"></span></button>*#
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
#* <div class="row">
<div class="pagination" style="margin-left: 400px">
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber)
of #Model.PageCount #Html.PagedListPager(Model, page => Url.Action("IncentiveGroupIndex", new { page }))
</div>
</div>*#
</div>
</div>
</div>
image of filtered data count
When I am using this code as web view, it works fine, but when with developer option in Chrome I select Mobile View, FormCollection shows empty strings in the controller
VIEW (Edit updtaed)
<div class="page product-details-page deal-product-details-page">
#using (Html.BeginForm("AddProductToCart_Details", "DealProduct", new { productId = Model.Id, shoppingCartTypeId = 1 }, FormMethod.Post))
{
<div class="page-body">
#using (Html.BeginRouteForm("Product", new { SeName = Model.SeName }, FormMethod.Post, new { id = "product-details-form" }))
{
#{
var dataDictAttributes = new ViewDataDictionary();
dataDictAttributes.TemplateInfo.HtmlFieldPrefix = string.Format("attributes_{0}", Model.Id);
#Html.Partial("~/Views/Product/_ProductAttributes.cshtml", Model.ProductAttributes, dataDictAttributes)
}
<!--gift card-->
#{
var dataDictGiftCard = new ViewDataDictionary();
dataDictGiftCard.TemplateInfo.HtmlFieldPrefix = string.Format("giftcard_{0}", Model.Id);
#Html.Partial("~/Views/Product/_GiftCardInfo.cshtml", Model.GiftCard, dataDictGiftCard)
}
<!--rental info-->
#{
var dataDictRental = new ViewDataDictionary();
dataDictRental.TemplateInfo.HtmlFieldPrefix = string.Format("rental_{0}", Model.Id);
#Html.Partial("~/Views/Product/_RentalInfo.cshtml", Model, dataDictRental)
}
<!--price & add to cart-->
#{
var dataDictPrice = new ViewDataDictionary();
dataDictPrice.TemplateInfo.HtmlFieldPrefix = string.Format("price_{0}", Model.Id);
#Html.Partial("~/Views/Product/_ProductPrice.cshtml", Model.ProductPrice, dataDictPrice)
#Html.Partial("~/Views/Product/_ProductTierPrices.cshtml", Model.TierPrices)
}
<!--wishlist, compare, email a friend-->
<!--attributes-->
#{
var item = #Model.AssociateProductAttributesList.Where(x => x.Item1 == data.Id).Select(x => x.Item2).ToList()[0];
bool isAttributes =false;
}
<div class="popup" data-popup="popup-#data.Id">
<div class="popup-inner">
<h2>#data.Name</h2>
<p>#data.ShortDescription</p>
<br />
#foreach (System.Collections.DictionaryEntry value in item)
{
var val = data.Id + "_" + value.Key.ToString();
isAttributes = true;
#*<div class="attributes">*#
<dl>
<dt id="product_attribute_label_19">
<label class="text-prompt">
#value.Key.ToString()
</label>
</dt>
<dd id="product_attribute_input_19" class="product_attribute_inputdiv_#val">
#Html.DropDownList("Attributes," + data.Id + "," + value.Key.ToString(), new SelectList((System.Collections.IEnumerable)value.Value, "Id", "Name"), "--- Please select ---")
</dd>
</dl>
#*</div>*#
}
<br />
<div onclick="ImageBlur('div_#data.Id')" class="buttons" style="text-align:left;">
<input class="button-1" data-popup-close="popup-#data.Id" type="button" value="Add to back" />
</div>
<a class="popup-close" data-popup-close="popup-#data.Id" href="#">x</a>
</div>
</div>
#if (item.Count == 0)
{
#Html.Hidden("Attributes," + data.Id + ",", "0")
<div class="popup" data-popup="popup-#data.Id">
<div class="popup-inner">
<h2>#data.Name</h2>
<p>#data.ShortDescription</p>
<div onclick="ImageBlur('div_#data.Id')" class="buttons" style="text-align:left;">
<input class="button-1" data-popup-close="popup-#data.Id" type="button" value="Add to back" />
</div>
<a class="popup-close" data-popup-close="popup-#data.Id" href="#">x</a>
</div>
</div>
}
#if (isAttributes)
{
<a style="color: blue;" data-popup-open="popup-#data.Id" href="#">
<img id="imgdiv_#data.Id" src="~/Themes/Playground/Content/img/dealselectattribut.png" class="select-atr-img" style="width: 50%; margin-bottom: 10px;"/>
</a>
}
</div>
}
</div>
<div>
</div>
#{
var dataDictAddToCart = new ViewDataDictionary();
dataDictAddToCart.TemplateInfo.HtmlFieldPrefix = string.Format("addtocart_{0}", Model.Id);
<div class="overview" style="width:100%; margin-left:auto">
#Html.Partial("~/Views/Product/_AddToCart.cshtml", Model.AddToCart, dataDictAddToCart)
</div>
}
</div>
}
</div>
}
</div>
Controller
public ActionResult AddProductToCart_Details(int productId, int shoppingCartTypeId, FormCollection form)
{
if (_productService.IsDealProducts(productId))
{
if (!IsCompleteSelected(form))
{
return Json(new
{
success = false,
message = " Plese select all associated product attribute "
});
}
}
//more code here
}
Normal View (Web View)
Mobile View
Form in form is not allowed. This is your issue.
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="" />
}
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.