Search code examples
asp.net-coredrop-down-menudropdownhtml-select

Save Dropdownlist value to database


I have a table with two columns containing dropdownlist, the second dropdownlist is populated based on the first dropdownlist selected value. Now i want to save the second dropdpwnlist selected value to database, this is the code i used:

public IActionResult Create()
{
    List<Category> categories = _dbcontext.Category.ToList();
    ViewBag.ListCategories = new SelectList(categories, "CategoryId", "CategoryName");            
    Invoice invoice= new Invoice();
    invoice.StockItems.Add(new StockItems() { StockItemsId = 1});
    return View(decharge);
}
[HttpPost]
public IActionResult Create(Invoice invoice)
{
   if (invoice!= null)
   {
        _dbcontext.Invoice.Add(invoice);
        _dbcontext.SaveChanges();
        return RedirectToAction("Index");
    }
    return View();
}

[HttpPost]
public IActionResult GetStockByCat(int CatId)
{
    List<Stock> stocks = new List<Stock>();
    stocks = _dbcontext.Stock.Where(s => s.CategoryId == CatId).ToList();
    SelectList stocksList = new SelectList(stocks, "StockId", "Name");
    return Json(stocksList);
}

Create View:

    <table class="table table-bordered table-hover">
    <thead>
        <tr>
            ....
        </tr>
    </thead>
    <tbody>
    @for (int i = 0; i < Model.StockItems.Count; i++)
    {
        <tr>
            <td>@Html.DropDownList("Category", ViewBag.ListCategories, null, new { @class = "form-control", @onchange = "GetStocks(this)" })</td>
            <td>@Html.DropDownListFor(x => x.StockItems[i].StockId,null, "--Select --",  new { htmlAttributes = new { @class = "form-control",@id= "stocks", @name = "stocks"} })</td>

        </tr>
     }
    </tbody>
</table>

    <script language="javascript" type="text/javascript">
    function GetStocks(dropdown1) {
        var procemessage = "<option value='0'> Please wait...</option>";
        var dropdown2 = $(dropdown1).closest('tr').find('#stocks');
        dropdown2.html(procemessage).show();
        var url = '@Url.Action("GetStockByCat", "Stock")';
    
        $.ajax({
            url: url,
            data: { CatId: dropdown1.value},
            cache: false,
            type: "POST",
            success: function (data) {
                var markup = "<option value='0'>---------</option>";
                for (var x = 0; x < data.length; x++) {
                    markup += '<option value="' + data[x].value + '">' + data[x].text + '</option>';
                }
                dropdown2.html(markup).show();
                
            },
            error: function (reponse) {
                alert("error : " + reponse);
            }
        });        
    }

When i access to Create View i got this error message:

InvalidOperationException: There is no ViewData item of type 'IEnumerable' that has the key 'StockItems[0].StockId'

S how to save the value of the populated dropdownlist to the database??


Solution

  • Your second Dropdownlist is completed by splicing html with JavaScript, it is not appropriate to use DropDownListFor here.

    Your Invoice model should contain a List<StockItems> property like this:

    public class Invoice
    {
        public int InvoiceId { get; set; }
        public List<StockItems> StockItems { get; set; }
    }
    public class StockItems
    { 
        public int StockItemsId { get; set; }
        public int StockId { get; set; }
    }
    

    What you want to do should be to pass the value selected in the second Dropdownlist into the StockItems.StockId in the Invoice, right?

    The easiest way is to use the select tag and set the matching name attribute(StockItems[@i].StockId):

    <form method="post" asp-action="Create">
        <table class="table table-bordered table-hover">
            <thead>
                <tr>
                    @*....*@
                </tr>
            </thead>
            <tbody>
            @for (int i = 0; i < Model.StockItems.Count; i++)
            {
                <tr>
                    <td>@Html.DropDownList("Category", ViewBag.ListCategories, null, new { @class = "form-control", @onchange = "GetStocks(this)" })</td>
                    <td><select id="stocks" name="StockItems[@i].StockId" class="form-control"></select></td>
                </tr>
             }
            </tbody>
        </table>
        <input type="submit" value="Create" />
    </form>
    

    Test Result: enter image description here