Send All Checkbox via Post

Asked

Viewed 1,650 times

3

I’m trying to send all my View Checkbox, however, I can send only those selected via Formcollection

Controller

public ActionResult Index()
{
    List<ListaCheckBox> listacheck = new List<ListaCheckBox>();
    Random rand = new Random();

    for (int i = 0; i < 4; i++)
    {

        ListaCheckBox listaDemo = new ListaCheckBox
        {
            CD_CHECKBOX = i,
            CD_SELECIONADO = rand.Next(0,1),
            DS_CHECKBOX = "CHECK" + i
        };

        listacheck.Add(listaDemo);
    }

    return View(listacheck);
}

[HttpPost]
public ActionResult Index(FormCollection form,ListaCheckBox listaDemo)
{
    string[] formCollec = form["chek"].Split(',');
    return View();
}

Model

public class ListaCheckBox
{
    public int CD_CHECKBOX { get; set; }
    public string DS_CHECKBOX { get; set; }
    public int CD_SELECIONADO { get; set; }
}

View

@model List<Testes.Models.ListaCheckBox>

@using (Html.BeginForm())
{  
    @foreach (var item in @Model)  
    {  
        <label for="chek">@item.DS_CHECKBOX.ToString()</label>  
        <input type="checkbox" name="chek" id="check" value="@item.CD_CHECKBOX" />  
        <br />     
    }  

    <br />    
    <input type="submit" value="Envia CheckBox" />  
}

My FormColletion is receiving, but only the items that were selected. I would like to see the ones that were not selected as well. What I am doing wrong?

3 answers

2

This way is not good to use. FormCollection has several problems, and the correct is to go through the strong typing.

Another thing is that you need to index each item on the list so that the Model Binder can identify the elements. A suggestion would be:

@model List<Testes.Models.ListaCheckBox>

@using (Html.BeginForm())
{  
    @foreach (var item in @Model.Select((valor, i) => new { i, valor }))  
    {  
        <label for="chek">@item.valor.DS_CHECKBOX.ToString()</label>  
        <input type="hidden" name="listaDemo.index" value="@item.i" />
        <input type="checkbox" name="listaDemo[@item.i].CD_CHECKBOX" id="@("listaDemo_" + @item.i + "_CD_CHECKBOX")" value="@item.valor.CD_CHECKBOX" />  
        <br />     
    }  

    <br />    
    <input type="submit" value="Envia CheckBox" />  
}

And the Controller:

[HttpPost]
public ActionResult Index(List<ListaCheckBox> listaDemo)
{
    /* Coloque sua lógica aqui */
}

Alternatively, you can use the package Begincollectionitem to make the logic easier to assemble.

Would look like this:

@model IEnumerable<TesteBool.Models.ListaCheckBox>

@using (Html.BeginForm())
{
    foreach (var item in Model.Select((valor, i) => new { i, valor }).ToList())
    {
        @Html.Partial("_Parcial", item.valor)
    }

    <br />
    <input type="submit" value="Envia CheckBox" />
}

# _Parcial.cshtml

@model TesteBool.Models.ListaCheckBox

@using (Html.BeginCollectionItem("listaDemo")) 
{ 
    <label for="chek">@Model.DS_CHECKBOX</label>
    @Html.CheckBoxFor(model => model.CD_CHECKBOX)
    <br />
}
  • The list is coming empty "- listDemo null System.Collections.Generic.List<Tests.Models.Listcheckbox> "

  • @Andrealves, try to change listaDemo for index. The parameter name must be equal to name form.

1


Less gambiarra (aka. Workaround), my heheh people.

André, you can use the standard Helpers from ASP.NET MVC. Since the value of a <input type="checkbox"/> only goes to server, if this is selected (checked).

So you can generate your Html.CheckBoxFor(Expression<Func<TModel, Boolean>>, Object) and receive as follows:

Controller

public ActionResult Index()
{
    List<ListaCheckBox> listacheck = new List<ListaCheckBox>();
    Random rand = new Random();

    for (int i = 0; i < 4; i++)
    {
        ListaCheckBox listaDemo = new ListaCheckBox
        {
            Id = i,
            Checked = (rand.Next(0,1) % 0) == 0,
            Description = "CHECK" + i
        };

        listacheck.Add(listaDemo);
    }

    return View(listacheck);
}

[HttpPost]
public ActionResult Index(List<ListaCheckBox> list)
{
    // aqui você pode filtrar todos os selecionados e não selecionados
    // com LINQ
    var selecionados = list.Where(l => l.Checked).ToList();
    var naoSelecionados = list.Where(l => !l.Checked).ToList();

    return View(list);
}

Model

public class ListaCheckBox
{
    public int Id { get; set; }
    public string Description { get; set; }
    public bool Checked { get; set; }
}

View

@model List<Testes.Models.ListaCheckBox>

@using (Html.BeginForm())
{  
    @for(int i = 0;i < Model.Count; i++)
    {
        <label>
            @Html.HiddenFor(m => Model[i].Id)
            @Html.HiddenFor(m => Model[i].Description)
            @item.Description
            @Html.CheckBoxFor(m => Model[i].Checked, new { @value = "True" })
        </label>
        <br />     
    }

    <br />
    <input type="submit" value="Envia CheckBox" />  
}

I hope I helped the/

  • 1

    It killed, it worked with p code yes, I didn’t imagine that I would take the values with @value = true with the Boolean ckecked model

0

Without a workaround, is not possible. This is characteristic of <input type="checkbox" />. However, I believe that changing the way you’re treating request in his action, should improve.

See, you’re using the same ID for all your checkboxes, this is not good. The ID value, within the scope of HTML, should be unique, always.

In your scenario, I suggest adding the value of the ID of the Model to the ID of checkbox:

@foreach (var item in @Model)  
{  
    <input type="checkbox" name="chek" id="[email protected]_CHECKBOX" value="@item.CD_CHECKBOX" />  
}   

Then you can receive one by one at action of your controller, thus revealing which were marked and which were not:

var rand = new Random();
for (var i = 0; i < 4; i++)
{
    var id = $"check-{i}";
    var value = form[id];
    var checked = !string.IsNullOrEmpty(value);

    if (checked) 
    {
        // campo checado
    }
    else
    {
       // campo não marcado
    }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.