0

Having already used @Html.CheckBoxFor within a View, I plan to use with the former Tag Helper in conjunction to ViewBag within the same View to circumvent few errors (e.g. variable definition):

MODEL

   public class test
    {
      public int ItemID { get; set; }
      public string ItemName { get; set; }
      public bool IsAvailable { get; set; }
    }

CONTROLLER

List<test> ItemList = new List<test>();
         ItemList.Add(new test {ItemID=1, ItemName="apple", IsAvailable = false});
         ItemList.Add(new test {ItemID=2, ItemName="mango", IsAvailable = false});
         ItemList.Add(new test {ItemID=3, ItemName="stuck", IsAvailable = false});
         ItemList.Add(new test {ItemID=4, ItemName="blocked", IsAvailable = false});
         ItemList.Add(new test {ItemID=5, ItemName="help:(", IsAvailable = false});
         ViewBag.ItemList = ItemList;

VIEW

<table>
      @foreach (var item in ViewBag.ItemList)
           {
            <tr><td>
           <input type= "checkbox" id = "Check_@item.ItemID" checked="@item.IsAvailable" 
           onclick="CheckOnlyOneCheckBox(this);"/>
           <label for="Check_@item.ItemID">@item.ItemName</label>
           </tr>
           }
 </table>

2 main issues have been encountered:

(a) Value of the selected box could not retrieved from a submit button using

   foreach (var item in ViewBag.ItemList)
         {
           if (item.IsCheck)
              {
                var zz = item.ItemName;
               }                     
          }     

(b) format of the displayed ItemName using <input type= "checkbox"> look slightly different (e.g. bold font) than the ones obtained from a previous checkbox list using @Html.CheckBoxFor.

Thus any assistance in using @Html.CheckBoxFor with ViewBag would highly be appreciated.

EDIT

@Md Farid Uddin Kiron

The main issue lies on the fact that a checkbox list has already been defined (in the same same View) via:

List<test> chk = new List<test>();
          chk.Add(new test() {ReferalTypeId=1, ReferalTypeName = "box1",
IsReferalCheck=false});
          chk.Add(new test() {ReferalTypeId=2, ReferalTypeName = 
"box2", IsReferalCheck=false});
          chk.Add(new test() {ReferalTypeId=3, ReferalTypeName = 
"Other", IsReferalCheck=false});

 CtrList chklist = new CtrList(); // Ctrl being a public class defined 
                                 // in MODEL
 chklist.reflist = chk;  
 return View(chklist);

Empirically I've ended up to a situation, where I could not define within public IActionResult Index() another checkbox list returning something else than chklist since the variable (e.g. list) won't be defined while looping it from View.

As a result I had to use, as a way around: ViewBag, enabling me to pass variable from Model to View without any problem. Without binding it, this effective way around has been raising another issue and the solution of last resort I am investigating consists of:

(a) looping through the checkbox;

(b) identifying the selected value via ViewBag;

(c) then finding a way to pass the selected variable from View to Controller. However, I had to concede that this latter approach looks sub-optimal.

Best

dark.vador
  • 619
  • 1
  • 6
  • 25
  • Why don't you try with `@model List` instead of `ViewBag.ItemList` any specific reason for `viewBag` here – Md Farid Uddin Kiron Sep 05 '21 at 14:58
  • @dark.vador Can you share the code from the cshtml? – Rahatur Sep 05 '21 at 15:17
  • So far I have researched on it you can handle `CheckBoxFor` helper with `ViewBag` for single checkbox, but for list of checkboxfor helper bring you into many other problem. First issue is you cannot bind the value with it easily while submit the value to controller. If you want to try instead let me know. There are better solution using `viewModel` – Md Farid Uddin Kiron Sep 06 '21 at 09:27
  • @MdFaridUddinKiron: Thanks indeed for your reply. I've edited the post given the questions while being interesting in knowing best approaches. Best. – dark.vador Sep 07 '21 at 18:06
  • @Rahatur: Thanks for your feedback. As ```cshtml``` is quite massive, I've edited the post, hoping it helps in accurately understanding the issues encountered. Best – dark.vador Sep 07 '21 at 18:11
  • in order to get values bind to the model, your html inputs has to have a name attribute in them.consider that if you need to have list of checkbox/radio buttons you need to name them equal. – Masoud DaneshPour Sep 07 '21 at 18:15

