Cascading dropdownlist, first dropdownlist is filled, second not - c#

I have two dropdown lists. And whant to make them Cascading. Here is the viewModel:
public class FaqOverviewModel
{
public int Id { get; set; }
public string EmailBericht { get; set; }
public string Naam { get; set; }
public string AfzenderNaam { get; set; }
public string TelefoonNr { get; set; }
[ForeignKey("FaqCategorie")]
public int FaqCategorie_Id { get; set; }
public FaqOverviewModel()
{
Categorie = new List<FaqCategorie>();
SubCategorie = new List<FaqSubCategorie>();
}
public FaqOverviewModel(IEnumerable<FaqCategorie> categories)
{
this.Categorie = categories;
//this.SubCategorie = subcategorie;
}
#region FAQCategorie
private readonly IEnumerable<FaqCategorie> Categorie;
private readonly IEnumerable<FaqSubCategorie> SubCategorie;
//private IOrderedQueryable<FaqCategorie> categories;
private IEnumerable<SelectListItem> subCategorie;
public int? SelectedCategoriedFaqId { get; set; }
public int? SelectedSubCategorieFaqId { get; set; }
public IEnumerable<SelectListItem> FAQCategorieItems
{
get
{
return new SelectList(Categorie, "Id", "Naam");
}
}
#endregion
#region subcategorie
#endregion
}
And the Contoller:
public class FAQController : Controller
{
//FaqService faqService;
FaqCategorieService faqCategorieService;
FaqCategorieSubService faqCategorieSubService;
public FAQController(FaqCategorieService faqCategorieService, FaqCategorieSubService faqCategoriesubservice)
{
this.faqCategorieService = faqCategorieService;
this.faqCategorieSubService = faqCategoriesubservice;
}
// GET: FAQ
// [HttpGet]
public ActionResult Index()
{
var categories = faqCategorieService.GetAll().OrderBy(x => x.Naam);
// var subCategorie = faqCategorieSubService.GetAll().OrderBy(sub => sub.Naam);
//var subCategorie = faqCategorieSubService.GetAll().Where(s => s.Id == s.FaqCategorie_Id).ToList()
// .Select(c => new SelectListItem() { Value = c.Id.ToString(), Text = c.Naam });
FaqOverviewModel model = new FaqOverviewModel(categories);
return View(model);
}
public JsonResult SubCategorie(int Categorieid)
{
var subCategorie = faqCategorieSubService.GetAll().Where(s => s.Id == Categorieid).ToList()
.Select(c => new SelectListItem() { Value = c.Id.ToString(), Text = c.Naam });
//var Subcategorie = faqCategorieSubService.GetAll().Where(s => s.Id == Categorieid).ToList()
// .Select(c => new SelectListItem)(){ = c.Id.ToString(), Text = c.Naam });
return this.Json(subCategorie, JsonRequestBehavior.AllowGet);
}
}
And the View:
#using (Html.BeginForm())
{
#*#Html.DropDownList("Id", ViewBag.Id as SelectList, "Select a Category", new { id = "FaqCategorie_Id" })<br />
<select id="FaqSubCategorie" name="FaqSubCategorie"></select><br />*#
<p>
<span class="fixedLabelWidth">#Html.LabelFor(model => model.SelectedCategoriedFaqId, "Categorie:")</span>
#Html.DropDownListFor(x => x.SelectedCategoriedFaqId, Model.FAQCategorieItems)
<select name="Id" id="Id"></select>
</p>
#*<p>
<span class="fixedLabelWidth">#Html.LabelFor(model => model.SelectedSubCategorieFaqId, "onderwerp:")</span>
#Html.DropDownListFor(x => x.SelectedSubCategorieFaqId, Model.FaqCategorieSubItems)
</p>*#
<p>
<span class="fixedLabelWidth">#Html.LabelFor(model => model.EmailBericht, "Bericht:")</span>
#Html.TextAreaFor(x => x.EmailBericht)
</p>
<p>
<span class="fixedLabelWidth">#Html.LabelFor(model => model.AfzenderNaam, "Afzender:")</span>
#Html.TextBoxFor(x => x.AfzenderNaam)
</p>
<p>
<span class="fixedLabelWidth">#Html.LabelFor(model => model.TelefoonNr, "Tel:")</span>
#Html.TextBoxFor(x => x.TelefoonNr)
</p>
}
#section scripts
{
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/Form")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/Bundles/Q")
#Scripts.Render("~/Bundles/moment")
#Scripts.Render("~/bundles/Utils")
#Scripts.Render("~/bundles/Jquery-ui")
<script type="text/javascript">
$(document).ready(function () {
$("#Id").change(function () {
var strStateID = "";
strCategorieID = $(this)[0].value; // get the selected categorie id
var url = Medicijnverstrekking.baseUrl + "/FAQ/SubCategorie/" + strCategorieID;
// call controller's action
$.getJSON(url, null, function (data) {
// do something once the data is retrieved
$("#Id").empty();
$.each(data, function (index, optionData) {
$("#Id").append("<option value='"
+ optionData.Id
+ "'>" + optionData.Naam
+ "</option>");
});
});
})
.change(); // value});
});
</script>
}
The first dropdownlist is filled. But the second dropdownlist is empty.And also the Json:
public JsonResult SubCategorie(int Categorieid) doesnt hit, when I put a breakpoint there
Thank you

Related

Preserving data even when ModelState is invalid or one required entry is null

