Skip to content
Advertisement

Bind elements to a list with spring mvc ModelAttribute

The question is based on getting a spring model attribute list element using an index from javascript on which explains that each name of the html element must contain an index. Example user[0]

I have a form that allows the user to dynamically add or remove elements from the list before submitting it. Let me put an example: we add 3 users, so the form will now contain 3 inputs:

<input name="user[0].name"    type="text" />
<input name="user[0].surname" type="text" />
<input name="user[1].name"    type="text" />
<input name="user[1].surname" type="text" />
<input name="user[2].name"    type="text" />
<input name="user[2].surname" type="text" />

If we submit this, we’ll have 3 users each having a name and a surname. But, the problem comes when we try to remove the user[1] because I end up with this html:

<input name="user[0].name"    type="text" />
<input name="user[0].surname" type="text" />
<input name="user[2].name"    type="text" />
<input name="user[2].surname" type="text" />

If we submit this form, springs still creates 3 users but the user[1] will have null values for the name and surname.

I know that I can handle input names to always have a “correct” form. But is there another solution? I thought that a form like

<input name="user[].name"    type="text" />
<input name="user[].surname" type="text" />
<input name="user[].name"    type="text" />
<input name="user[].surname" type="text" />

may solve the problem but then I realized: how can spring know which name comes with which surname.

Any idea on a better solution?

Advertisement

Answer

Finally I added all the inputs without the indexed variable (in following the code now i’ll add the containers that were missing before):

<div class="container">
    <input name="name"    type="text" />
    <input name="surname" type="text" />
</div>
<div class="container">
    <input name="name"    type="text" />
    <input name="surname" type="text" />
</div>
<div class="container">
    <input name="name"    type="text" />
    <input name="surname" type="text" />
</div>

So before submitting the form I use updateIndexedInputNames($(".container"), "user");

And let me share the code of updateIndexedInputNames:

function updateIndexedInputNames($container, name){
    $container.each(function(containerIndex, container){
        $(this).find("input,select").each(function(index, element){
            $(element).attr("name", name+"["+containerIndex+"]."+element.name);
        });
    });
}

I don’t think that this is a better solution than the one suggested by @sp00m but it works too.

Hope this helps somebody!

Advertisement