3

This is my Controller code.

public ActionResult Create()
{
    ViewBag.grp_id = new SelectList(db.tm_grp_group, "grp_id", "grp_name");
    ViewBag.perm_id = new SelectList(db.tm_perm_level, "perm_id", "perm_levelname");
    return View();
}

Below is my view code.

@model Permission.ts_grp_perm_mapping
....
@using (Html.BeginForm()) {
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>ts_grp_perm_mapping</legend>
        <div class="editor-label">
            @Html.LabelFor(model => model.grp_permid)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.grp_permid)
            @Html.ValidationMessageFor(model => model.grp_permid)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.grp_id, "tm_grp_group")
        </div>
        <div class="editor-field">
            @Html.DropDownList("grp_id", String.Empty)
            @Html.ValidationMessageFor(model => model.grp_id)
        </div>
        <div class="editor-label">
            @Html.LabelFor(model => model.perm_id, "tm_perm_level")
        </div>
        <div class="editor-field">
            @Html.DropDownList("perm_id", String.Empty)
            @Html.ValidationMessageFor(model => model.perm_id)
        </div>
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

In controller ViewBag.perm_id contains some values (this is foreign key). In view perm.id displays in the form of dropdownbox but I want it in the form of checkboxlist. How can I achieve this?

This is the viewmodel I created.

public class AssignUserViewModel
{
    public tm_perm_level[] perms { get; set; }
    public int grp_id { get; set; }
}

Now in controller how can i send values to view? This is my tm_perm_level model

public partial class tm_perm_level
{
    public tm_perm_level()
    {
        this.ts_grp_perm_mapping = new HashSet<ts_grp_perm_mapping>();
    }
    public int perm_id { get; set; }
    public string perm_levelname { get; set; }
    public string perm_description { get; set; }
    public bool perm_status { get; set; }
    public virtual ICollection<ts_grp_perm_mapping> ts_grp_perm_mapping { get; set; }
}

This is ts_grp_perm_mapping model

public partial class ts_grp_perm_mapping
{
    public ts_grp_perm_mapping()
    {
        this.ts_perm_levelmapping = new HashSet<ts_perm_levelmapping>();
    }
    public int grp_permid { get; set; }
    public int grp_id { get; set; }
    public int perm_id { get; set; }
    public List<tm_perm_level> permissions { get; set; }

    public virtual tm_grp_group tm_grp_group { get; set; }
    public virtual tm_perm_level tm_perm_level { get; set; }
    public virtual ICollection<ts_perm_levelmapping> ts_perm_levelmapping { get; set; }
}
Tieson T.
  • 20,774
  • 6
  • 77
  • 92

1 Answers1

1

Especially when editing, always start with view models to represent what you want to display (refer What is ViewModel in MVC?)

public class PermissionVM
{
  public int ID { get; set; }
  public string Name { get; set; }
  public bool IsSelected { get; set; }
}
public class GroupPermissionVM
{
  public int GroupID { get; set; }
  public IEnumerable<SelectListItem> GroupList { get; set; }
  public IEnumerable<PermissionVM> Permissions { get; set; }
}

Then create an EditorTemplate for PermissionVM. In the /Views/Shared/EditorTemplates/PermissionVM.cshtml folder

@model PermissionVM
<div>
    @Html.HiddenFor(m => m.ID)
    @Html.HiddenFor(m => m.Name)
    @Html.CheckBoxFor(m => m.IsSelected)
    @Html.LabelFor(m => m.IsSelected, Model.Name)
</div>

and the main view will be

@model GroupPermissionVM
....
@using (Html.BeginForm())
{
    // dropdownlist
    @Html.LabelFor(m => m.GroupID)
    @Html.DropDownListFor(m => m.GroupID, Model.GroupList, "Please select")
    @Html.ValidationMessageFor(m => m.GroupID)
    // checkboxlist
    @Html.EditorFor(m => m.Permissions)

    <input type="submit" value="Create" />
}

The controller methods would then be

