Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create more than one object of the same type in the same view

in my create view I want to give the user the possibility to create a list of objects (of the same type). Therefore I created a table in the view including each inputfield in each row. The number of rows respective "creatable" objects is a fixed number.

Lets say there is a class Book including two properties title and author and the user should be able two create 10 or less books.

How can I do that?

I don't know how to pass a list of objects (that are binded) to the controller. I tried:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(ICollection<Book> bookList)
    {
        if (ModelState.IsValid)
        {
            foreach(var item in bookList)
                db.Books.Add(item);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(articlediscounts);
    }

And in the view it is:

<fieldset>
    <legend>Book</legend>

    <table id="tableBooks" class="display" cellspacing="0" width="100%">
            <thead>
                <tr>
                    <th>Title</th>
                    <th>Author</th>
                </tr>
            </thead>
            <tbody>
                @for (int i = 0; i < 10 ;i++ )
                {
                    <tr>
                        <td>
                            <div class="editor-field">
                                @Html.EditorFor(model => model.Title)
                                @Html.ValidationMessageFor(model => model.Title)
                            </div>
                        </td>
                        <td>
                            <div class="editor-field">
                                @Html.EditorFor(model => model.Author)
                                @Html.ValidationMessageFor(model => model.Author)
                            </div>
                        </td>
                    </tr>
                }
            </tbody>
        </table>

    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>

As booklist is null, it doesn't work and I don't know how to put all created objects in this list.

If you have any suggestions I would be very thankful.

like image 228
Underfaker Avatar asked Nov 01 '22 03:11

Underfaker


1 Answers

Scott Hanselman has some details on passing arrays to MVC control binding: http://www.hanselman.com/blog/ASPNETWireFormatForModelBindingToArraysListsCollectionsDictionaries.aspx

Which is essentially: ensure your controls have the correct names: using an index for lists

Change your for loop to something like:

@for (int i = 0; i < 10 ; i++)
{
    <tr>
        <td>
            <div class="editor-field">
                <input type="text" name="book[" + i + "].Title" />
            </div>
        </td>
        <td>
            <div class="editor-field">
                <input type="text" name="book[" + i + "].Author" />
            </div>
        </td>
    </tr>
}

this will then bind to your post action automatically.

[HttpPost]
public ActionResult Create(IList<Book> bookList)

You can then show/hide these as required or use js/jquery to add them dynamically

Edit: As correctly observed by Stephen Muecke, the above answer only regards the binding from the form+fields to the HttpPost, which appears to be the emphasis of the question.

The post action in the original post is not compatible with the view. There's quite a bit of missing code in the OP that may or may not be relevant, but worth observing that if your view is for a single model, then your fail code on ModelState.IsValid needs to return a single model or your view needs to be for an IList (or similar), otherwise you won't get server-side validation (but you can still get client-side validation if you manually add it to the <input>s)

like image 56
freedomn-m Avatar answered Nov 15 '22 04:11

freedomn-m