1

I'm going to have users that need to submit multiple lines into a database, I'm wanting to use a table to collect the input and then insert all the data into the database. In my head it looks like taking the first row of the table, clicking "Add another item" storing that row in a list of Objects... Repeat for N number of rows. When the user pushes the Submit button it will loop through the List of Objects and insert them. What would be the best approach to accomplishing something like this? See image for a brief example of what I'm going for.Example

2 Answers 2

2

Here is a worked example .you could refer to and make the modification according to your demand

Model

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }
    public int Quantity { get; set; }
    [ForeignKey("Category")]
    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

public class Category
{
    public int Id { get; set; }
    public string CategoryName { get; set; }
}

public class ProductViewModel
{
    public List<Product> Products { get; set; }
}

Controller

public IActionResult CreateMultipleData()
    {
        ViewBag.Category = new SelectList(_context.Category.ToList(), "Id", "CategoryName");
        ViewBag.Categories = JsonConvert.SerializeObject( new SelectList(_context.Category.ToList(), "Id", "CategoryName"));
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> PostData(ProductViewModel productVM)
    {
        if (ModelState.IsValid)
        {
            _context.AddRange(productVM.Products);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(productVM.Products);
    }

View , use jquery to add multi-line records

@model SaveMultipleRows.Models.ProductViewModel

<form method="post" action="PostData">
<table id="tblCustomers" class="table" cellpadding="0" cellspacing="0">
    <thead>
        <tr>
            <th style="width:150px">Product Name</th>
            <th style="width:150px">Quantity</th>
            <th style="width:150px">CategoryId</th>
            <th></th>
        </tr>
    </thead>
    <tbody></tbody>
    <tfoot id="item-list">
        <tr>
            <td><input type="text" asp-for="Products[0].Name" class="items" /></td>
            <td><input type="text" asp-for="Products[0].Quantity" class="items" /></td>
            <td><select asp-for="Products[0].CategoryId" class="items" asp-items="@ViewBag.Category">
                </select>
            </td>
            @*<td><input type="button" id="btnAdd" value="Add" /></td>*@
        </tr>
    </tfoot>
</table>
<button id="add">Add another item</button>
<input type="submit" value="Create" class="btn btn-default" />
</form>

@section Scripts {
<script>

$("#add").click(function (e) {
   e.preventDefault();
   var i = ($(".items").length) / 3;
   var model = @Html.Raw(@ViewBag.Categories);
   var n = '<tr> <td><input type="text" class="items" name="Products[' + i + '].Name" /></td>' +
       '<td><input type="text" class="items" name="Products[' + i + '].Quantity" /></td>' +
       '<td><select id="Products_' + i + '_CategoryId" name="Products[' + i + '].CategoryId" class="items" /></td></tr>'

   $("#item-list").append(n);

   var categories = "";
   $(model).each(function () {
       categories = categories + '<option value="' + this.Value + '">' + this.Text + '</option>'
   });

   var subCateList = $("#Products_" + i + "_CategoryId");
   subCateList.empty();
   subCateList.append(categories);
});
</script>
}
Sign up to request clarification or add additional context in comments.

3 Comments

This looks like what I'm looking for but forgive me as I'm not the strongest with Javascript. How does the List make it from the ViewModel to the controller? It appears "name="Products[' + i + '].CategoryId" on Add puts it in the List.
@arrchar , the property of ProductViewModel is only List<Product>.In the model binding , the parameter name of the action and the key of data passed from the view should be consistent . You could use the browser's developer tools( press F12) to check the FormData of the Request in the Network .
@XueliChen you are a life saver. Thank you for taking the time to outline such a detailed answer. God bless.
0

Try This kind of...

$(document).on('click', '.add', function(){
      var html = '';
      var row_count = $('#row_count').val();
      var row_count_val = +row_count+ 1;
      /*alert(row_count_val);*/
      $("#row_count").val(row_count_val);
      html += '<tr>';
      html += '<td>'+
                '<select class="form-control category" name="category_id[]" id="category_'+row_count_val+'">'+
                    '<option value="0"> Select Category </option>'+
                    '@if(count($ingredient_categories) > 0)'+
                        '@foreach($ingredient_categories->all() as $ingredient_category)'+
                            '<option value="{{ $ingredient_category->id }}">{{ $ingredient_category->category }}</option>'+
                        '@endforeach'+
                    '@else'+
                        '<option value="-"> -- No Data -- </option>'+
                    '@endif'+
                '</select>'+
                '</td>';
      html += '<td>'+
                '<select name="ingredient_id[]" id="ingredient_'+row_count_val+'" class="form-control ingredient" required="">'+
                    '<option value="-"> -- No Data -- </option>'+
                '</select>';
      html += '<td>'+
                '<select name="unit_id[]" id="unit_'+row_count_val+'" class="form-control" required="">'+
                    '<option value="-"> -- No Data -- </option>'+
                '</select>';
      html += '<td><input type="text" name="quantity[]" id="quantity_'+row_count_val+'" class="form-control income_quality" placeholder="0" /></td>';
      html += '<td><input type="text" name="rate[]" id="rate_'+row_count_val+'" class="form-control income_rate" placeholder="0.00"/></td>';
      html += '<td><input type="text" name="tax[]" id="tax_'+row_count_val+'" class="form-control income_tax" placeholder="0%"/></td>';
      html += '<td><input type="text" name="amount[]" id="amount_'+row_count_val+'" class="form-control income_amount" placeholder="0.00"/></td>';
      html += '<td><button type="button" name="remove" class="btn btn-danger btn-sm remove"><span class="glyphicon glyphicon-minus"></span></button></td></tr>';
      $('#income_table').append(html);
     });

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.