Fullbalanced Fullbalanced - 25 days ago 11
C# Question

c# - render list of checkboxes, always returned as checked

Dears,

Please could you help with below problem:

I want to render list of checkbox in my view.

@model IEnumerable<CFts.Models.CFModel>
...
@foreach (var test in ViewBag.CF_list)
{

if (test.Text != "" && test.Text != " ")
{
<div class="checkbox">
<label><input value="@test.Value" id="CF_list_" name="CF_list_" @(test.Selected == true ? "checked" : "") type="checkbox"> @test.Text</label>
</div>
}
}


OK, checkbox on the page.

CF_list generated in controller (SelectListItem)

But problem that - if send this form, at least one of checkboxes all time marked as selected. For example: 1. I selected two chekckboxed, send form - everything is OK. 2. I remove all ticks and send form - one of the checkbox (last clicked) indicated as selected.

Why?

CF_List is SelectListItem

Another question:

Please could you help me to understand very simple thing

I have model with my class:

public class VendorAssistanceViewModel
{
public string Name { get; set; }
public bool Checked { get; set; }
}
public partial class CSModel : IEntity
{
public CSModel()
{

VendorAssistances = new[]
{
new VendorAssistanceViewModel { Name = "DJ/BAND" },
new VendorAssistanceViewModel { Name = "Officiant" },
new VendorAssistanceViewModel { Name = "Florist" },
new VendorAssistanceViewModel { Name = "Photographer" },
new VendorAssistanceViewModel { Name = "Videographer" },
new VendorAssistanceViewModel { Name = "Transportation" },
}.ToList();
}


public IList VendorAssistances { get; set; }


I have view:

@model IEnumerable<CSTS.Models.CSModel>

... some html code...
and how here to show array of checkboxes from Model, using VendorAssistances ?


I know that this is very simple, I read a lot of docs, but still can not understand

Thank you!

Answer

Do not set the checked attribute, let the value attribute determine whether it is checked or not.

Change

<label><input value="@test.Value" id="CF_list_" name="CF_list_" @(test.Selected == true ? "checked" : "") type="checkbox">@test.Text</label>

To

<label><input value="@test.Value" id="c_" name="CF_list_" type="checkbox">@test.Text</label>

UPDATE: Just to make this easier to understand..

Do not use a SelectListItem for CF_List, use this instead. SelectListItem is used for drop down lists.

public class CFListCheckbox
{
    public bool IsChecked { get; set; } // Add a property to know if the checkbox should be checked or not
    public string Text { get; set; }
    public object Value { get; set; }  // Change as needed
}

In your GET action..

// Assign an ICollection<CFListCheckbox> to your ViewBag.CF_list 
ICollection<CFListCheckbox> cfListCB = cfCollection.Select(r => new CFListCheckbox()
{
    IsChecked = false,
    Text = r.SomeProp,
    Value = r.SomePropOrWhatever
}).ToList();
ViewBag.CF_list = cfListCB;

On your view, use the Html.Checkbox to create your checkboxes.

@foreach (var test in ViewBag.CF_list)
{    
    if (!string.IsNullOrWhiteSpace(test.Text))
    {
        <div class="checkbox">
            <label>
                @Html.Checkbox("CF_list_", test.IsChecked, new { Value = test.Value }) @test.Text
            </label>
        </div>
    }
}

On your POST action, just set the ViewBag.ViewBag.CF_list in case your post fails and goes back to the view.

// Assign an ICollection<CFListCheckbox> to your ViewBag.CF_list 
ICollection<CFListCheckbox> cfListCB = cfCollection.Select(r => new CFListCheckbox()
{
    IsChecked = false,
    Text = r.SomeProp,
    Value = r.SomePropOrWhatever
}).ToList();

// Add logic to re-assign the IsChecked property for your ViewBag.CF_list
foreach(var entry in model.CF_list_)
{
    CFListCheckbox item = cfListCB.FirstOrDefault(r => r.Text == entry.SomeProp && r.Value == entry.SomePropOrWhatever);
    if(item != null)
    {
        item.IsChecked = true;
    }
}

ViewBag.CF_list = cfListCB;

return View(model);

Please note that the sample code is just to give you an idea on what you can do. It is not absolute. Optimize it as needed.

Comments