DEV Community

Stevan Kostoski
Stevan Kostoski

Posted on

Add items dynamically in list in .net core

Very often there is a need to add items in a collection of items. Usually we have some object that holds a list of complex objects, for example, one Order contains several OrderItems which are complex objects (has their properties). When creating a Controller and View for such object, Razor ignores these properties and doesn't create input fields for them. In this example, I can show you how I solve this problem without refreshing the page.

AddAnimation

One of the first thins that you should do is to create an Editor for the Objects that are in the list, in this example the order items. This editor is simple copy-paste from its Edit.cshtml file, but remember to remove the

element, otherwise, the submit button will not work. Name of the editor must be the same as the name of the model that you're editing, in this case, OrderItem and place it under Views/Shared/EditorTemplates. If you don't have the EditorTemplates folder under Shared, create it.

When we have the EditorTemplate we can use it in the Create.cshtml file to display the collection of the items. Usually, we place this part in a separate div element with specific id (in this case it's id="orderItemsContainer" so we can later change the content of this div with ajax.

After displaying the items, we should create a button that can be pressed to add a new element to the list. Let's create the Add Button together with the javascript code, that will be used for the ajax call.

To be able to serialize this form, we should also add an id to the form in the create file.

As you noted, we call a method AddOrderItem from Orders controller in the javascript ajax method, and this method we should also create in the controller and set up its binding. This method in the controller is adding a new element to the list and rendering the whole list as a partial view which is later shown in the HTML.

In the AddOrderItem method, we're returning PartialView where we render the list of the order items. Create a partial view in your Views/Order folder called OrderItems.cshtml. The Partial view is pretty much simple, it should only use the editor that we created previously.

When we have everything shown on the screen, now we should add the binding for the list in the create method of the controller and we are ready to use it (include Items in the binding list, because they are not included by default).

Notice that we changed the model, we added a default constructor that will initialize the list. Also, I've added a property that will give us the total number of items in the list, usually this logic should be in ViewModel, but for the sake of simplicity, I put it in the model.

Latest comments (18)

Collapse
 
adinastan profile image
adinastan

Great job! Exactly what I was looking for.
What about deleting them dynamically?

Collapse
 
neokuro profile image
Joshua Hughes

Creating my first MVC application, however I've gotten stuck a bit at the end. You reference a '_context' object, and yet in mine I don't seem able to access that. Is it an inherited member of the Controller, am I missing a reference, or did you construct it in some other tutorial?

Collapse
 
yoannagicheva profile image
yoanna-gicheva • Edited

Hello, Stevan, thank you for your tutorial. It is just great, it is in a big help for me in my first MVC project. I would like to ask you something additional about the PartialViews loaded inside the form.
I have a Partial View with a JavaScript inside which has to operate only on the exact view but instead this script only operates on the first generated partial view. Do you have an idea how to mend this?

Collapse
 
stevcooo profile image
Stevan Kostoski

I don't know what is your javascript code in the partial view, it's hard for me to give you an idea or solution. Maybe you can consider making a more general javascript code and run it on the view, that way you will avoid loading javascript with all your partial views.

Collapse
 
cesarsouza profile image
César Souza

Hi Stevan,

After also fighting a while against the model binder and understanding what it is necessary for it to work properly, I decided to write a library for creating dynamic lists in ASP.NET. I wanted to share it here in case it would be useful for you and the others in the comments. I've called it Dynamic View-Model Lists (very creative, I know) and it's available at dynamic-vml.github.io/

In a particular application I was working on, I had to create several lists for different models using slightly different layouts to use in wizard-like pages. So I decided to make the library a templating engine where you could easily define different view templates for each component of a dynamic list. It also supports nesting lists with any depth.

It comes with sample applications if anyone would like to see examples that just work out-of-the-box.

Hope someone finds it useful!

Cesar

Collapse
 
hajerkr profile image
Hajer Karoui

Hi César,

I had a couple issues with Stevan's solution so I just came across your library and decided to give it a shot. After installing it, for some reason " using DynamicVML;" is not resolving, although it does appear under Packages! Do you know what the issue could be? Am I supposed to reference it somewhere else before referencing it in my ViewModel? Awaiting your response, thanks!

Collapse
 
yuqiu00922996 profile image
Yu Qiu

Thanks for posting this, it is really helpful. but I got a question...if we want to delete an item dynamically after we added some, how would you accomplish that?

Collapse
 
marcusstockton profile image
Marcus Stockton • Edited

Great article, and exactly what I was after, but I am having an issue with part of my data coming in as null in the AddOrderItem controller method.
If you were to add in a complex data type into OrderItem (i.e IFormFile, or another Custom object), would you need to create a custom model binder to get the data in?

Collapse
 
jstafford5380 profile image
jstafford5380

So, adding the item the first time works but if I try to add another item, it doesn't post back the first item that was added so there's nothing to add to. It's acting as if the form isn't including the new items added in the partial

Collapse
 
stevcooo profile image
Stevan Kostoski

I can't reproduce that, can you check out my repository
github.com/stevcooo/AddItemsDynami...

Collapse
 
jstafford5380 profile image
jstafford5380

Ok I was able to get rid of it. I was using razor pages instead of controllers and I had a javascript bug. So I can add all day long. Can you expand this to add a delete? I'm seeing an issue where the form data doesn't seem to be updating. To reproduce, add two items an keep track of their IDs. Delete the first item and everything seems fine, now add one back, suddenly the first ID is back

Collapse
 
jstafford5380 profile image
jstafford5380

Yes will do. I've been working on this exact scenario for a while now and I'm getting really frustrated with the inconsistency in how the model binder works... I think I've gotten to the point where I can consistently add more items, but I'm noticing that the post back of new items appears in the payload but not in the page model. But the page model has the other data and the payload does not.

Collapse
 
stevcooo profile image
Stevan Kostoski

Thank you for the feedback, I'll check this out, if that's the case on my side too, I'll fix it and I let you know.

Collapse
 
sofiery profile image
iSoShiFiery

Heey, Great explanation! But I am having a little trouble. The @Html.EditorFor() is not working for me. It does not load the partial view what so ever. I think I did everything the same way you explain it. Any help you could offer?

Collapse
 
edihasaj profile image
Edi

Just add the model template you are trying to add with EditorFor() to the ~Views/Shared/EditorTemplates/YOURPARTIALVIEW.cshtml.

Create EditorTemplates if it doesn't exist!

Collapse
 
sofiery profile image
iSoShiFiery

Thanks for your reply, but I already have that. So that is not the fix.

Thread Thread
 
hajerkr profile image
Hajer Karoui

Hi! I am having the same issue, did you figure out what the issue may be?

Collapse
 
vakvak35 profile image
TÜRK DEMEK TÜRKÇE DEMEKTİR NE MUTLU TÜRKÜM DİYENE!

Stevan wonderfull job.Thanks for sharing.It is uniqe on the net.
Thanks again