Whenever I submit form to the Edit action method on my controller, without any entry or with invalid entry, it triggers the error message as expected. However, I lose all the other data as well. I am looking for a way to preserve data entered even if the ModelState is invalid. Below is my code:
Viewmodel
public class EditOrderViewModel
{
[Required(ErrorMessage = "Must Provide Order Number")]
public string OrderNumber { get; set; }
public int OrderId { get; set; }
public int CustomerId { get; set; }
public int TrailerId { get; set; }
public List<SelectListItem> Trailers { get; set; }
public List<SelectListItem> Customers { get; set; }
public EditOrderViewModel()
{
}
public EditOrderViewModel(Order orderToEdit, IEnumerable<Trailer> trailers, IEnumerable<Customer> customers)
{
OrderNumber = orderToEdit.OrderNumber;
CustomerId = orderToEdit.CustomerId;
OrderId = orderToEdit.OrderID;
TrailerId = orderToEdit.TrailerId;
Trailers= new List<SelectListItem>();
foreach (var trailer in trailers)
{
Trailers.Add(new SelectListItem
{
Value = (trailer.TrailerID).ToString(),
Text = trailer.TrailerNumber
});
};
Customers = new List<SelectListItem>();
foreach (var customer in customers)
{
Customers.Add(new SelectListItem
{
Value = (customer.CustomerID).ToString(),
Text = customer.CustomerName
});
};
}
}
Controller
public IActionResult Edit(int id)
{
var orderToEdit = _context.Orders.Include(t => t.Trailer).Include( c => c.Customer).Where(o => o.OrderID == id).SingleOrDefault();
var trailers = _context.Trailers.Where(x => x.TrailerStatus == "Available" || x.TrailerID == orderToEdit.TrailerId).ToList();
var customers = _context.Customers.ToList();
EditOrderViewModel editOrderViewModel = new EditOrderViewModel(orderToEdit, trailers, customers);
return View(editOrderViewModel);
}
[HttpPost]
public IActionResult Edit(EditOrderViewModel editOrderViewModel)
{
Order order = _context.Orders.FirstOrDefault(o => o.OrderID == editOrderViewModel.OrderId);
Trailer newTrailer = _context.Trailers.FirstOrDefault(t => t.TrailerID == editOrderViewModel.TrailerId);
Trailer oldTrailer = _context.Trailers.FirstOrDefault(t => t.TrailerID == order.TrailerId);
if (ModelState.IsValid)
{
order.OrderNumber = editOrderViewModel.OrderNumber;
order.CustomerId = editOrderViewModel.CustomerId;
if (oldTrailer.TrailerID != newTrailer.TrailerID)
{
oldTrailer.TrailerStatus = "Available";
newTrailer.TrailerStatus = "Unavailable";
}
order.TrailerId = newTrailer.TrailerID;
_context.SaveChanges();
return Redirect("/Order");
}
return Redirect("/Order/Edit");
}
Razor view page
#model WebApplication1.ViewModels.EditOrderViewModel
#{
ViewData["Title"] = "Edit Order";
}
<h2>#ViewData["Title"]</h2>
<form asp-controller="Order" asp-action="Edit" method="post">
<fieldset>
#Html.HiddenFor(o => o.OrderId)
<div>
<label asp-for="#Model.OrderNumber">Order number </label>
<input asp-for="#Model.OrderNumber" />
<span asp-validation-for="#Model.OrderNumber"></span>
</div>
<div>
<label asp-for="#Model.TrailerId">Customers Name</label>
<select asp-for="#Model.TrailerId" asp-items="#Model.Trailers"></select>
<span asp-validation-for="#Model.TrailerId"></span>
</div>
<div>
<label asp-for="#Model.CustomerId">Customers Name</label>
<select asp-for="#Model.CustomerId" asp-items="#Model.Customers"></select>
<span asp-validation-for="#Model.CustomerId"></span>
</div>
<div>
<input type="submit" value="Update" name="submitButton" />
</div>
</fieldset>
</form>
<p> <a asp-controller="Order" asp-action="Index">Cancel</a> </p>
I've tried using
return Page(editOrderViewModel);
and
return RedirectToAction(editOrderViewModel);
both methods returns the view page to the original state and that's not the expected result. I want to be able to see error message with all the valid and invalid data on the page so that able to correct and resubmit if necessary. How can I achieve this?
I just had to repopulate the data, pass it to the viewmodel and then pass it back to the View
[HttpPost]
public IActionResult Edit(EditOrderViewModel editOrderViewModel)
{
Order order = _context.Orders.FirstOrDefault(o => o.OrderID == editOrderViewModel.OrderId);
Trailer newTrailer = _context.Trailers.FirstOrDefault(t => t.TrailerID == editOrderViewModel.TrailerId);
Trailer oldTrailer = _context.Trailers.FirstOrDefault(t => t.TrailerID == order.TrailerId);
if (ModelState.IsValid)
{
order.OrderNumber = editOrderViewModel.OrderNumber;
order.CustomerId = editOrderViewModel.CustomerId;
if (oldTrailer.TrailerID != newTrailer.TrailerID)
{
oldTrailer.TrailerStatus = "Available";
newTrailer.TrailerStatus = "Unavailable";
}
order.TrailerId = newTrailer.TrailerID;
_context.SaveChanges();
return Redirect("/Order");
}
var orderToEdit = _context.Orders.Include(t => t.Trailer).Include(c => c.Customer).Where(o => o.OrderID == editOrderViewModel.OrderId).SingleOrDefault();
var trailers = _context.Trailers.Where(x => x.TrailerStatus == "Available" || x.TrailerID == orderToEdit.TrailerId).ToList();
var customers = _context.Customers.ToList();
EditOrderViewModel repopulateViewModel = new EditOrderViewModel(orderToEdit, trailers, customers);
return View(repopulateViewModel);
}

Edit Cascade DropDownList using ASP.NET Core MVC

