简体   繁体   中英

Binding check box values to list in the model mvc

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM