My problem is I have to create a layout like the following Using MVC to assign rights to the user.
Now there is no problem in creating the check boxes I'll create it using the list of users. but while submitting the form i should submit it to the list like below.
public class UserRightsViewModel
{
public UserRightsViewModel()
{
_screenrights = new List<ScreenRight>();
}
public String Id { get; set; }// Role Name
List<ScreenRight> _screenrights;
public List<ScreenRight> ScreenRights { get { return _screenrights; } set { _screenrights = value; } }
}
definition for screenRight is below
public class ScreenRight
{
public String UserName { get; set; }
public Boolean Select{ get; set; }
public Boolean Add{ get; set; }
public Boolean Edit{ get; set; }
,,,
}
Now while submitting the form how can i post it to the controller in the right format.
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new UserRightsViewModel
{
// Obviously those could come from some data source
ScreenRights = new[]
{
new ScreenRight { UserName = "Robert", Select = true, Add = false, Edit = false },
new ScreenRight { UserName = "John", Select = true, Add = true, Edit = false },
new ScreenRight { UserName = "Mike", Select = true, Add = true, Edit = false },
new ScreenRight { UserName = "Allan", Select = true, Add = true, Edit = true },
new ScreenRight { UserName = "Richard", Select = false, Add = false, Edit = false },
}.ToList()
};
return View(model);
}
[HttpPost]
public ActionResult Index(UserRightsViewModel model)
{
// The view model will be correctly populated here
// TODO: do some processing with them and redirect or
// render the same view passing it the view model
...
}
}
View:
@model UserRightsViewModel
@using (Html.BeginForm())
{
<table>
<thead>
<tr>
<th>User Id</th>
<th>Select</th>
<th>Add</th>
<th>Edit</th>
</tr>
</thead>
<tbody>
@for (int i = 0; i < Model.ScreenRights.Count; i++)
{
<tr>
<td>
@Html.DisplayFor(x => x.ScreenRights[i].UserName)
@Html.HiddenFor(x => x.ScreenRights[i].UserName)
</td>
<td>
@Html.CheckBoxFor(x => x.ScreenRights[i].Select)
</td>
<td>
@Html.CheckBoxFor(x => x.ScreenRights[i].Add)
</td>
<td>
@Html.CheckBoxFor(x => x.ScreenRights[i].Edit)
</td>
</tr>
}
</tbody>
</table>
<button type="submit">OK</button>
}
Further reading: Model Binding To a List
.
To work backwards, your eventual HTML should look like this (ignoring your table)
<input type="hidden" value="0" name="ScreenRights[0].Select"/>
<input type="checkbox" name="ScreenRights[0].Select"/>
<input type="hidden" value="0" name="ScreenRights[0].Add"/>
<input type="checkbox" name="ScreenRights[0].Add"/>
<input type="hidden" value="0" name="ScreenRights[0].Edit"/>
<input type="checkbox" name="ScreenRights[0].Edit"/>
<input type="hidden" value="0" name="ScreenRights[1].Select"/>
<input type="checkbox" name="ScreenRights[1].Select"/>
<input type="hidden" value="0" name="ScreenRights[1].Add"/>
<input type="checkbox" name="ScreenRights[1].Add"/>
<input type="hidden" value="0" name="ScreenRights[1].Edit"/>
<input type="checkbox" name="ScreenRights[1].Edit"/>
The idea is that the index order shows up in the [i] array portion of the property name, and then chain into the next property. It should bind up in the same order as your i's. The other key here is the check boxes only bind up with CHECKED attribute, so value has no meaning in terms of the binder. That's why you have the hidden input in front. The binder will always assign false, and then override to true if the checkbox is checked. You can verify this resulting html with Html.CheckBoxFor on a simple model.
In terms of getting your HTML to look like that, you can do it manually, or you can make use of the built-in framework.
I'm pretty sure you can just do this in a for Loop (i as the iterator)
@Html.CheckBoxFor(m => m.ScreenRights[i].Select)
@Html.CheckBoxFor(m => m.ScreenRights[i].Add)
@Html.CheckBoxFor(m => m.ScreenRights[i].Add)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With