Search code examples
c#asp.net-mvcasp.net-core.net-corerazor

How to bind razor view to model with list of objects?


Using Razor code, how can I bind a list of Widgets to the List<WidgetModel> in my Model? I assume there's an easy standard way to do this as it seems like a common scenario.

I have a model with a list of widgets, like this:

public class CustomerModel
{
    public List<WidgetsModel> widgets { get; set; }
}

I also have a View where the user can add widgets

<input type="button" id="add-link" value="Add"/>

<div class="widget-wrapper">

    <p>Widget Name:</p>
    @Html.TextBoxFor(m => m.widgets.name)

    <p>Widget Price:</p>
    @Html.TextBoxFor(m => m.widgets.price)
  
    <hr>
</div>

<script type="text/javascript">
    $('#add-link').on('click', function(){
        var x = $('.widget-wrapper')[0].outerHTML;
        $(x).insertAfter(this);
    });
</script>

Solution

  • Here is a working demo.When click the add button,it will creat a input for name and a input for price.If fill in the inputs,and click the submit button,it will post the whole data to action.

    Models:

    public class CustomerModel
        {
            public List<WidgetsModel> widgets { get; set; }
        }
        public class WidgetsModel {
            public string name { get; set; }
            public int price { get; set; }
    
        }
    

    View:

    <form method="post">
        <input type="button" id="add-link" value="Add" />
        <div class="widget-wrapper">
            @for (var i = 0; i < Model.widgets.Count(); i++)
            {
    
    
                <p>Widget Name:</p>
                @Html.TextBoxFor(m => m.widgets[i].name)
    
                <p>Widget Price:</p>
                @Html.TextBoxFor(m => m.widgets[i].price)
    
                <hr>
    
    
            }
    
        </div>
        <input type="submit" id="add-link" value="Submit" />
    </form>
    <script type="text/javascript">
        
        $('#add-link').on('click', function () {
            var count = $('input[name*="name"]').length;
            var html = '<p>Widget Name:</p><input id = "widgets_' + count + 'name" name = "widgets[' + count + '].name" type = "text" ><p> Widget Price:</p> <input id="widgets_' + count + '__price" name="widgets[' + count + '].price" type="text" ><hr>';
            $('.widget-wrapper').append(html);
        });
    </script>
    

    Controller:

    [HttpGet]
            public IActionResult TestCustomerModel() {
                CustomerModel c = new CustomerModel { widgets = new List<WidgetsModel> { new WidgetsModel { name = "w1", price = 1 }, new WidgetsModel { name = "w2", price = 2 }, new WidgetsModel { name = "w3", price = 3 } } };
                return View(c);
            }
            [HttpPost]
            public IActionResult TestCustomerModel(CustomerModel c)
            {
               
                return Ok();
            }
    

    result: enter image description here