I'm having trouble retrieving/displaying the CityId value from the database to the City drop down list based on the selected Customer's ID that I wish to Edit.
When I select a Customer to Edit it populates the data from the database properly except for the City drop down list. The City drop down list will show "Select a City" along with all Cities that are related to the State in the State drop down list.
If I select another state then it loads all cities for the selected state properly.
The problem is that it does not show the City value for the City drop down list like it should when I first load the page based on the selected Customer ID.
I'm very new to jQuery/AJAX and I had someone help me with the jQuery code for the cascade drop down lists.
I supplied my ViewModel, Controller and Edit View that I'm using now below:
Customer Model
public class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int CityId { get; set; }
public City City { get; set; }
public int LocalityId { get; set; }
public Locality Locality { get; set; }
public int SubLocalityId { get; set; }
public SubLocality SubLocality { get; set; }
}
City Model
public class City
{
public int ID { get; set; }
public string Name { get; set; }
public List<Customer> Customers { get; set; }
public List<Locality> Localities { get; set; }
}
Locality Model
public class Locality
{
public int ID { get; set; }
public string Name { get; set; }
public int CityId { get; set; }
public City City { get; set; }
public List<Customer> Customers { get; set; }
public List<SubLocality> SubLocalities { get; set; }
}
SubLocality Model
public class SubLocality
{
public int ID { get; set; }
public string Name { get; set; }
public int LocalityId { get; set; }
public Locality Locality { get; set; }
public List<Customer> Customers { get; set; }
}
WebAppDbContext
public class WebAppDbContext : DbContext
{
public WebAppDbContext(DbContextOptions<WebAppDbContext> options) : base(options)
{ }
public DbSet<Customer> Customers { get; set; }
public DbSet<City> Cities { get; set; }
public DbSet<Locality> Localities { get; set; }
public DbSet<SubLocality> SubLocalities { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>()
.HasKey(c => c.CustomerId);
modelBuilder.Entity<Customer>()
.Property(c => c.FirstName)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<Customer>()
.Property(c => c.LastName)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<City>()
.HasKey(ci => ci.ID);
modelBuilder.Entity<City>()
.Property(ci => ci.Name)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<City>()
.HasMany(ci => ci.Customers)
.WithOne(c => c.City)
.HasForeignKey(c => c.CityId);
modelBuilder.Entity<City>()
.HasMany(l => l.Localities)
.WithOne(ci => ci.City)
.HasForeignKey(ci => ci.CityId);
modelBuilder.Entity<Locality>()
.HasKey(l => l.ID);
modelBuilder.Entity<Locality>()
.Property(l => l.Name)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<Locality>()
.HasMany(l => l.Customers)
.WithOne(c => c.Locality)
.HasForeignKey(c => c.LocalityId);
modelBuilder.Entity<Locality>()
.HasMany(sl => sl.SubLocalities)
.WithOne(l => l.Locality)
.HasForeignKey(l => l.LocalityId);
modelBuilder.Entity<SubLocality>()
.HasKey(sl => sl.ID);
modelBuilder.Entity<SubLocality>()
.Property(sl => sl.Name)
.HasColumnType("varchar(50)")
.HasMaxLength(50)
.IsRequired();
modelBuilder.Entity<SubLocality>()
.HasMany(sl => sl.Customers)
.WithOne(c => c.SubLocality)
.HasForeignKey(c => c.SubLocalityId);
}
}
CustomerFormVM
public class CustomerFormVM
{
[Required(ErrorMessage = "Please enter a First Name")]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required(ErrorMessage = "Please enter a Last Name")]
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Required(ErrorMessage = "Please select a city")]
[Display(Name = "City")]
public int? SelectedCity { get; set; }
[Required(ErrorMessage = "Please select a locality")]
[Display(Name = "Locality")]
public int? SelectedLocality { get; set; }
[Required(ErrorMessage = "Please select a sub locality")]
[Display(Name = "Sub Locality")]
public int? SelectedSubLocality { get; set; }
public SelectList CityList { get; set; }
public SelectList LocalityList { get; set; }
public SelectList SubLocalityList { get; set; }
}
CustomersController
public class CustomersController : Controller
{
private readonly WebAppDbContext _context;
public CustomersController(WebAppDbContext context)
{
_context = context;
}
// GET: Customers
public async Task<IActionResult> Index()
{
var webAppDbContext = _context.Customers.Include(c => c.City).Include(c => c.Locality).Include(c => c.SubLocality);
return View(await webAppDbContext.ToListAsync());
}
// GET: Customers/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var customer = await _context.Customers
.Include(c => c.City)
.Include(c => c.Locality)
.Include(c => c.SubLocality)
.SingleOrDefaultAsync(m => m.CustomerId == id);
if (customer == null)
{
return NotFound();
}
return View(customer);
}
// GET: Customers/Create
[HttpGet]
public ActionResult Create()
{
CustomerFormVM model = new CustomerFormVM();
ConfigureViewModel(model);
return View(model);
}
// POST: Customers/Create
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(CustomerFormVM vm)
{
if (ModelState.IsValid)
{
var customer = new Customer();
{
customer.FirstName = vm.FirstName;
customer.LastName = vm.LastName;
customer.CityId = vm.SelectedCity.Value;
customer.LocalityId = vm.SelectedLocality.Value;
customer.SubLocalityId = vm.SelectedSubLocality.Value;
}
_context.Customers.Add(customer);
_context.SaveChanges();
return RedirectToAction("Index");
}
else
{
ConfigureViewModel(vm);
return View(vm);
}
}
[HttpGet]
public JsonResult FetchLocalities(int ID)
{
var data = _context.Localities
.Where(l => l.CityId == ID)
.Select(l => new { val = l.ID, text = l.Name });
return Json(data);
}
[HttpGet]
public JsonResult FetchSubLocalities(int ID)
{
var data = _context.SubLocalities
.Where(l => l.LocalityId == ID)
.Select(l => new { val = l.ID, text = l.Name });
return Json(data);
}
private void ConfigureViewModel(CustomerFormVM model)
{
List<City> cities = _context.Cities.ToList();
model.CityList = new SelectList(cities, "ID", "Name");
if (model.SelectedCity.HasValue)
{
IEnumerable<Locality> localities = _context.Localities.Where(l => l.CityId == model.SelectedCity.Value);
model.LocalityList = new SelectList(localities, "ID", "Name");
}
else
{
model.LocalityList = new SelectList(Enumerable.Empty<SelectListItem>());
}
if (model.SelectedLocality.HasValue)
{
IEnumerable<SubLocality> subLocalities = _context.SubLocalities.Where(l => l.LocalityId == model.SelectedLocality.Value);
model.SubLocalityList = new SelectList(subLocalities, "ID", "Name");
}
else
{
model.SubLocalityList = new SelectList(Enumerable.Empty<SelectListItem>());
}
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var customervm = new CustomerFormVM();
{
Customer customer = _context.Customers.SingleOrDefault(c => c.CustomerId == id);
if (customer == null)
{
return NotFound();
}
customervm.CustomerId = customer.CustomerId;
customervm.FirstName = customer.FirstName;
customervm.LastName = customer.LastName;
}
return View(customervm);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(CustomerFormVM vmEdit)
{
if (ModelState.IsValid)
{
Customer customer = _context.Customers.SingleOrDefault(c => c.CustomerId == vmEdit.CustomerId);
if (customer == null)
{
return NotFound();
}
customer.FirstName = vmEdit.FirstName;
customer.LastName = vmEdit.LastName;
_context.Entry(customer).State = EntityState.Modified;
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(vmEdit);
}
// GET: Customers/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var customer = await _context.Customers
.Include(c => c.City)
.Include(c => c.Locality)
.Include(c => c.SubLocality)
.SingleOrDefaultAsync(m => m.CustomerId == id);
if (customer == null)
{
return NotFound();
}
return View(customer);
}
// POST: Customers/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var customer = await _context.Customers.SingleOrDefaultAsync(m => m.CustomerId == id);
_context.Customers.Remove(customer);
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
private bool CustomerExists(int id)
{
return _context.Customers.Any(e => e.CustomerId == id);
}
}
Create View
#using (Html.BeginForm("Create", "Customers"))
{
<div class="form-group">
#Html.LabelFor(c => c.FirstName)
#Html.TextBoxFor(c => c.FirstName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(c => c.LastName)
#Html.TextBoxFor(c => c.LastName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.SelectedCity)
#Html.DropDownListFor(m => m.SelectedCity, Model.CityList, "Please select", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SelectedCity)
</div>
<div class="form-group">
#Html.LabelFor(m => m.SelectedLocality)
#Html.DropDownListFor(m => m.SelectedLocality, Model.LocalityList, "", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SelectedLocality)
</div>
<div class="form-group">
#Html.LabelFor(m => m.SelectedSubLocality)
#Html.DropDownListFor(m => m.SelectedSubLocality, Model.SubLocalityList, "", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SelectedSubLocality)
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default" />
</div>
}
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
var localityUrl = '#Url.Action("FetchLocalities")';
var subLocalityUrl = '#Url.Action("FetchSubLocalities")';
var localities = $('#SelectedLocality');
var subLocalities = $('#SelectedSubLocality');
$('#SelectedCity').change(function() {
localities.empty();
subLocalities.empty();
$.getJSON(localityUrl, { ID: $(this).val() },function (data) {
if (!data) {
return;
}
localities.append($('<option></option>').val('').text('Please select'));
$.each(data, function(index, item) {
localities.append($('<option></option>').val(item.val).text(item.text));
});
});
})
$('#SelectedLocality').change(function() {
subLocalities.empty();
$.getJSON(subLocalityUrl, { ID: $(this).val() },function (data) {
if (!data) {
return;
}
subLocalities.append($('<option></option>').val('').text('Please Select'));
$.each(data, function(index, item) {
subLocalities.append($('<option></option>').val(item.val).text(item.text));
});
});
})
</script>
}
Edit View
#using (Html.BeginForm("Edit", "Customers"))
{
<div class="form-group">
#Html.LabelFor(c => c.FirstName)
#Html.TextBoxFor(c => c.FirstName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(c => c.LastName)
#Html.TextBoxFor(c => c.LastName, new { #class = "form-control" })
</div>
<div class="form-group">
#Html.LabelFor(m => m.SelectedCity)
#Html.DropDownListFor(m => m.SelectedCity, Model.CityList, "Please select", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SelectedCity)
</div>
<div class="form-group">
#Html.LabelFor(m => m.SelectedLocality)
#Html.DropDownListFor(m => m.SelectedLocality, Model.LocalityList, "", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SelectedLocality)
</div>
<div class="form-group">
#Html.LabelFor(m => m.SelectedSubLocality)
#Html.DropDownListFor(m => m.SelectedSubLocality, Model.SubLocalityList, "", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.SelectedSubLocality)
</div>
#Html.HiddenFor(m => m.CustomerId)
<div class="form-group">
<input type="submit" value="Save" class="btn btn-default" />
</div>
}
<div>
<a asp-action="Index">Back to List</a>
</div>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script type="text/javascript">
var localityUrl = '#Url.Action("FetchLocalities")';
var subLocalityUrl = '#Url.Action("FetchSubLocalities")';
var localities = $('#SelectedLocality');
var subLocalities = $('#SelectedSubLocality');
$('#SelectedCity').change(function() {
localities.empty();
subLocalities.empty();
$.getJSON(localityUrl, { ID: $(this).val() },function (data) {
if (!data) {
return;
}
localities.append($('<option></option>').val('').text('Please select'));
$.each(data, function(index, item) {
localities.append($('<option></option>').val(item.val).text(item.text));
});
});
})
$('#SelectedLocality').change(function() {
subLocalities.empty();
$.getJSON(subLocalityUrl, { ID: $(this).val() },function (data) {
if (!data) {
return;
}
subLocalities.append($('<option></option>').val('').text('Please Select'));
$.each(data, function(index, item) {
subLocalities.append($('<option></option>').val(item.val).text(item.text));
});
});
})
</script>
}
Probably you missing this directive on the View:
#using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, new { #class = "form-horizontal", role = "form" }))

