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 = "[email protected]" checked="@item.IsAvailable" 
           onclick="CheckOnlyOneCheckBox(this);"/>
           <label for="[email protected]">@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

6
  • Why don't you try with @model List<Test> instead of ViewBag.ItemList any specific reason for viewBag here Commented Sep 5, 2021 at 14:58
  • @dark.vador Can you share the code from the cshtml? Commented Sep 5, 2021 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 Commented Sep 6, 2021 at 9:27
  • @MdFaridUddinKiron: Thanks indeed for your reply. I've edited the post given the questions while being interesting in knowing best approaches. Best. Commented Sep 7, 2021 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 Commented Sep 7, 2021 at 18:11

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Thank You Very Much for the time devoted to this post. Furthermore, the explanations are very clear. Much appreciated, hence my gratefulness. Best regards.
Glad to investigate your problem.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.