1 Answers1

1

I have researched a lot on your scenario. The way you planned it cannot execute well because we cannot set htmlAttributes on CheckBoxFor so in this way we cannot retrive value from the from CheckBoxFor as you might know to get value from submitted item we need to set htmlAttributes on it like id class or name

So considering your scenario the easiest solution I have founded for you like below:

Your Predefined Model:

public class CheckBoxTestModel
    {
        public int ItemID { get; set; }
        public string ItemName { get; set; }
        public bool IsAvailable { get; set; }
    }

View Model To Lead Check On View:

 public class CheckBoxFromViewBagModel
    {
        public List<CheckBoxTestModel> CheckBoxes { get; set; }
        
    }

Controller On Load:

 public IActionResult CheckboxforFromViewBag()
        {
            var checkBoxList = new List<CheckBoxTestModel>()
            {
                new CheckBoxTestModel() { ItemID=1,ItemName="apple", IsAvailable = false },
                new CheckBoxTestModel() { ItemID=2,ItemName="mango", IsAvailable = false },
                new CheckBoxTestModel() { ItemID=3,ItemName="stuck", IsAvailable = false },
                new CheckBoxTestModel() { ItemID=4,ItemName="blocked", IsAvailable = false },
                new CheckBoxTestModel() { ItemID=5,ItemName="help:(", IsAvailable = false },


            };

            var model = new CheckBoxFromViewBagModel();
            model.CheckBoxes = checkBoxList;
            return View(model);
        }

View When Load CheckBox:

@model CheckBoxFromViewBagModel
@{
    ViewData["Title"] = "CheckboxforFromViewBag";
}
<h4>Load CheckBox From ViewModel & Submit value to Controller wtih Selected Value</h4>

<hr />
<style>
    table {
        font-family: arial, sans-serif;
        border-collapse: collapse;
        width: 100%;
    }

    td, th {
        border: 1px solid #dddddd;
        text-align: left;
        padding: 8px;
    }
</style>
@using (Html.BeginForm("SubmitValueFromCheckBoxList", "UserLog"))
{
    <table class="table-bordered">
        <tr>
            <th>Item Name</th>
            <th>Is Checked</th>

        </tr>

        @for (int i = 0; i < Model.CheckBoxes.Count; i++)
        {
            <tr>

                <td> @Model.CheckBoxes[i].ItemName</td>
                <td> @Html.CheckBoxFor(r => Model.CheckBoxes[i].IsAvailable)</td>
                @Html.HiddenFor(h => @Model.CheckBoxes[i].ItemID)
                @Html.HiddenFor(h => @Model.CheckBoxes[i].ItemName)

            </tr>

        }
    </table>
    <br />
    <input id="Button" type="submit" value="Submit To Controller" class="btn btn-primary" />
}

Controller When Submit The Value:

        [HttpPost]
        public IActionResult SubmitValueFromCheckBoxList(CheckBoxFromViewBagModel checkBoxViewModel)
        {
            var checkBoxValueFromView = checkBoxViewModel;
            return Ok(checkBoxValueFromView);
        }

Output:

enter image description here

Note: As per your scenario I think this would the eligant way to handle this. Other than either of the work around bring us another chanllenge. In my solution you can ignore the CSS part. Here the important and tricky part is @Html.HiddenFor(h => @Model.CheckBoxes[i].ItemID) @Html.HiddenFor(h => @Model.CheckBoxes[i].ItemName) sets htmlAttributes for us.

I hope it would help you well.

Md Farid Uddin Kiron
  • 16,817
  • 3
  • 17
  • 43