Cascading DropDown Lists - What am I missing? - javascript

I've been following a tutorial on how to have one dropdown cascade from another, but am unable to get it to work. Any assistance would be greatly appreciated. I do not know javascript well, so fudging my way thru. I am not entirely sure I have the URL portion correct?
I am attempting to populate the ArrestDept dropdown and then filter and populate the ArrestOfficer dropdown based on the selected ArrestDept.
Here is what I have so far:
Relevant Part of View:
<td style="width: 20%">
<div class="mb-3">
<label asp-for="Incident.ArrestDept"></label>
<select id="agency" class="form-select"></select>
</div>
</td>
<td style="width: 20%">
<div class="mb-3">
<label asp-for="Incident.ArrestOfficer"></label>
<select id="officer" class="form-select"></select>
</div>
</td>
#section Scripts at bottom of View:
#section Scripts
{
<partial name="_ValidationScriptsPartial" />
<script type="text/javascript">
$(document).ready(function () {
$('#agency').attr('disabled', true);
$('#officer').attr('disabled', true);
LoadAgencies();
});
function LoadAgencies() {
$('#agency').empty();
$.ajax({
url: '/CreateModel/GetAgencies',
success: function (response) {
if (response != null && response != undefined && response.length > 0) {
$('#agency').attr('disabled', false);
$('#agency').append('
<option>---Select Arresting Agency---</option>');
$('#officer').append('
<option>---Select Arresting Officer---</option>');
$.each(response, function (i, data) {
$('#agency').append('
<option value=' + data.id + '>' + data.AgencyName + '</option>');
});
}
else {
$('#agency').attr('disabled', true);
$('#officer').attr('disabled', true);
$('#agency').append('
<option>---Arresting Agencies Not Available---</option>');
$('#officer').append('
<option>---Arresting Officers Not Available---</option>');
}
},
error: function (error) {
alert(error);
}
});
}
}
function LoadOfficers(agencyId) {
$('#officer').empty();
$.ajax({
url: '/CreateModel/GetOfficers?Id=' + agencyId,
success: function (response) {
if (response != null && response != undefined && response.length > 0) {
$('#officer').attr('disabled', false);
$('#officer').append('
<option>---Select Arresting Officer---</option>');
$.each(response, function (i, data) {
$('#officer').append('
<option value=' + data.id + '>' + data.OfficerDisplayName + '</option>');
});
}
else {
$('#officer').attr('disabled', true);
$('#officer').append('
<option>---Arresting Officers Not Available---</option>');
}
},
error: function (error) {
alert(error);
}
});
</script>
}
.cs for the View:
using DWITracker.Data;
using DWITracker.Model;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
namespace DWITracker.Pages.Incidents;
[BindProperties]
public class CreateModel : PageModel
{
private readonly ApplicationDbContext _db;
public Incident Incident { get; set; }
public CreateModel(ApplicationDbContext db)
{
_db = db;
}
public IEnumerable<City> DisplayCityData { get; set; }
public IEnumerable<County> DisplayPIAddressCountyData { get; set; }
public IEnumerable<Ethnicity> DisplayPIEthnicityData { get; set; }
public IEnumerable<ArrestMethod> DisplayArrestMethodData { get; set; }
public IEnumerable<Test> DisplayTestGivenData { get; set; }
public IEnumerable<Charge> DisplayChargeData { get; set; }
public IEnumerable<DrinkLocation> DisplayLastDrinkData { get; set; }
public IEnumerable<DrugRecognitionExpert> DisplayDrugExpertData { get; set; }
public async Task OnGet()
{
await _db.City.Select(a => a.CityName).ToListAsync();
DisplayCityData = await _db.City.ToListAsync();
await _db.County.Select(a => a.CountyName).ToListAsync();
DisplayPIAddressCountyData = await _db.County.ToListAsync();
await _db.Ethnicity.Select(a => a.EthnicityName).ToListAsync();
DisplayPIEthnicityData = await _db.Ethnicity.ToListAsync();
await _db.ArrestMethod.Select(a => a.ArrestMethodDesc).ToListAsync();
DisplayArrestMethodData = await _db.ArrestMethod.ToListAsync();
await _db.Test.Select(a => a.TestDesc).ToListAsync();
DisplayTestGivenData = await _db.Test.ToListAsync();
await _db.Charge.Select(a => a.ChargeCode).ToListAsync();
DisplayChargeData = await _db.Charge.ToListAsync();
await _db.DrinkLocation.Select(a => a.LastDrinkLocation).ToListAsync();
DisplayLastDrinkData = await _db.DrinkLocation.ToListAsync();
await _db.DrugRecognitionExpert.Select(a => a.DrugRecExpert).ToListAsync();
DisplayDrugExpertData = await _db.DrugRecognitionExpert.ToListAsync();
}
public JsonResult GetAgencies()
{
var agencies = _db.Agency.OrderBy(x => x.AgencyName).ToList();
return new JsonResult(agencies);
}
public JsonResult GetOfficers(int id)
{
var officers = _db.Officer.Where(x => x.Agency.Id == id).OrderBy(x => x.OfficerDisplayName).ToList();
return new JsonResult(officers);
}
public async Task<IActionResult> OnPost()
{
if (ModelState.IsValid)
{
_db.Incident.Add(Incident);
await _db.Incident.AddAsync(Incident);
await _db.SaveChangesAsync();
TempData["success"] = "Incident added successfully.";
return RedirectToPage("Index");
}
return Page();
}
}
Relevant part of Incident Model:
public class Incident
{
[Key]
public int Id { get; set; }
[Display(Name = "Arresting Dept")]
public string? ArrestDept { get; set; }
[Display(Name = "Arresting Officer")]
public string? ArrestOfficer { get; set; }
}
Relevant part of Agency Model:
public class Agency
{
[Key]
public int Id { get; set; }
[Required]
[Display(Name = "Agency")]
public string AgencyName { get; set; }
}
Relevant Part of Officer Model:
public class Officer
{
[Key]
public int Id { get; set; }
[Display(Name ="Officer Name (Last, First, MI)")]
public string? OfficerDisplayName { get; set; }
[Display(Name = "First Name")]
public string? OfficerFirstName { get; set; }
[Display(Name = "MI")]
public string? OfficerMiddleInitial { get; set; }
[Display(Name = "Last Name")]
public string? OfficerLastName { get; set; }
public Agency Agency { get; set; }
}
***An additional question is if this would be easier to accomplish using ONE table as I can easily combine the Officer and Agency models into ONE table. Actually, this would be my preference, but have not been able to find a tutorial that addresses how to do this.
I'm thinking I could easily eliminate the Agency model and simply combine them on the Officer model, so have edited to add the Agency to the Officer model. There could be many officers to a single 'OfficerAgency'.
using System.ComponentModel.DataAnnotations;
namespace DWITracker.Model
{
public class Officer
{
[Key]
public int Id { get; set; }
[Display(Name ="Officer Name (Last, First, MI)")]
public string? OfficerDisplayName { get; set; }
[Display(Name = "First Name")]
public string? OfficerFirstName { get; set; }
[Display(Name = "MI")]
public string? OfficerMiddleInitial { get; set; }
[Display(Name = "Last Name")]
public string? OfficerLastName { get; set; }
[Display(Name = "Agency")]
public string? OfficerAgency { get; set; }
[Display(Name = "Added/Updated By")]
public string UpdatedBy { get; set; }
[Display(Name = "Date Added/Updated")]
[DataType(DataType.Date)]
public DateTime UpdateDate { get; set; }
public Agency Agency { get; set; }
}
}
How would this change the code? Hoping it would make it simpler?
Just not sure how I would change the .cs to work on the single table, specifically the OnGetGetOfficers(int id):
public JsonResult OnGetGetAgencies()
{
var agencies = _db.Officer.OrderBy(x => x.OfficerAgency).ToList();
return new JsonResult(agencies);
}
public JsonResult OnGetGetOfficers(int id)
{
var officers = _db.Officer.Where(x => x.OfficerAgency == id).OrderBy(x => x.OfficerDisplayName).ToList();
return new JsonResult(officers);
}

Your js contains multiple problems here:
1.You add an extra } in LoadAgencies function.
2.You miss a } in LoadOfficers function.
3.You can see each time you use append, the string in this method you always write in a new line, you need concatenate strings in JavaScript using the + operator like below(just an example, your js contains many this type problems):
$('#agency').append(''+
'<option>---Select Arresting Agency---</option>');
Or just move to the same line:
$('#agency').append('<option>---Select Arresting Agency---</option>');
4.The response data is camel case format, for example, you need change data.AgencyName to data.agencyName:
$('#agency').append('<option value=' + data.id + '>' + data.agencyName + '</option>');
5.Razor Pages routing is not like MVC, Razor pages uses OnGet and OnPost to deal with the Http Get and Post request. And the url is related to the PageModelName and folder name, e.g: IndexModel in Pages/Student folder, the url is:/Student/Index. If it is just in Pages folder, the url is:/Index. If you need another Get or Post method in current PageModel, you need define the method name like: OnGetHandlerName or OnPostHandlerName. The url is: /FolderName/PageModelName?handler=HandlerName.
Whole working code:
Page
#page
#model CreateModel
<table>
<tr>
<td style="width: 20%">
<div class="mb-3">
<label asp-for="Incident.ArrestDept"></label>
#*add onchange function*#
<select id="agency" class="form-select" onchange="LoadOfficers(this.value)"></select>
</div>
</td>
<td style="width: 20%">
<div class="mb-3">
<label asp-for="Incident.ArrestOfficer"></label>
<select id="officer" class="form-select"></select>
</div>
</td>
</tr>
</table>
JS in page:
#section Scripts
{
<partial name="_ValidationScriptsPartial" />
<script type="text/javascript">
$(document).ready(function () {
$('#agency').attr('disabled', true);
$('#officer').attr('disabled', true);
LoadAgencies();
});
function LoadAgencies() {
$('#agency').empty();
$.ajax({
url: '/Create?handler=GetAgencies', //change here....
success: function (response) {
if (response != null && response != undefined && response.length > 0) {
$('#agency').attr('disabled', false);
$('#agency').append('<option>---Select Arresting Agency---</option>');//change to one line...
$('#officer').append('<option>---Select Arresting Officer---</option>');//change to one line...
$.each(response, function (i, data) {
//change to camel case here...
$('#agency').append('<option value=' + data.id + '>' + data.agencyName + '</option>');
});
}
else {
$('#agency').attr('disabled', true);
$('#officer').attr('disabled', true);
$('#agency').append('<option>---Arresting Agencies Not Available---</option>');//change to one line...
$('#officer').append('<option>---Arresting Officers Not Available---</option>');//change to one line...
}
},
error: function (error) {
alert(error);
}
});
}
//}
function LoadOfficers(agencyId) {
$('#officer').empty();
$.ajax({
url: '/Create?handler=GetOfficers&Id=' + agencyId, //change here....
success: function (response) {
if (response != null && response != undefined && response.length > 0) {
$('#officer').attr('disabled', false);
$('#officer').append('<option>---Select Arresting Officer---</option>'); //change to one line...
$.each(response, function (i, data) {
//change to camel case here...
$('#officer').append('<option value=' + data.id + '>' + data.officerDisplayName + '</option>');
});
}
else {
$('#officer').attr('disabled', true);
$('#officer').append('<option>---Arresting Officers Not Available---</option>'); //change to one line...
}
},
error: function (error) {
alert(error);
}
});
} //add this '}'
</script>
}
PageModel
public JsonResult OnGetGetAgencies()
{
//...
return new JsonResult(agencies);
}
public JsonResult OnGetGetOfficers(int id)
{
//...
return new JsonResult(officers);
}

Related

I want to post a formdata with array of objects and image upload in react js application where i have asp.net core web api as my backed

I want to post formdata to my asp.net core web api backend where in the post request i have one image upload and 3 array of objects i need to post below is my post request model
public class PostProjectDto
{
public Guid Id { get; set; }
public string Code { get; set; }
public string ProjectName { get; set; }
public string Location { get; set; }
public Guid PropertyTypeId { get; set; }
public Guid OwnershipTypeId { get; set; }
public Guid RentTypeId { get; set; }
public long Duration { get; set; }
public long YearlyRent { get; set; }
public bool ElectricityIncluded { get; set; }
public bool WaterIncluded { get; set; }
public IFormFile File { get; set; }
public string ImageUrl { get; set; }
public List<PostElectricMeterDto> ElectricMeters { get; set; }
public List<PostWaterMeterDto> WaterMeters { get; set; }
public List<PostProjectFacilityRelation> ProjectFacilities { get; set; }
}
I am using CQRS pattern in backend where i have business logic written in application layer
public class Create
{
public class Command : IRequest<Result<Unit>>
{
public PostProjectDto Project { get; set; }
}
public class CommandValidator : AbstractValidator<Command>
{
public CommandValidator()
{
RuleFor(x => x.Project).SetValidator(new ProjectValidation());
}
}
public class Handler : IRequestHandler<Command, Result<Unit>>
{
private readonly DataContext _context;
private readonly IMapper _mapper;
private readonly IWebHostEnvironment _hostingEnvironment;
public Handler(DataContext context, IMapper mapper, IWebHostEnvironment hostingEnvironment)
{
_context = context;
_mapper = mapper;
_hostingEnvironment = hostingEnvironment;
}
public async Task<Result<Unit>> Handle(Command request, CancellationToken cancellationToken)
{
if(request.Project.File != null)
{
var fr = FileSystem.UploadFile(_hostingEnvironment, request.Project.File, new FileSystem.FileUploadSettings
{
FileType = FileSystem.FileType.Image,
StoragePath = LocalStorages.ProjectImageStoragePath
});
if (fr.IsSuccess)
{
request.Project.ImageUrl = fr.Result.ToString();
await _context.Projects.AddRangeAsync(_mapper.Map<Domain.Domains.Projects.Project>(request.Project));
var result = await _context.SaveChangesAsync(cancellationToken) > 0;
if (result)
{
if(request.Project.ElectricMeters.Count > 0 || request.Project.WaterMeters.Count > 0)
{
if (request.Project.ElectricMeters.Count > 0)
{
foreach (var item in request.Project.ElectricMeters)
{
await _context.AddAsync(_mapper.Map<Domain.Domains.Common.ElectricMeterNumber>(item));
}
}
if (request.Project.WaterMeters.Count > 0)
{
foreach (var item in request.Project.WaterMeters)
{
await _context.AddAsync(_mapper.Map<Domain.Domains.Common.WaterMeterNumber>(item));
}
}
var result2 = await _context.SaveChangesAsync(cancellationToken) > 0;
if (!result2) return Result<Unit>.Failure("Unable to add Project Features");
}
}
return Result<Unit>.Success(Unit.Value);
}
else
{
return Result<Unit>.Failure("Unable to add Project Image");
}
}
await _context.Projects.AddRangeAsync(_mapper.Map<Domain.Domains.Projects.Project>(request.Project));
var result1 = await _context.SaveChangesAsync(cancellationToken) > 0;
if (result1)
{
if (request.Project.ElectricMeters.Count > 0 || request.Project.WaterMeters.Count > 0)
{
if (request.Project.ElectricMeters.Count > 0)
{
foreach (var item in request.Project.ElectricMeters)
{
await _context.AddAsync(_mapper.Map<Domain.Domains.Common.ElectricMeterNumber>(item));
}
}
if (request.Project.WaterMeters.Count > 0)
{
foreach (var item in request.Project.WaterMeters)
{
await _context.AddAsync(_mapper.Map<Domain.Domains.Common.WaterMeterNumber>(item));
}
}
var result2 = await _context.SaveChangesAsync(cancellationToken) > 0;
if (!result2) return Result<Unit>.Failure("Unable to add Project Features");
}
}
if (!result1) return Result<Unit>.Failure("Unable to add Project");
return Result<Unit>.Success(Unit.Value);
}
}
}
Below is my endpoint
[HttpPost]
public async Task<IActionResult> CreateProject([FromForm]PostProjectDto Project)
{
return HandleResult(await Mediator.Send(new Create.Command { Project = Project }));
}
i am sending a formdata from the react application
const onFinish =(values)=>{
//Change the formdata to normal request remove the image upload in post request of project and make the image upload seperate
const formdata= new FormData()
formdata.append("id", projectId)
formdata.append("code",values.code)
formdata.append("projectName",values.projectName)
formdata.append("waterMeters", JSON.stringify(waterMeters)) \\ array of objects
formdata.append("electricMeters", JSON.stringify(electricMeters)) \\ array of objects
formdata.append("projectFacilities",JSON.stringify(facilitedAdded)) \\ array of objects
if(values.file) formdata.append("file", projectImage)
formdata.append("propertyTypeId", values.propertyTypeId)
formdata.append("ownershipTypeId", values.ownershipTypeId)
formdata.append("rentTypeId", values.rentTypeId)
formdata.append("duration", Number(values.duration))
formdata.append("yearlyRent", Number(values.yearlyRent))
formdata.append("electricityIncluded", electricityIncluded)
formdata.append("waterIncluded", waterIncluded)
formdata.append("location", values.location)
agent.Project.create(formdata).then(res=> projectform.resetFields())
console.log("submitted value", Object.fromEntries(formdata))
}
i am using axios for api requests
create:async (data)=> await axios.post('Project',data,{headers: { 'Content-type': 'multipart/form-data' }}).then(res=>{
if(res.status==200) message.success("Added Project Successfully")
}).catch(function(err){
const error = err.toJSON()
if(error.status === 500){
message.error("Unable to Add Project!")
}
})
But the problem is iam not getting the array at the endpoint the count is always zero and i am not able to store it

Selected value in the dropdownlistfor doesnt retrieve the value id

I have 2 class models, one is called WorkCategory and the second one is called ServiceCategory. Based on each category selected from the dropdown(WorkCategory) it will populate the second dropdown with data from the second class(ServiceCategory) based on the foreign key.
The first dropdown is populated from the database without javascript, in the second dropdown I populate the value with javascript based on the first dropdown with the method on change.
This is my model view which has the attributes that I want to capture.
public class PostJobViewModel
{
[Required]
public WorkCategory Category { get; set; }
[Required]
public string Headline { get; set; }
[Required]
public string JobAddress { get; set; }
[Required]
public string AboutJob { get; set; }
[Required]
public string JobCity { get; set; }
[Required]
public string JobPostCode { get; set; }
public ServiceCategory JobService { get; set; }
}
This is the first dropdown which populates well from DB and also when I post the form has the ID of the selected option.
#Html.DropDownListFor(m => m.Category.CategoryName, ViewBag.whatWorkToBeDone as SelectList, "-- Select Category --", new { #class = "form-control", #onchange="FillService()" })
#Html.ValidationMessageFor(m => m.Category.CategoryName, "", new { #class = "text-danger" })
and this is the second dropdown list which is populated on runtime with Ajax, based on the first selected option.
#Html.DropDownListFor(m => m.JobService.Category, new SelectList(Enumerable.Empty<SelectListItem>(), "ServiceId", "ServiceName"), "-- Select Service --", new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.JobService.Category, "", new { #class = "text-danger" })
The problem that I have is when I debug the controller the "JobService" is always null even though the option has a value of ids. Despite this, the modelstate is not valid and it throws an error on the UI saying "The value '14' is invalid.(where 14 is the number(id) but for some reason is presented like string).
And here below is the JavaScript/ajax call which I populate the dropdown.
function FillService() {
var serviceId = $('#Category_CategoryName').val();
$.ajax({
url: '#Url.Action("FillServ", "PostJob")',
type: "GET",
contentType: "JSON",
data: { ServiceCategory: serviceId },
success: function (services) {
if (services == '') {
// $('#step-wizard').load(' .step-anchor');
document.getElementById('JobService_Category').disabled = true;
$("#Title-Category").html(""); // clear before appending new list
$("#JobService_Category").html(""); // clear before appending new list
$("#Title-Category").append('Please skip this step!');
$("#secondStep").html("");
$("#secondStep").append('Skip this step!');
} else {
document.getElementById('JobService_Category').disabled = false;
$("#JobService_Category").html(""); // clear before appending new list
$.each(services, function (i, service) {
$("#JobService_Category").append($('<option></option>').val(service.ServiceId).html(service.ServiceName));
});
}
}
});
what is wrong with this?
---UPDATE---
ServiceCategory Class
public class ServiceCategory
{
[Key]
public int ServiceId { get; set; }
public string ServiceName { get; set; }
public WhatToHaveDone Category { get; set; }
public string ServiceDescription { get; set; }
}
public class WhatToHaveDone
{
[Key]
public int WhatToDoneId { get; set; }
public string WhatToDoneItem { get; set; }
public string ItemDescription { get; set; }
public ICollection<ServiceCategory> Services { get; set; }
}
And this is the Method that returns data from the Api call in ajax
[HttpGet]
public ActionResult FillServ(int ServiceCategory)
{
var services = (from s in _context.JobService where s.Category.WhatToDoneId == ServiceCategory select s).ToList();
return Json(services, JsonRequestBehavior.AllowGet);
}
controller debug
[HttpPost]
public ActionResult Index(PostJobViewModel JobModel, List<HttpPostedFileBase> jobImages)
{
if (User.Identity.Name == "")
{
return RedirectToAction("Login","Account");
}
else
{
var imgList = new List<JobImage>();
var user = (from u in _context.Users where u.Email == User.Identity.Name select u.Id).First();
foreach (var item in jobImages)
{
var newJobimage = new JobImage
{
JobFileName = item.FileName,
JobImageContentBytes = new byte[item.ContentLength],
};
imgList.Add(newJobimage);
}
if (ModelState.IsValid)
{
var newJob = new JobPost{
Category = JobModel.Category,
JobAddress=JobModel.JobAddress,
AboutJob=JobModel.AboutJob,
JobCity=JobModel.JobCity,
JobPostCode=JobModel.JobPostCode,
JobImages=imgList,
UserId = user,
JobService=JobModel.JobService
};
_context.jobPosts.Add(newJob);
_context.SaveChanges();
}
else
{
}
}
var workCategories = new SelectList(_context.Categories, "CategoryId", "CategoryName");
ViewBag.WorkCategories = workCategories;
var whatWorkToBeDone = new SelectList(_context.JobWizardCategories, "WhatToDoneId", "WhatToDoneItem");
ViewBag.whatWorkToBeDone = whatWorkToBeDone;
return View();
}

When creating double dropdown SelectList with JQuery on POST returns 0. ASP.Net CORE 2.1

I have created two dropdownlists, of which one acts as a filter for the other. So, with dropdown Customer a customer is selected and only a limited set of ClientUsers is presented in in the dropdown ClientUser. I use a Jquery function to make this happen.
The selection works excellent, but when I POST the form the ClientUser is set to 0, instead of the choice.
The View is as follows (simplified for readability purposes):
#model DropDownTester2.Models.CaseViewModel
<form asp-action="Maak">
<label asp-for="CaseTitle" class="control-label"></label>
<input asp-for="CaseTitle" class="form-control" />
<select id="customerId" asp-for="CustomerId" asp-items='#(new SelectList(ViewBag.customers, "CustomerId", "CompanyName"))'>
<option>Select Customer Name</option>
</select>
<select id="clientUserId" asp-for="ClientUserId" asp-items='#(new SelectList(string.Empty, "ClientUserId", "LastName"))'>
</select>
<input type="submit" value="Maak" class="btn btn-default" />
</form>
#section Scripts {
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script src="~/lib/jquery/dist/jquery.js"></script>
<script type="text/javascript">
$(function () {
$("#customerId").change(function () {
var url = '#Url.Content("~/")' + "Case/getClientUserById";
var ddlsource = "#customerId";
$.getJSON(url, { id: $(ddlsource).val() }, function (data) {
//$.getJSON("#Url.Action("getClientUserById","Case")", { id: $(ddlsource).val() }, function (data) {
var items = '';
$("#clientUserId").empty();
$.each(data, function (i, row) {
items += "<option value='" + row.value + "'>" + row.text + "</option>";
});
$("#clientUserId").html(items);
})
});
});
</script>
}
The CaseViewModel is:
public class CaseViewModel
{
public int CaseId { get; set; }
public string CaseTitle { get; set; }
public int CustomerId { get; set; }
public int ClientUserId { get; set; }
public IEnumerable<Customer> CustomerList { get; set; }
public IEnumerable<ClientUser> ClientUserList {get; set;}
My Model for Case is:
public class Case
{
public int CaseId { get; set; }
public string CaseTitle { get; set; }
public string CaseRoleDescription { get; set; }
public int CustomerId { get; set; }
public int ClientUserId { get; set; }
public virtual Customer Customer { get; set; }
public virtual ICollection<ClientUser> ClientUsers { get; set; }
}
Finally my controllers are :
// GET: Case/Maak
public IActionResult Maak()
{
ViewBag.customers = _context.Customer.ToList();
return View();
}
public JsonResult getClientUserById(int id)
{
List<ClientUser> list = new List<ClientUser>();
list = _context.ClientUser.Where(c => c.Customer.CustomerId == id).ToList();
list.Insert(0, new ClientUser { ClientUserId = 0, LastName = "Please select a clientuser" });
return Json(new SelectList(list, "ClientUserId", "LastName"));
}
// POST: Case/Maak
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Maak(CaseViewModel model)
{
if (ModelState.IsValid)
{
var newCase = new Case
{
CaseId = model.CaseId,
CaseTitle = model.CaseTitle,
CustomerId = model.CustomerId,
ClientUserId = model.ClientUserId
};
_context.Add(newCase);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ViewData["CustomerId"] = new SelectList(_context.Set<Customer>(), "CustomerId", "CustomerId", model.CustomerId);
return View(model);
}
I can't reproduce your issue :
The difference part of codes is that i create the Customer/ClientUser manually but that shouldn't be the issue cause :
public class Customer {
public int CustomerId { get; set; }
public string CompanyName { get; set; }
}
public class ClientUser
{
public int ClientUserId { get; set; }
public string LastName { get; set; }
}
You may search the "ClientUserId " in your pages to confirm whether other function reset the value .
As a workaround, you can also :
Create a hidden filed in your page and bind to your model property , create the select change event javascript function to set the value based on the selection .
Use Jquery to get the selected opinion , use Ajax to call action function and pass the value as parameter .

Three Tables Cascading DropdownList in Asp.net MVC

I want to have a cascading dropdownlist in Asp.Net MVC. I have managed to do it with Two Tables Country and State, now I want to add City.
public class Country
{
[Key]
public int cId { get; set; }
public string cName { get; set; }
public ICollection<State> state { get; set; }
}
public class State
{
[Key]
public int sId { get; set; }
public string sname { get; set; }
public int cId { get; set; }
public Country country { get; set; }
}
//Get list of States
public JsonResult GetStateList(int cId)
{
db.Configuration.ProxyCreationEnabled = false;
List<State> listState = db.States.Where(x => x.cId == cId).ToList();
return Json(listState,JsonRequestBehavior.AllowGet);
}
//Script that invokes the Method
$(document).ready(function () {
$("#cId").change(function () {
$.get("/Home/GetStateList", { cId: $("#cId").val() }, function (data) {
$("#sId").empty();
$.each(data, function (index, row) {
$("#sId").append("<option value= '"+row.sId+"'>"+ row.sname+"</option>")
});
});
})
});
Well just add this:
public class City
{
[Key]
public int cityId { get; set; }
public string cityName { get; set; }
public int sId { get; set; } // stateId
public State state { get; set; }
}
public JsonResult GetCityList(int sId)
{
db.Configuration.ProxyCreationEnabled = false;
List<City> listCity = db.Cities.Where(x => x.sId == sId).ToList();
return Json(listCity,JsonRequestBehavior.AllowGet);
}
$(document).ready(function () {
$("#sId").change(function () {
$.get("/Home/GetCityList", { sId: $("#sId").val() }, function (data) {
$("#cityId").empty();
$.each(data, function (index, row) {
$("#cityId").append("<option value= '"+row.cityId+"'>"+ row.cityName+"</option>")
});
});
})
});

Json invoke not working after moving to mvc5

Same code stopped working after move to mvc5. In the following code I am trying to get cities for a country which is chosen in a dropdownlist using json.
The View.cshtml
#Html.DropDownList("CountryId", (SelectList)ViewBag.Countries, " -- choose a country -- ", new { onchange = "CountryDDLChanged()", #class = "form-control" })
JavaScript file (a part of the code)
function CountryDDLChanged() {
var url1 = "../Country/GetCitiesByCountryId";
var countryid = $("#CountryId").val();
$.ajax({
type: "GET",
url: url1,
data: { countryId: countryid },
dataType: "json",
success: function (result) {
alert("yes");
},
error: function(req, status, error){
alert(error);
}
});
}
CountryController
public JsonResult GetCitiesByCountryId(int countryId)
{
JsonResult result = new JsonResult();
using (var db = new DBContext())
{
List<City> cities = db.Cities.Where(c => c.CountryId == countryId).ToList();
result.Data = cities;
result.JsonRequestBehavior = JsonRequestBehavior.AllowGet;
}
return result;
}
When I digg down in the code and debugging it. it generates this error.
he ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Why this works in MVC4 but not in MVC5? is it because of different version of EF?
how can I solve it?
UPDATED: Here is my Country Entithy and City :
[Table("Country")]
public class Country
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int CountryId { get; set; }
[StringLength(100)]
public string Name { get; set; }
public virtual List<City> Cities { get; set; }
public virtual List<Member> Members { get; set; }
public virtual List<MemberFee> MemberFees { get; set; }
}
[Table("City")]
public class City
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int CityId { get; set; }
public string Name { get; set; }
public int CountryId { get; set; }
[ForeignKey("CountryId")]
public virtual Country Country { get; set; }
public virtual List<Member> Members { get; set; }
}

Categories

Resources