ASP.Net MVC page posting to controller and not returning record ID in address bar

I have a Razor page that displays a list of meetings. Each meeting has a id which is an attribute of a link assigned to each meeting which when clicked loads another Razor View showing the meeting details. This view calls a childAction which loads a partial page, displaying dropdown containing all available attendees and a <div> which will show a form if new visitors need to be created. The URL of the details page looks like
http://localhost:53533/Meetings/AddVisitors/18
I can select a visitor from the dropdown list and I have a working method that create a new record linking the visitor to the meeting. The methods returns the view having added the record, but the details are not shown in the refreshed table and the meeting id has gone from the page URL.
The method to show the page is:
public ActionResult AddVisitors(int? id)
{
var meetings = db.Meetings.Include("Host").Include("VisitorsMeetings").Where(x => x.id == id).FirstOrDefault();
return View(meetings);
}
The method that creates the visitor/meeting record is:
[HttpPost]
public ActionResult AddVisitors(VisitorList model)
{
VisitorMeeting newVisitorMeeting = new VisitorMeeting
{
MeetingId = model.meetingId,
VisitorId = model.SelectedId,
Arrived = false,
Departed = false,
BadgePrinted = false
};
db.VisitorMeetings.Add(newVisitorMeeting);
db.SaveChanges();
var meetings = db.Meetings.Include("Host").Include("VisitorsMeetings").Where(x => x.id == model.meetingId).FirstOrDefault();
return AddVisitors(model.meetingId);
}
The view is:
#model VisitorManager.Models.Meeting
....
<div>
<h4>Meeting</h4>
<dl class="dl-horizontal">
<dt>#Html.DisplayNameFor(model => model.Host.Name)</dt>
<dd>#Html.DisplayFor(model => model.Host.Name)</dd>
<dt>#Html.DisplayNameFor(model => model.StartTime)</dt>
<dd>#Html.DisplayFor(model => model.StartTime)</dd>
... // more properties of Meeting
</dl>
</div>
<h4>Visitor List</h4>
<div>
<table class="table">
<tr>
<th>Visitor Name</th>
<th>Company</th>
...
<th></th>
</tr>
#foreach (var item in Model.VisitorsMeetings)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.Visitor.VisitorName</td>
<td>#Html.DisplayFor(modelItem => item.Visitor.Company)</td>
<td>#Html.DisplayFor(modelItem => item.Arrived)</td>
....
<td>#Html.ActionLink("Delete", "Delete", new { id = item.VisitorId })</td>
</tr>
}
</table>
</div>
// Add partial view to show drop down of all visitors
#Html.Action("VisitorList", "Meetings")
#section Scripts{
<script type="text/javascript">
var dialog = $('#dialog-mask');
$('#addVisitor').click(
function () {
$('#VisitorModal').load('#Url.Action("Add", "Meetings")');
//$('#VisitorModal').find('form')[0].reset();
//dialog.find('form')[0].reset();
dialog.show();
}
);
$('#cancel').on('click', function () {
dialog.hide();
return false;
});
$('#VisitorModal').on('submit', '#visitorform', function () {
var data = $(this).serialize();
var url = '#Url.Action("AddVisitors", "Meetings")';
var text = $('#title').val() + ' ' + $('#firstname').val() + ' ' + $('#surname').val() + ' (' + $('#company').val() + ')'; // a value from the form that you want as the option text
$.post(url, data, function (response) {
if (response) {
$('#VisitorID').append($('<option></option>').val(response).text(text)).val(response);
} else {
dialog.hide();
// Oops
}
}).fail(function () {
// Oops
dialog.hide();
});
// ... close the modal
//$('#VisitorModal').hide();
//$('#VisitorModal').find('form')[0].reset();
dialog.hide();
return false; // cancel the default submit
});
</script>
}
The PartialView is:
#using VisitorManager.Models
#model VisitorList
#{
Layout = null;
}
#using (Html.BeginForm("AddVisitors", "Meetings"))
{
#Html.AntiForgeryToken()
<hr />
<div class="form-horizontal">
<h4>Add A Visitor</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.Label("Visitor Name", htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-4">
#Html.DropDownListFor(m => m.SelectedId, Model.Data, "- Please select -", htmlAttributes: new { #class = "form-control", #id="VisitorID" })
</div>
<button type="button" id="addVisitor" class="btn btn-success">Create new Visitor</button>
</div>
#Html.HiddenFor(m=>m.meetingId)
<div class="form-group">
<div class="col-md-offset-4 col-md-8">
<input type="submit" value="Add Visitor" class="btn btn-default" />
</div>
</div>
</div>
}
<div id="dialog-mask">
<div id="dialog" style="width:500px; height:auto;">
<div id="VisitorModal"></div>
</div>
</div>
VisitorList Action:
[ChildActionOnly]
public ActionResult VisitorList()
{
var dropDownData = db.Visitors.OrderBy(z => z.Company).ThenBy(y=>y.LastName).ThenBy(x=>x.FirstName)
.Select(d => new SelectListItem
{
Text = d.Title + " " + d.FirstName + " " + d.LastName + " (" + d.Company + ")",
Value = d.id.ToString()
});
var model = new VisitorList
{
Data = dropDownData,
meetingId = 18
};
return PartialView(model);
}
VisitorList viewmodel:
public class VisitorList
{
public IEnumerable<SelectListItem> Data { get; set; }
public int SelectedId { get; set; }
public int meetingId { get; set; }
}
Meeting model:
public class Meeting
{
public int id { get; set; }
[Display(Name="Start Time", Prompt = "Please supply a start date and time.")]
[Required(ErrorMessage = "Please supply a start date and time.")]
[DataType(DataType.DateTime)]
public DateTime StartTime { get; set; }
.... // more properties
[Required]
[ForeignKey("Host")]
[Display(Name="Meeting Host")]
public int HostId { get; set; }
[Display(Name="Meeting Host")]
public virtual Host Host { get; set; }
public ICollection<VisitorMeeting> VisitorsMeetings { get; set; }
}
Visitor Model:
public class Visitor
{
public int id { get; set; }
[Display(Name="Visitor Title")]
[Required]
public string Title { get; set; }
[Display(Name="Visitor Firstname")]
[Required]
public string FirstName { get; set; }
[Display(Name="Visitor Lastname")]
[Required]
public string LastName { get; set; }
[Display(Name="Company Name")]
[Required]
public string Company { get; set; }
[NotMapped]
[Display(Name="Visitor Name")]
public string VisitorName
{
get
{
return Title + " " + FirstName + " " + LastName;
}
}
public ICollection<VisitorMeeting> VisitorsMeetings { get; set; }
}
VisitorMeeting Model:
public class VisitorMeeting
{
public int Id { get; set; }
[Display(Name="Visitor Arrived")]
[Required]
public bool Arrived { get; set; }
.... // more properties
[Required]
[ForeignKey("Meeting")]
public int MeetingId { get; set; }
public virtual Meeting Meeting{ get; set; }
[Required]
[ForeignKey("Visitor")]
public int VisitorId { get; set; }
public virtual Visitor Visitor { get; set; }
}
Can anyone tell me How I keep the meeting ID in the AddVisitors URL and why the complete added visitor row isn't correctly showing in the list of visitors displayed in the partial view called by the child action?
There is several options to do so.
I advise you to use post-redirect-get pattern as it will safe for user to refresh page any time:
[HttpPost]
public ActionResult AddVisitors(VisitorList model)
{
// ...
return this.Redirect("AddVisitors", new { id = model.meetingId});
}
Another way is to generate appropriate post url. Look like you use default route mapping, so valid url should be generated:
#using (Html.BeginForm("AddVisitors", "Meetings", new { id = Model.meetingId }))

How do I send drop down list selection to my controller

I will start by saying that I am very new to asp.net MVC, but have a project that i need to complete. That being said, any help is greatly appreciated.
I have two cascading dropdown lists created and populating with MVC, LINQ to SQL and Ajax that i need the selections brought into my controller. I am trying to simply create and send an email with my form data in the body and have been stuck for some time. The Javascript returns the Id number from the database, but i need the "StateName and "CountyName" that is associated with the Id rather than just the Id. For a reference, this is the method that I used to create what I have now, but there was no explanation on how to submit the selections.
http://www.codeproject.com/Articles/730953/Cascading-Dropdown-List-With-MVC-LINQ-to-SQL-and-A
Here is my Controller
public class AddressController : Controller
{
private IAddressRepository _repository;
public AddressController() : this(new AddressRepository())
{
}
public AddressController(IAddressRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
AddressModel model = new AddressModel();
model.AvailableUSStates.Add(new SelectListItem { Text = "-Please select-", Value = "Selects items" });
var usstates = _repository.GetAllUSStates();
foreach (var usstate in usstates)
{
model.AvailableUSStates.Add(new SelectListItem()
{
Text = usstate.USStateName,
Value = usstate.USStateID.ToString()
});
}
return View(model);
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetCountiesByUSStateID(string USStateID)
{
if (string.IsNullOrEmpty(USStateID))
{
throw new ArgumentNullException("USStateID");
}
int id = 0;
bool isValid = Int32.TryParse(USStateID, out id);
var counties = _repository.GetAllCountiesByUSStateID(id);
var result = (from s in counties
select new
{
id = s.CountyID,
name = s.CountyName
}).ToList();
return Json(result, JsonRequestBehavior.AllowGet);
}
[HttpPost]
public ContentResult SimplePost(string submittedState)
{
string result = string.Format(submittedState);
return new ContentResult { Content = result };
}
[AcceptVerbs(HttpVerbs.Post)]
public async Task<ActionResult> Index([Bind(Include = "USStateName, CountyName")] AddressModel addressModel)
{
if (ModelState.IsValid)
{
MailMessage message = new MailMessage();
message.From = new MailAddress("address#gmail.com");
message.To.Add(new MailAddress("address#hotmail.com"));
message.Subject = "";
message.Body = "";
SmtpClient client = new SmtpClient();
client.Send(message);
return View("Index");
}
else
{
return View();
}
}
}
Model
namespace msifla.Models
{
public class AddressModel
{
public AddressModel()
{
AvailableUSStates = new List<SelectListItem>();
AvailableCounties = new List<SelectListItem>();
}
[Display(Name = "USState")]
public int USStateID { get; set; }
public List<SelectListItem> AvailableUSStates { get; set; }
[Display(Name = "County")]
public int CountyID { get; set; }
public List<SelectListItem> AvailableCounties { get; set; }
}
}
View
#model msifla.Models.AddressModel
#{
ViewBag.Title = "Index";
}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(function () {
$("#USStateID").change(function () {
var selectedItem = $(this).val();
var ddlCounties = $("#CountyID");
var countiesProgress = $("#counties-loading-progress");
$('.selItem').remove();
var selectedItem2 = $('<p class="selItem">' + selectedItem + '</p>');
$('.usState').append(selectedItem2);
//$('.usState').append($('<p>This works here</p>'));
countiesProgress.show();
$.ajax({
cache: false,
type: "GET",
url: "#(Url.RouteUrl("GetCountiesByUSStateID"))",
data: { "USStateID": selectedItem },
success: function (data) {
ddlCounties.html('');
$.each(data, function (id, option) {
ddlCounties.append($('<option> </option>').val(option.id).html(option.name));
});
alert(option.name);
countiesProgress.hide();
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Failed to retrieve states.');
countiesProgress.hide();
}
});
});
});
</script>
#using (Html.BeginForm())
{
<div>
#Html.LabelFor(model => model.USStateID)
#Html.DropDownListFor(model => model.USStateID, Model.AvailableUSStates)
</div>
<br />
<div>
#Html.LabelFor(model => model.CountyID)
#Html.DropDownListFor(model => model.CountyID, Model.AvailableCounties)
<span id="counties-loading-progress" style="display: none;">Please wait..</span>
</div>
<div class="usState"></div>
<input name="submit" type="submit" id="submit" value="Save"/>
<label id="stateLabel"></label>
}
Let me know if you need to see the repository.
Thank you in advance for your help.
Edit
I know this is old, but I found a solution and wanted to post it here. It has been a while since i fixed my issue so I don't remember where I found the solution, but here it is:
Controller
public ActionResult Index()
{
AddressModel model = new AddressModel();
model.AvailableUSStates.Add(new SelectListItem { Text = "-Please select-", Value = "Selects items" });
model.AvailableLibraries.Add(new SelectListItem { Text = "-Please select-", Value = "Selects items" });
var usstates = _repository.GetAllUSStates();
foreach (var usstate in usstates)
{
model.AvailableUSStates.Add(new SelectListItem()
{
Text = usstate.USStateName,
Value = usstate.USStateID.ToString()
});
}
return View(model);
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetLibrariesByUSStateID(string USStateID)
{
if (string.IsNullOrEmpty(USStateID))
{
throw new ArgumentNullException("USStateID");
}
int id = 0;
bool isValid = Int32.TryParse(USStateID, out id);
var counties = _repository.GetAllLibrariesByUSStateID(id);
var result = (from s in counties
select new
{
id = s.LibraryID,
name = s.LibraryName
}).ToList();
return Json(result, JsonRequestBehavior.AllowGet);
}
[AcceptVerbs(HttpVerbs.Post)]
//[ValidateAntiForgeryToken]
public ActionResult Index(AddressModel model)
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
if (ModelState.IsValid)
{
ConfirmModel model2 = new ConfirmModel();
model2.USStateName = SelectedUSState(model.USStateID.ToString());
model2.CountyName = SelectedCounty(model.LibraryID.ToString(), model.USStateID.ToString());
model2.CountyID = model.LibraryID;
model2.clientID = model.clientId.ToString();
return View("Confirmation", model2);
}
return View(model);
}
public ActionResult Confirmation(AddressModel model2)
{
ConfirmModel model = new ConfirmModel();
model.USStateName = SelectedUSState(model2.USStateID.ToString());
model.CountyName = SelectedCounty(model2.LibraryID.ToString(), model2.USStateID.ToString());
var USStateName = model.USStateName;
return View(model);
}
//[AcceptVerbs(HttpVerbs.Get)]
//public ActionResult Confirmation(ConfirmModel model)
//{
// string USStateName = model.USStateName;
// return View();
//}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult submitConfirmation(ConfirmModel model)
{
if (ModelState.IsValid)
{
string usStateName = model.USStateName;
string countyName = model.CountyName;
DateTime dateTime = DateTime.Now;
string ipAddress = Request.UserHostAddress;
string ipAddress2 = Request.ServerVariables["Remote_Addr"];
string userAgent = Request.UserAgent;
MailMessage message = new MailMessage();
message.From = new MailAddress("someone#domain.com");
message.To.Add(new MailAddress("someoneElse#domain.com"));
message.Subject = "Subject";
// You need to use Index because that is the name declared above
message.Body = "<!DOCTYPE html><head></head><body>" +
"<pre>State:\t\t" + usStateName + "</pre>" +
"<pre>County:\t\t" + countyName + "</pre>" +
"<pre>Remote Name:\t" + ipAddress + "</pre>" +
"<pre>Remote User:\t" + userAgent + "</pre>" +
"<pre>Date:\t" + dateTime.ToLongDateString() + "</pre>" +
"<pre>Time:\t" + dateTime.ToLongTimeString() + "</pre>" +
"\n"
"</body>";
message.IsBodyHtml = true;
SmtpClient client = new SmtpClient();
client.Send(message);
return RedirectToAction("Index");
}
return View(model);
}
[HttpPost]
public ActionResult resetConfirmation()
{
return RedirectToAction("Index");
}
public string SelectedUSState(string USStateID)
{
ViewBag.YouSelected = USStateID.ToString();
AddressModel model = new AddressModel();
int id = 0;
int usStateIDInt = int.Parse(USStateID);
bool isValid = Int32.TryParse(USStateID, out id);
var usstates = _repository.GetAllUSStates();
var state = from s in _repository.GetAllUSStates()
where s.USStateID.ToString() == USStateID
select s.USStateName;
var currUSState = state.SingleOrDefault();
//var currUSStatename = usstates.te
//model.USStateName = currUSState;
ViewBag.currUSState = currUSState;
return currUSState;
}
public string SelectedCounty(string CountyID, string USStateID)
{
AddressModel model = new AddressModel();
int id = 0;
int countyIDInt = int.Parse(CountyID);
bool isValid = Int32.TryParse(CountyID, out id);
int usStateIDInt = int.Parse(USStateID);
var counties = _repository.GetAllLibrariesByUSStateID(usStateIDInt);
var county = from s in counties
where s.LibraryID.ToString() == CountyID
select s.LibraryName;
var currCounty = county.SingleOrDefault();
ViewBag.currCounty = currCounty;
return currCounty;
}
Model
public class AddressModel
{
public AddressModel()
{
AvailableUSStates = new List<SelectListItem>();
AvailableLibraries = new List<SelectListItem>();
}
[Display(Name = "USState")]
[Required(ErrorMessage = ("Please choose a State"))]
public int USStateID { get; set; }
//public string USStateName { get; set; }
public List<SelectListItem> AvailableUSStates { get; set; }
[Display(Name = "Library")]
[Required(ErrorMessage = ("Please chose a Library for the selected State"))]
public int LibraryID { get; set; }
public List<SelectListItem> AvailableLibraries { get; set; }
}
public class ConfirmModel
{
[Display(Name = "State Name")]
public string USStateName { get; set; }
[Display(Name = "County Name")]
public string CountyName { get; set; }
}
View
#model msifla2.Models.MSIProModel
#{
ViewBag.Title = "HCOrder";
}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
#*<script src="~/Scripts/angular.min.js"></script>*#
#*<script src="~/Scripts/cascade.js"></script>*#
<script type="text/javascript">
$(function () {
$("#USStateDDL").change(function () {
var selectedItem = $(this).val();
var ddlLibraries = $("#LibraryID");
var librariesProgress = $("#libraries-loading-progress");
librariesProgress.show();
$.ajax({
cache: false,
type: "GET",
url: "#(Url.RouteUrl("GetLibrariesByUSStateID"))",
data: { "USStateID": selectedItem },
success: function (data) {
ddlLibraries.html('');
$.each(data, function (id, option) {
ddlLibraries.append($('<option>Select a Library</option>').val(option.id).html(option.name));
});
librariesProgress.hide();
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Failed to retrieve libraries.');
librariesProgress.hide();
}
});
});
});
</script>
#*<script>
$(function () {
$('#USStateDDL').change(function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
data: { selectedValue: $('#USStateDDL').val() },
success: function (result) {
alert('#USStateDDL').val();
}
})
var selected = $(this).val();
alert(selected + " 1 selected")
$('#USStateLabel').load(input)
});
});
</script>*#
<div class="jumbotron">
</div>
<div class="container article">
<div data-ng-app="myModule" class="col-md-9 article_main container-fluid">
<h2>Header</h2>
#using (Html.BeginForm("Address", "Home", FormMethod.Post))
{
<div class="edit-label">
#Html.LabelFor(model => model.USStateID, new { id = "USStateLabel", #class = "col-xs-3" })
</div>
<div class="edit-field, col-xs-9">
#Html.DropDownListFor(model => model.USStateID, Model.AvailableUSStates, new { #class = "form-control dropdowns", id = "USStateDDL" })
</div>
#Html.LabelFor(model => model.LibraryID, new { #class = "col-xs-3" })
<div class=" col-xs-9">
#Html.DropDownListFor(model => model.LibraryID, Model.AvailableLibraries, new { #class = "form-control" })
</div>
<div class="col-xs-9 col-xs-offset-3" style="padding-top:5px;">
<input type="submit" id="submit" value="Send" class="btn-success btn" />
</div>
}
</div>
</div>
</div>
</div>
Confirm View
#model msifla2.Models.ConfirmModel
#{
ViewBag.Title = "Confirmation";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Confirmation</h2>
#using (Html.BeginForm("submitConfirmation", "Home", FormMethod.Post))
{
<div data-ng-app="myModule" class="col-md-9 article_main">
<div>
<h4>Please check your order and select <b>Confirm</b> to submit</h4>
</div>
<div class="row">
#Html.LabelFor(model => model.USStateName, new { #class = "col-xs-3" })
#Html.DisplayTextFor(model => model.USStateName)
#Html.HiddenFor(model => model.USStateName)
</div>
<div class="row">
#Html.LabelFor(model => model.CountyName, new { #class = "col-xs-3" })
#Html.DisplayTextFor(model => model.CountyName)
#Html.HiddenFor(model => model.CountyName)
</div>
<input type="submit" formaction="/home/submitConfirmation" value="Confirm" />
<input type="submit" formaction="/Home/resetConfirmation" value="Reset" />
</div>
}
I think I included everything. Let me know if you see something missing, but it's working for me.
If I understood your question correctly:
change
ddlCounties.append($('<option> </option>').val(option.id).html(option.name));
to
ddlCounties.append($('<option> </option>').val(option.name).html(option.name));
your model should also have the Name.
I know this is old, but I found a solution and wanted to post it here. It has been a while since i fixed my issue so I don't remember where I found the solution, but here it is:
Controller
public ActionResult Index()
{
AddressModel model = new AddressModel();
model.AvailableUSStates.Add(new SelectListItem { Text = "-Please select-", Value = "Selects items" });
model.AvailableLibraries.Add(new SelectListItem { Text = "-Please select-", Value = "Selects items" });
var usstates = _repository.GetAllUSStates();
foreach (var usstate in usstates)
{
model.AvailableUSStates.Add(new SelectListItem()
{
Text = usstate.USStateName,
Value = usstate.USStateID.ToString()
});
}
return View(model);
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult GetLibrariesByUSStateID(string USStateID)
{
if (string.IsNullOrEmpty(USStateID))
{
throw new ArgumentNullException("USStateID");
}
int id = 0;
bool isValid = Int32.TryParse(USStateID, out id);
var counties = _repository.GetAllLibrariesByUSStateID(id);
var result = (from s in counties
select new
{
id = s.LibraryID,
name = s.LibraryName
}).ToList();
return Json(result, JsonRequestBehavior.AllowGet);
}
[AcceptVerbs(HttpVerbs.Post)]
//[ValidateAntiForgeryToken]
public ActionResult Index(AddressModel model)
{
var errors = ModelState.Values.SelectMany(v => v.Errors);
if (ModelState.IsValid)
{
ConfirmModel model2 = new ConfirmModel();
model2.USStateName = SelectedUSState(model.USStateID.ToString());
model2.CountyName = SelectedCounty(model.LibraryID.ToString(), model.USStateID.ToString());
model2.CountyID = model.LibraryID;
model2.clientID = model.clientId.ToString();
return View("Confirmation", model2);
}
return View(model);
}
public ActionResult Confirmation(AddressModel model2)
{
ConfirmModel model = new ConfirmModel();
model.USStateName = SelectedUSState(model2.USStateID.ToString());
model.CountyName = SelectedCounty(model2.LibraryID.ToString(), model2.USStateID.ToString());
var USStateName = model.USStateName;
return View(model);
}
//[AcceptVerbs(HttpVerbs.Get)]
//public ActionResult Confirmation(ConfirmModel model)
//{
// string USStateName = model.USStateName;
// return View();
//}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult submitConfirmation(ConfirmModel model)
{
if (ModelState.IsValid)
{
string usStateName = model.USStateName;
string countyName = model.CountyName;
DateTime dateTime = DateTime.Now;
string ipAddress = Request.UserHostAddress;
string ipAddress2 = Request.ServerVariables["Remote_Addr"];
string userAgent = Request.UserAgent;
MailMessage message = new MailMessage();
message.From = new MailAddress("someone#domain.com");
message.To.Add(new MailAddress("someoneElse#domain.com"));
message.Subject = "Subject";
// You need to use Index because that is the name declared above
message.Body = "<!DOCTYPE html><head></head><body>" +
"<pre>State:\t\t" + usStateName + "</pre>" +
"<pre>County:\t\t" + countyName + "</pre>" +
"<pre>Remote Name:\t" + ipAddress + "</pre>" +
"<pre>Remote User:\t" + userAgent + "</pre>" +
"<pre>Date:\t" + dateTime.ToLongDateString() + "</pre>" +
"<pre>Time:\t" + dateTime.ToLongTimeString() + "</pre>" +
"\n"
"</body>";
message.IsBodyHtml = true;
SmtpClient client = new SmtpClient();
client.Send(message);
return RedirectToAction("Index");
}
return View(model);
}
[HttpPost]
public ActionResult resetConfirmation()
{
return RedirectToAction("Index");
}
public string SelectedUSState(string USStateID)
{
ViewBag.YouSelected = USStateID.ToString();
AddressModel model = new AddressModel();
int id = 0;
int usStateIDInt = int.Parse(USStateID);
bool isValid = Int32.TryParse(USStateID, out id);
var usstates = _repository.GetAllUSStates();
var state = from s in _repository.GetAllUSStates()
where s.USStateID.ToString() == USStateID
select s.USStateName;
var currUSState = state.SingleOrDefault();
//var currUSStatename = usstates.te
//model.USStateName = currUSState;
ViewBag.currUSState = currUSState;
return currUSState;
}
public string SelectedCounty(string CountyID, string USStateID)
{
AddressModel model = new AddressModel();
int id = 0;
int countyIDInt = int.Parse(CountyID);
bool isValid = Int32.TryParse(CountyID, out id);
int usStateIDInt = int.Parse(USStateID);
var counties = _repository.GetAllLibrariesByUSStateID(usStateIDInt);
var county = from s in counties
where s.LibraryID.ToString() == CountyID
select s.LibraryName;
var currCounty = county.SingleOrDefault();
ViewBag.currCounty = currCounty;
return currCounty;
}
Model
public class AddressModel
{
public AddressModel()
{
AvailableUSStates = new List<SelectListItem>();
AvailableLibraries = new List<SelectListItem>();
}
[Display(Name = "USState")]
[Required(ErrorMessage = ("Please choose a State"))]
public int USStateID { get; set; }
//public string USStateName { get; set; }
public List<SelectListItem> AvailableUSStates { get; set; }
[Display(Name = "Library")]
[Required(ErrorMessage = ("Please chose a Library for the selected State"))]
public int LibraryID { get; set; }
public List<SelectListItem> AvailableLibraries { get; set; }
}
public class ConfirmModel
{
[Display(Name = "State Name")]
public string USStateName { get; set; }
[Display(Name = "County Name")]
public string CountyName { get; set; }
}
View
#model msifla2.Models.MSIProModel
#{
ViewBag.Title = "HCOrder";
}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
#*<script src="~/Scripts/angular.min.js"></script>*#
#*<script src="~/Scripts/cascade.js"></script>*#
<script type="text/javascript">
$(function () {
$("#USStateDDL").change(function () {
var selectedItem = $(this).val();
var ddlLibraries = $("#LibraryID");
var librariesProgress = $("#libraries-loading-progress");
librariesProgress.show();
$.ajax({
cache: false,
type: "GET",
url: "#(Url.RouteUrl("GetLibrariesByUSStateID"))",
data: { "USStateID": selectedItem },
success: function (data) {
ddlLibraries.html('');
$.each(data, function (id, option) {
ddlLibraries.append($('<option>Select a Library</option>').val(option.id).html(option.name));
});
librariesProgress.hide();
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Failed to retrieve libraries.');
librariesProgress.hide();
}
});
});
});
</script>
#*<script>
$(function () {
$('#USStateDDL').change(function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
data: { selectedValue: $('#USStateDDL').val() },
success: function (result) {
alert('#USStateDDL').val();
}
})
var selected = $(this).val();
alert(selected + " 1 selected")
$('#USStateLabel').load(input)
});
});
</script>*#
<div class="jumbotron">
</div>
<div class="container article">
<div data-ng-app="myModule" class="col-md-9 article_main container-fluid">
<h2>Header</h2>
#using (Html.BeginForm("Address", "Home", FormMethod.Post))
{
<div class="edit-label">
#Html.LabelFor(model => model.USStateID, new { id = "USStateLabel", #class = "col-xs-3" })
</div>
<div class="edit-field, col-xs-9">
#Html.DropDownListFor(model => model.USStateID, Model.AvailableUSStates, new { #class = "form-control dropdowns", id = "USStateDDL" })
</div>
#Html.LabelFor(model => model.LibraryID, new { #class = "col-xs-3" })
<div class=" col-xs-9">
#Html.DropDownListFor(model => model.LibraryID, Model.AvailableLibraries, new { #class = "form-control" })
</div>
<div class="col-xs-9 col-xs-offset-3" style="padding-top:5px;">
<input type="submit" id="submit" value="Send" class="btn-success btn" />
</div>
}
</div>
</div>
</div>
</div>
Confirm View
#model msifla2.Models.ConfirmModel
#{
ViewBag.Title = "Confirmation";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Confirmation</h2>
#using (Html.BeginForm("submitConfirmation", "Home", FormMethod.Post))
{
<div data-ng-app="myModule" class="col-md-9 article_main">
<div>
<h4>Please check your order and select <b>Confirm</b> to submit</h4>
</div>
<div class="row">
#Html.LabelFor(model => model.USStateName, new { #class = "col-xs-3" })
#Html.DisplayTextFor(model => model.USStateName)
#Html.HiddenFor(model => model.USStateName)
</div>
<div class="row">
#Html.LabelFor(model => model.CountyName, new { #class = "col-xs-3" })
#Html.DisplayTextFor(model => model.CountyName)
#Html.HiddenFor(model => model.CountyName)
</div>
<input type="submit" formaction="/home/submitConfirmation" value="Confirm" />
<input type="submit" formaction="/Home/resetConfirmation" value="Reset" />
</div>
}
I think I included everything. Let me know if you see something missing, but it's working for me.