public ActionResult Create()
{
    var groups = db.tm_grp_group;
    var permissions = db.tm_perm_level;

    GroupPermissionVM model = new GroupPermissionVM
    {
        GroupList = new SelectList(groups, "grp_id", "grp_name"),
        Permissions = permissions.Select(p => new PermissionVM
        {
            ID = p.perm_id,
            Name = p.perm_levelname
        }
    };
    return View(model);
}

[HttpPost]
public ActionResult Create(GroupPermissionVM model)
{
    if (!ModelState.IsValid)
    {
        var groups = db.tm_grp_group;
        model.GroupList = new SelectList(groups, "grp_id", "grp_name");
        return View(model);
    }
    // map the view model to a new instance of your data model(s)
    // note: to get the ID's of the selected permissions - 
    //    var selectedPermissions = model.Permissions.Where(p => p.IsSelected).Select(p => p.ID);
    // save and redirect
}

Side note: I strongly recommend you follow normal naming conventions

Edit

Based on OP's comment for an option using radio buttons to select only one item, the revised code would be

public class PermissionVM
{
  public int ID { get; set; }
  public string Name { get; set; }
}
public class GroupPermissionVM
{
  public int GroupID { get; set; }
  public int PermissionID { get; set; }
  public IEnumerable<SelectListItem> GroupList { get; set; }
  public IEnumerable<PermissionVM> Permissions { get; set; }
}

and the view would be (no separate EditorTemplate required)

@model GroupPermissionVM
....
@using (Html.BeginForm())
{
    // dropdownlist as above

    // radio buttons
    foreach (var permission in Model.Permissions)
    {
        <label>
            @Html.RadioButtonForm(m => m.PermissionID, permission.ID)
            <span>@permission.Name</span>
        </label>
    }
    <input type="submit" value="Create" />
}

and in the POST method, the value of model.PermissionID will contain the ID of the selected Permission.

Community
  • 1
  • 1
  • Thank you very much. I will implement now. – LUTHFI ABDUL KADER Feb 01 '16 at 07:11
  • I am able to populate checkboxes but there is some issue with this sentence GroupList = new SelectList(groups, "grp_id", "grp_name"), and the error message is cannot implicitly convert type system.web.mvc.selectlistitem to system.collections.generic.IEnumerable an explicit conversion is exist(are you missing cast)? – LUTHFI ABDUL KADER Feb 01 '16 at 07:31
  • Can you tell me this line? i mean logic @Html.LabelFor(m => m.IsSelected, Model.Name) – LUTHFI ABDUL KADER Feb 01 '16 at 07:32
  • You have a wrong `using` statement in the controller or the model. It should be `@using System.Web.Mvc;` –  Feb 01 '16 at 07:33
  • `@Html.LabelFor(m => m.IsSelected, Model.Name)` generates a label associated with the checkbox (and displays the `Name` property). When you click on the label it checks (or unchecks the associated checkbox) –  Feb 01 '16 at 07:35
  • Its working fine now. Thanks a lot Mr. Stephen Muecke. Struggling lot from one week. Thank you very much. – LUTHFI ABDUL KADER Feb 01 '16 at 07:37
  • Sorry for the inconvenience. I have little doubt. If i want to save the data then i used db.GroupPermissionVM.Add(model); but GroupPermissionVM is a view model which not exist in db. I am supposed to save data to ts_grp_perm_mapping table. So how can i save data to ts_grp_perm_mapping? – LUTHFI ABDUL KADER Feb 01 '16 at 07:57
  • The opposite of the GET method, e.g. `var data = new ts_grp_perm_mapping { grp_id = model.GroupID }; db.ts_grp_perm_mapping.Add(data); db.SaveChanges();` –  Feb 01 '16 at 08:00
  • Note also there are tools such as [automapper](http://automapper.org/) which can make this easier –  Feb 01 '16 at 08:01
  • I accepted. My friend told if i marked as answered they never reply so i reopened and asked doubt. Thanks a lot Stephen – LUTHFI ABDUL KADER Feb 01 '16 at 08:11
  • Don't listen to your friend (we are here to help) :) –  Feb 01 '16 at 08:13
  • Sure stephen. Yes I will get grp_id=model.GroupID, but perm_id how can i get? Will it be something like this? perm_id=model.Permissions.? – LUTHFI ABDUL KADER Feb 01 '16 at 08:24
  • i tried this perm_id=selectedPermissions; but error is coming cannot implicitly convert type system.generec.collections.IEnumerable to int – LUTHFI ABDUL KADER Feb 01 '16 at 08:28
  • See the note in the code `var selectedPermissions = model.Permissions.Where(p => p.IsSelected).Select(p => p.ID);` gives you the ID's of the selected permissions but your model does not seem to have a virtual property for `ICollection` so I suspect there is something wrong with your data model (you do have `virtual tm_perm_level tm_perm_level` but that's just for one object, not a collection) –  Feb 01 '16 at 08:28
  • I dont figure out where i am going wrong? Di i need to make any changes in my model? Model is already posted above – LUTHFI ABDUL KADER Feb 01 '16 at 08:41
  • All your data has is `virtual tm_perm_level tm_perm_level` (and you don't even have a navigation property for it). If you want a collection of `tm_perm_level` associated with a `ts_grp_perm_mapping` then you data model needs `virtual ICollection permissons`. I suspect you have problems with your database design. If you can't work it out, you need to ask a new question showing you database structure and the data models - this thread is already too long (and when you do, I suggest you explain what all those cryptic names actually mean so its easier to understand) –  Feb 01 '16 at 08:48
  • okay stephen i will close conservation here. Anyway you helped me lot. Thank you – LUTHFI ABDUL KADER Feb 01 '16 at 08:50
  • I got small doubt. Sorry for adding conversation here. In the above code if i want radiobutton instead of checkbox can i try something like this @Html.RadioButtonFor(m => m.perm_status) but it needs one more parameter. Can i have some suggestion? – LUTHFI ABDUL KADER Feb 05 '16 at 05:03
  • So I assume you now only want to select one item from the collection, not 1 or more? If that's the case, you need a slightly different view model. Please confirm and I'll update the answer with the alternative –  Feb 05 '16 at 05:06
  • You said last time i have problem with db. you are just brilliant. Now i understood the situation clearly – LUTHFI ABDUL KADER Feb 05 '16 at 05:26
  • Give me 45 min or so and I will edit my answer with the alternative. I'll ping you when its done :) –  Feb 05 '16 at 05:28
  • Thanks a lot stephen – LUTHFI ABDUL KADER Feb 05 '16 at 05:29
  • Thanks a lot stephen – LUTHFI ABDUL KADER Feb 05 '16 at 06:07
  • i edited but in view i am getting this error Unexpected "foreach" keyword after "@" character. Once inside code, you do not need to prefix constructs like "foreach" with "@". – LUTHFI ABDUL KADER Feb 05 '16 at 06:14
  • Then remove the `@` before the word `foreach` - it all depends on you html structure as to whether you need to or not. –  Feb 05 '16 at 06:15
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/102659/discussion-between-stephen-muecke-and-luthfi-abdul-kader). –  Feb 05 '16 at 06:21