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
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:
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)
setshtmlAttributes
for us.
I hope it would help you well.