views:

203

answers:

2

I have an action method setup:

public ActionResult Delete(IList<Product> products)

And a table of products in my view. I have got Model Binding working so that on submit I can populate the products list. But I would like to populate it with only the products that are selected via a checkbox.

I think I could do it by changing the action method to this:

public ActionResult Delete(IList<Product> products, IList<int> toDelete)

And passing the list of check boxes to the toDelete but I would really like to avoid changing the method signature if possible.

Is there a way to pass only the selected items? Or am I going to have to write a custom ModelBinder?

+2  A: 

You could always use the checkbox value to indicate whether to delete the item or not.

The name of this value would relate to a property in your Product class.

<form>
    <% for(int i = 0; i < products.Count) { %>
      <div>
        <input type="hidden" name='<%=string.Format("products[{0}].Property1", i) %>' value='<%= products[i].Property1 %>' />
        <input type="hidden" name='<%=string.Format("products[{0}].Property2", i) %>' value='<%= products[i].Property2 %>' />
        <input type="hidden" name='<%=string.Format("products[{0}].Property3", i) %>' value='<%= products[i].Property3 %>' />
        <input type="checkbox" name='<%=string.Format("products[{0}].ToDelete", i) %>' value='true' />
      </div>
    <% } %>
</form>

Then, when you get to your Delete(), you could do something like:

products = products.Where(x=>x.ToDelete == false).ToList();
Dan Atkinson
This would be a neat way of doing it, and I've tried to find a property I can attach such a flag too. Unfortunately I can't touch the model.
jeef3
+1  A: 

I don't understand why you don't want to change the signature, but if you really don't, just access ViewData["toDelete"] or

int[] toDelete;
UpdateModel(toDelete, "toDelete");

or

public class FormViewModel { 
   IList<Product> Products {get;set;}
   int[] ToDelete {get;set;} 
}

var viewmodel = new FormViewModel();
UpdateModel(viewmodel, new[]{"Products", "ToDelete"});
queen3
It's not that I *can't* touch the signature, it's that I don't really want to. If you read a method that says `Delete(IList<Product> products)` you instantly know that it will delete the products in that list. It's a little backwards to read `Delete(IList<Products> products, int[] toDelete)` or similar.I might have a play with your second suggestion though, cheers.
jeef3
After much deliberation I ended up altering the method signature to add a whitelsit. I started to make a custom model binder but it was going to take too long and I really needed to press on from this. If I get time I may look into the custom model binder again.
jeef3