This is a migrated thread and some comments may be shown as answers.

Need help adding a multiselect or dropdown in my grid

3 Answers 715 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Nicklas
Top achievements
Rank 1
Nicklas asked on 14 May 2014, 11:20 AM
Hi,

I'm working on a user management system in asp.net mvc, where I display all my users in a grid using KendoUI. However, I have a string based list of user roles, which I need to display as a dropdown in my edit view. Since my view is generated based on my model, I'm not really sure how to accomplish this.

Here's how my model looks like:
public class UserModel
{
    #region Properties
    [Display(Name = @"Username")]
    [Required]
    public string UserName { get; set; }
    [Required]
    public string Name { get; set; }
    [Display(Name = @"E-mail")]
    [EmailAddress]
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Company { get; set; }
    [DataType(DataType.Password)]
    [Display(Name = @"Password")]
    [Required]
    public string PasswordHash { get; set; }
    [Display(Name= @"Roles")]
    public List<string> UserRoles { get; set; }
    [ScaffoldColumn(false)]
    public string UserRoleIcon { get; set; }
    [ScaffoldColumn(false)]
    public string UserRoleIconInverted { get; set; }
 
    #endregion
 
    public UserModel()
    {
         
    }
 
    public UserModel(UserContract userContract)
    {
        SetupUserModel(userContract);
    }
 
    private void SetupUserModel(UserContract userContract)
    {
        UserName = userContract.UserName;
        Name = userContract.Name;
        Email = userContract.Email ?? "";
        Phone = userContract.Phone ?? "";
        Company = userContract.Company ?? "";
        PasswordHash = userContract.PasswordHash ?? "";
        UserRoles = new List<string>();
 
        if (userContract.UserRoles != null)
        {
            foreach (var userRole in userContract.UserRoles)
            {
                UserRoles.Add(userRole);
            }
        }
 
        SelectUserRoleIcon(UserRoles);
    }
 
    // TODO: Hierarchy on roles and selecting images?
    private void SelectUserRoleIcon(IEnumerable<string> userRoles)
    {
        foreach (var userRole in userRoles)
        {
            switch (userRole.ToLower())
            {
                case "administrator":
                    UserRoleIcon = "Administrator.png";
                    UserRoleIconInverted = "Administrator_Black.png";
                    break;
                case "operator":
                    UserRoleIcon = "Operator.png";
                    UserRoleIconInverted = "Operator_Black.png";
                    break;
                case "supervisor":
                    UserRoleIcon = "Supervisor.png";
                    UserRoleIconInverted = "Supervisor_Black.png";
                    break;
                default:
                    UserRoleIcon = "Guest.png";
                    UserRoleIconInverted = "Guest_Black.png";
                    break;
            }
        }
    }
}

Here's my grid:
@(Html.Kendo().Grid<Stimline.Xplorer.Services.Models.User.UserModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.UserName);
            columns.Bound(p => p.Name);
            columns.Bound(p => p.Email);
            columns.Bound(p => p.Phone);
            columns.Bound(p => p.UserRoles);
            columns.Command(command => { command.Edit(); }).Width(160);
        })
        .ToolBar(toolbar => toolbar.Create())
        .Editable(editable => editable.Mode(GridEditMode.PopUp))
        .Pageable()
        .Sortable()
        .Scrollable()
        .HtmlAttributes(new { style = "height:430px;" })
        .DataSource(dataSource => dataSource
            .Ajax()
            .PageSize(20)
            .Events(events => events.Error("error_handler"))
            .Model(model => model.Id(p => p.UserName))
            .Create(update => update.Action("EditingPopup_Create", "UserManagement"))
            .Read(read => read.Action("EditingPopup_Read", "UserManagement"))
            .Update(update => update.Action("EditingPopup_Update", "UserManagement"))
            //.Destroy(update => update.Action("EditingPopup_Destroy", "Grid"))
        )
    )

I don't really need to display the column with selected roles in the grid, but what I do need is the possibility to add / edit them from the popup. Preferably as a multiselect list, as a user could have several roles. I've tried following this example, but can't seem to manage to get it right.
See the attached images for a description of how it looks now.

3 Answers, 1 is accepted

Sort by
0
Vladimir Iliev
Telerik team
answered on 16 May 2014, 07:13 AM
Hi Nicklas,

For your convenience I created small example (attached to the current thread) of using both MultiSelect and DropDownList widgets inside custom PopUp editor template which you can use as a baseline to achieve the desired behavior. The project is self explanatory.

Regards,
Vladimir Iliev
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
0
Nicklas
Top achievements
Rank 1
answered on 16 May 2014, 11:03 AM
Thanks! I've been able to get it working!  :) The only problem now is that I can't seem to populate the actual roles column in the grid with the selected values.

<script type="text/kendo" id="rolesTemplate">
    <ul>
        #for(var i = 0; i< data.length; i++){#
        <li>#:data[i].Name#</li>
        #}#
    </ul>
</script>
<script type="text/javascript">
    var rolesTemplate = kendo.template($("#rolesTemplate").html(), { useWithBlock: false });
</script>
<div class="container">
    <div class="row">
        <div class="col-md-12 sl-table">
            @(Html.Kendo().Grid<UserModel>()
                    .Name("grid")
                    .Columns(columns =>
                    {
                        columns.Bound(p => p.UserName);
                        columns.Bound(p => p.Name);
                        columns.Bound(p => p.Email);
                        columns.Bound(p => p.Phone);
                        columns.Bound(p => p.UserRoles).ClientTemplate("#=rolesTemplate(UserRoles)#");
                        columns.Bound(p => p.Disabled).Width(150);
                        columns.Command(command => { command.Edit(); }).Width(100);
                    })
                    .ToolBar(toolbar => toolbar.Create())
                    .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("CustomPopUpTemplate"))
                    .Pageable()
                    .Sortable()
                    .Scrollable()
                    .HtmlAttributes(new { style = "height:500px;" })
                    .DataSource(dataSource => dataSource
                        .Ajax()
                        .PageSize(10)
                        .Events(events => events.Error("error_handler"))
                        .Model(model => model.Id(p => p.UserName))
                        .Create(update => update.Action("EditingPopup_Create", "UserManagement"))
                        .Read(read => read.Action("EditingPopup_Read", "UserManagement"))
                        .Update(update => update.Action("EditingPopup_Update", "UserManagement"))
                    )
                )
        </div>
    </div>

Where UserRoles is a List<Role> in my UserModel. 
Console windows says this:
Uncaught TypeError: Cannot read property 'length' of null.

Suggestions?
0
Vladimir Iliev
Telerik team
answered on 20 May 2014, 09:06 AM
Hi Nickalas,

From the provided information it seems that the UserRoles are null in the column template. In current case I would suggest to first check if the "data" parameter is not null before executing the loop:

<script type="text/kendo" id="rolesTemplate">
    <ul>
        #if(data){#
            #for(var i = 0; i< data.length; i++){#
                <li>#:data[i].Name#</li>
            #}#
        #}#
    </ul>
</script>

Also you should define default value for the "UserRoles" in the DataSource Model definition. Please check the suggested change below:

.DataSource(dataSource => dataSource
    .Ajax()
    .Model(model =>
    {
        model.Field(p => p.UserRoles).DefaultValue(new List<string>());

If the above changes doesn't help, please provide runable example where the issue is reproduced in order to investigate further current behavior. 

Kind Regards,
Vladimir Iliev
Telerik
 

Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.

 
Tags
Grid
Asked by
Nicklas
Top achievements
Rank 1
Answers by
Vladimir Iliev
Telerik team
Nicklas
Top achievements
Rank 1
Share this question
or