MVC4 DropDownList from DB

I'm trying to make very simple forum, but I have problem with DropDownList. I have two models:
ForumThread.cs
public partial class ForumThread
{
public ForumThread()
{
this.ForumCategory = new HashSet<ForumCategory>();
}
public int TH_ID { get; set; }
public System.DateTime DATE { get; set; }
public string TOPIC { get; set; }
public string USER { get; set; }
public virtual ICollection<ForumCategory> ForumCategory { get; set; }
}
ForumCategory.cs
public partial class ForumCategory
{
public ForumCategory()
{
this.ForumThread = new HashSet<ForumThread>();
}
public int CA_ID { get; set; }
public string CATEGORY { get; set; }
public bool isSelected { get; set; }
public virtual ICollection<ForumThread> ForumThread { get; set; }
}
I tried to make "Create" function with view:
Create
#model AnimeWeb.Models.ForumThread
#{
ViewBag.Title = "Create";
}
<h2>New Thread</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<div class="editor-field">
#Html.HiddenFor(model => model.TH_ID)
</div>
<div class="editor-label">
TOPIC
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TOPIC)
#Html.ValidationMessageFor(model => model.TOPIC)
</div>
<div class="editor-label">
CATEGORY
</div>
<div class="editor-field">
#Html.EditorFor(model => model.ForumCategory)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
And PartialView for ForumCategory:
ForumCategory
#model AnimeWeb.Models.FORUMCATEGORY
#Html.HiddenFor(model => model.CA_ID)
#Html.HiddenFor(model => model.CATEGORY)
<div>
#Html.DropDownListFor(item => Model.CA_ID, ViewBag.CA_ID as SelectList, "-- Select --")
</div>
ForumController
public ActionResult Create()
{
var db = new MainDatabaseEntities();
var viewModel = new ForumThread
{
ForumCategory = db.ForumCategory.Select(c => new { CA_ID = c.CA_ID, CATEGORY = c.CATEGORY, isSelected = false }).ToList().Select(g => new ForumCategory
{
CA_ID = g.CA_ID,
CATEGORY = g.CATEGORY,
isSelected = false
}).ToList(),
};
return View(viewModel);
}
//
// POST: /Forum/Create
[HttpPost]
public ActionResult Create(ForumThread forumthread, String user, int id)
{
var db = new MainDatabaseEntities();
var newthread = new ForumThread
{
TH_ID = forumthread.TH_ID,
DATE = DateTime.Now,
TOPIC = forumthread.TOPIC,
USER = forumthread.USER,
ForumCategory = new List<ForumCategory>()
};
foreach (var selectedCategory in forumthread.FORUMCATEGORY.Where(c => c.isSelected))
{
var category = new ForumCategory { CA_ID = selectedCategory.CA_ID };
db.ForumCategory.Attach(category);
newthread.ForumCategory.Add(category);
}
db.ForumThread.Add(newthread);
db.SaveChanges();
return RedirectToAction("Index");
}
And it obviously doesn't work. I tried to use other threads on this forum but nothing helped. Could someone explain me how to make this work?
The error is in partial view of ForumCategory:
The ViewData item that has the key 'CA_ID' is of type 'System.Int32' but must be of type 'IEnumerable<SelectListItem>'.
In your PartialView for ForumCategory, your cast is not correct:
#Html.DropDownListFor(item => Model.CA_ID, ViewBag.CA_ID as SelectList, "-- Select --")
You have to use a SelectList (List of SelectListItem) that you can implement for example in a method in your model:
public List<SelectListItem> GetCategories()
{
var db = new MainDatabaseEntities();
List<SelectListItem> list = new List<SelectListItem>();
// Add empty item if needed
SelectListItem commonItem = new SelectListItem();
commonItem.Text = "--- Select ---";
commonItem.Value = "-1";
commonItem.Selected = true;
list.Add(commonItem);
// Add items from Database
foreach (ForumCategory fc in db.ForumCategory)
{
SelectListItem i = new SelectListItem();
i.Text = fc.CATEGORY;
i.Value = fc.CA_ID.ToString();
list.Add(i);
}
return list;
}
And then you can have you dropdown like that:
#Html.DropDownList("DropName", Model.GetCategories())
There may be other errors in some parts of your code, I just answered to the one you quoted
In your editortemplate, you have:
ViewBag.CA_ID as SelectList
But you don't show where you fill the ViewBag. Instead you might want to do something like this:
#Html.DropDownListFor(m => m.CA_ID,
new SelectList(Model.ForumCategory,
"CA_ID", "CATEGORY", Model.CA_ID))
As also explained in MVC3 DropDownListFor - a simple example?.

Categories