I'm coding with ASP.NET Core. I have a form in a view that has several select inputs to insert orders. I want to change asp-items in select input of Products at run time, after changing select inputs of Properties of Products. In other words, a select input populates with a new list, after selecting new value in other inputs.
I try to use ajax for bind new list to select. but I don't know why ajax can't send input data to controller.
View's Code:
<form id="InsertForm">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="ProductTitleId" class="control-label"></label>
<select asp-for="ProductTitleId" asp-items="@ViewBag.ProductTitles" class="form-control" id="txtProductTitleId" name="SearchItem">
<option value="0" disabled selected>Select an item...</option>
</select>
<span asp-validation-for="ProductTitleId" class="text-danger </span>
</div>
<div class="form-group">
<label asp-for="ProductTypeId" class="control-label"></label>
<select asp-for="ProductTypeId" asp-items="@ViewBag.ProductTypes" class="form-control" id="txtProductTypeId" name="SearchItem">
<option value="0" disabled selected>Select an item...</option>
</select>
<span asp-validation-for="ProductTypeId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="SizeId" class="control-label"></label>
<select asp-for="SizeId" asp-items="@ViewBag.Sizes" id="txtSizeId" class="form-control" name="SearchItem">
<option value="0" disabled selected>Select an item...</option>
</select>
<span asp-validation-for="SizeId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="FinalProductId" class="control-label"></label>
<select asp-for="FinalProductId" asp-items="@ViewBag.FinalProducts" class="form-control" dir="rtl" id="txtFinalProductId">
<option value="0" disabled selected>Select an item...</option>
</select>
<span asp-validation-for="FinalProductId" class="text-danger"></span>
</div>
<div class="form-group">
<button type="submit" class="btn">Insert</button>
</div>
</form>
<script>
$(document).ready(function () {
$('[name = SearchItem]').change(function () {
var _url = '@Url.Action("FindFinalProductCode", "Order")';
$.ajax({
url: _url,
type: "Post",
data: {
ProductTitleId: $("#txtProductTitleId option:selected").val(),
ProductTypeId: $("#txtProductTypeId option:selected").val(),
SizeId: $("#txtSizeId option:selected").val(),
},
dataType: "json",
contentType: "application/json;charset=utf-8",
success: function (data) {
$("#txtFinalProductId").empty();
$("#txtFinalProductId").append('<option value="' + "0" + '">' + "Select an item..." + '</option>');
$.each(data, function (i, item) {
$("#txtFinalProductId").append('<option value="' + item.Id + '">' + item.FinalProductCode + '</option>');
alert(i + ": " + item.Id);
});
},
error: function (data) {
alert(data);
}
});
});
});
</script>
Controller's Code: OrderController.cs
[HttpPost]
public IActionResult FindFinalProductCode(FinalProductViewModel finalProductViewModel)
{
List<FinalProduct> finalProducts = FindFinalProduct(finalProductViewModel);
return Json(finalProducts);
}
ViewModel's Code: FinalProductViewModel.cs
public class FinalProductViewModel
{
[Display(Name = "Title")]
public int ProductTitleId { get; set; }
[Display(Name = "Type")]
public int ProductTypeId { get; set; }
[Display(Name = "Size")]
public int SizeId { get; set; }
}
At run time, finalProductViewModel is empty when is posted to the action.
I changed ajax code like this (remove datatype and content type):
<script>
$(document).ready(function () {
$('[name = SearchItem]').change(function () {
var _url = '@Url.Action("FindFinalProductCode", "Order")';
$.ajax({
url: _url,
type: "Post",
data: {
ProductTitleId: $("#txtProductTitleId option:selected").val(),
ProductTypeId: $("#txtProductTypeId option:selected").val(),
SizeId: $("#txtSizeId option:selected").val(),
},
success: function (data) {
$("#txtFinalProductId").empty();
$("#txtFinalProductId").append('<option value="' + "0" + '">' + "Select an item..." + '</option>');
$.each(data, function (i, item) {
$("#txtFinalProductId").append('<option value="' + item.Id + '">' + item.FinalProductCode + '</option>');
alert(i + ": " + item.Id);
});
},
error: function (data) {
alert(data);
}
});
});
});
</script>
The controller is changed like this:
[HttpPost]
public IActionResult FindFinalProductCode(FinalProductViewModel finalProductViewModel)
{
List<FinalProduct> finalProducts = FindFinalProduct(finalProductViewModel);
return ok(finalProducts);
}
but this time ajax has error when action returns data.
How to change my code to run correctly?
Question:
What are another ways of sending a list from action controller to view(to re-populate asp-items of select input)??