Home > Software design >  How to create object that contains a list of object in a single form?
How to create object that contains a list of object in a single form?

Time:07-12

public class Basket
{
    public int Id { get; set; }
    public string Sharp { get; set; }
    public string Material { get; set; }
    public List<Fruit> Fruits { get; set; }
}


public class Fruit
{
    public int Id { get; set; }
    public string Color { get; set; }
    public string Taste { get; set; }
}

With the above example, how could I create both Basket and Fruit in the same asp-form without using any JavaScript?

<form method="post" asp-controller="Basket" asp-action="Create">
    <input asp-for="Material" />
    <input asp-for="Sharp" />

    @*I would like to also create custom amounts of new Fruit in this form.*@

    <input type="submit" value="Submit" />
</form>

If my razor form is defined as the above example, how could I create custom amounts of Fruit and create Basket at the same form? It is possible to avoid using JavaScript in this case?

CodePudding user response:

It is possible to avoid using JavaScript in this case?

Based on your scenario and current architecture what you need to do is, there should be a table where you would be adding your fruit object as it's a List<Fruit> Fruit kind of. As per your given code, your output should be as below:

enter image description here

how could I create custom amounts of Fruit and create Basket at the same form?

You could follow the below steps to achieve what you are trying to implement.

View:

@model DotNet6MVCWebApp.Models.Basket

<form method="post" asp-controller="Yonny" asp-action="Create">
    <div >
        <label asp-for="Material" ></label>
        <input asp-for="Material"  />
        <span asp-validation-for="Material" ></span>
    </div>

    <div  style="padding-bottom:20px">
        <label asp-for="Sharp" ></label>
        <input asp-for="Sharp"  />
        <span asp-validation-for="Sharp" ></span>
    </div>
    @*I would like to also create custom amounts of new Fruit in this form.*@
    <div style="padding-bottom:20px">
         <button type="button"  onclick="AddRow()">Add Fruit</button>
    </div>
   
    <div id="dataTable">
        <table>
            <thead>
                <tr>
                    <th>Id</th>
                    <th>Color</th>
                    <th>Taste</th>
                </tr>
            </thead>
            <tbody id="FruitList" data-count="0">
              
            </tbody>
        </table>
    </div>
    <input type="submit"  value="Submit" />
</form>

@section Scripts {
<script>
    /*
         . Hidding table on load
    */
      document.getElementById('dataTable').style.display ='none';

      function AddRow()
      {
          var countVal = parseInt($('#FruitList').attr('data-count'));
          var html = '';
          html  = '<tr>';
          html  = '<td><input type="text" name="Fruits['   countVal   '].Id" /></td>';
          html  = '<td><input type="text" name="Fruits['   countVal   '].Color" /></td>';
           html  = '<td><input type="text" name="Fruits['   countVal   '].Taste" /></td>';
          html  = '</tr>';

          $('#FruitList').append(html);
          countVal  = 1;
          $('#FruitList').attr('data-count', countVal);
      /*
         . Showing table when adding item into 
      */
           document.getElementById('dataTable').style.display ='block';
       
      }
</script>
}

Controller:

     [HttpPost]
     [ValidateAntiForgeryToken]
     public async Task<IActionResult> Create(
     [Bind("Id,Material,Sharp,Fruits")] DotNet6MVCWebApp.Models.Basket basket)
        {
            if (ModelState.IsValid)
            {
                //Save Basket
                _context.Add(basket);
                await _context.SaveChangesAsync();

                //Add Fruits List
                foreach (var item in basket.Fruits)
                {
                    _context.Add(item);
                    await _context.SaveChangesAsync();
                }
                return RedirectToAction(nameof(Create));
            }
            return View(basket);
        }

Note:

If you somehow got null data while sending request to controller make sure your binding property that is Bind("Id,Material,Sharp,Fruits") are same as name="Fruits[' countVal '].Id" inside the javascript function

Output:

enter image description here

  • Related