Jeandre Pentz
Jeandre Pentz

Reputation: 1002

ASP MVC submit list not mapping all values

I have a table where the user can add a entry and once the user is done they they can add another.

After they added a entry they can remove it again. This is where the problem happens. Here is an example

ACTION:

Public ActionResult Submit(List<String> Names)
{
   //DO STUFF
}

When they add a entry it will grab the index of the previous entry and add a hidden field for it, so at the end it will look something like this:

HTML:

 <input type="hidden" name='Names[0]' value='John'/>
 <input type='hidden' name='Names[1]' value='Peter' />
 <input type='hidden' name='Names[2]  value='David' />

When I submit this it will map all the names correcty. The problem is that the user can remove one of the names after they added it before the submit. If they remove the input with the value 'Peter' the html will look like this

HTML AFTER REMOVE:

 <input type="hidden" name='Names[0]' value='John'/>
 <input type='hidden' name='Names[2]  value='David' />

When this gets submitted, only the input with the value 'John', will get mapped.

Does anyone know how to fix this without coding a jquery function that will redo all the indexes in the html? I'm looking for a solution that I can add server side for the bindings, a override or something. The reason I don't want to do it with jquery is because I have multiple pages that has such functionality, and doing it for each page will be quite time time consuming.

*****EDIT*******

The code above are just an example, one of my models that I try to bind look like the following:

public class Product {
   public string Code {get;set;}
   public string Name {get;set;}
   public int Quantity {get;set;}
   public decimal Price {get;set;}

}

And then obviously in my Action

public ActionResult Submit(List<namespace.Product> Products)
{
  //do stuff
}

Upvotes: 1

Views: 2142

Answers (4)

Jeandre Pentz
Jeandre Pentz

Reputation: 1002

Thanks to Zabavsky comment, I found the solution I was looking for.

I used non-sequential indices.

Here is an example:

Action:

 public ActionResult Create(List<namespace.Product> Products)
 {
    //do stuff
 }

Model:

public class Product {
   public string Code {get;set;}
   public string Name {get;set;}
   public int Quantity {get;set;}
   public decimal Price {get;set;}

}

In my form the html will look like the following:

<input type='hidden' name='Products.Index' value='1'/>
<input type='hidden' name='Products[1].Code' value='xyz' />
<input type='hidden' name='Products[1].Name' value='Shirt' />
<input type='hidden' name='Products[1].Quantity' value='5'/>
<input type='hidden' name='Products[1].Price' value='50'/>

<input type='hidden' name='Products.Index' value='7'/>
<input type='hidden' name='Products[7].Code' value='zxy' />
<input type='hidden' name='Products[7].Name' value='Pants' />
<input type='hidden' name='Products[7].Quantity' value='8'/>
<input type='hidden' name='Products[7].Price' value='70'/>

<input type='hidden' name='Products.Index' value='foo'/>
<input type='hidden' name='Products[foo].Code' value='1234' />
<input type='hidden' name='Products[foo].Name' value='Shoes' />
<input type='hidden' name='Products[foo].Quantity' value='2'/>
<input type='hidden' name='Products[foo].Price' value='100'/>

All these will bind correctly. All that I had to add was the:

<input type='hidden' name='Products.Index' value='1'/>

All the index values just needs to be unique for this to work, so with just a few lines of jquery I was able to achieve this.

More information can be found here: Model Binding To A List

Upvotes: 0

chuckb35
chuckb35

Reputation: 39

I'm sure you figured this out a long time ago but it looks like you have a typo. Your example is using "values" instead of "value" for the second row values='David' />

Upvotes: 0

Benjamin RD
Benjamin RD

Reputation: 12034

You can try update the model with Ajax jQuery, that could be more eassier.

you can add a input button like:

<input type="button" value="Save/Update" id="saveUpdate" />
//Other HtmlCode

//Now script code
<script>
$(function(){

 $("#saveUpdate").click(function({
      $.ajax({
         url: '/myController/GetDataForInvoiceNumber',
         type: 'POST',
         data: JSON.stringify(requestData),
         dataType: 'json',
         contentType: 'application/json; charset=utf-8',
         error: function (xhr) {
            alert('Error: ' + xhr.statusText);
         },
         success: function (result) {
            CheckIfInvoiceFound(result);
         },
         async: true,
         processData: false
      });

 });

});
</script>

//Contoller
Public ActionResult Submit(Products requestData)
{
   //DO STUFF
}

That could works

Upvotes: 1

WannaCSharp
WannaCSharp

Reputation: 1898

You don't need an index to submit a list to the controller.

Public ActionResult Submit(string[] Names)
{
   //DO STUFF
}

Then just change Names[] to just Names and it will still map to the Names parameter even if you remove items.

<input type="hidden" name='Names' value='John'/>
<input type='hidden' name='Names`  values='David' />

Upvotes: 0

Related Questions