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

Values not passed to Multiselect in grid detail template

19 Answers 472 Views
MultiSelect
This is a migrated thread and some comments may be shown as answers.
Jark Monster
Top achievements
Rank 1
Jark Monster asked on 30 May 2013, 07:06 PM
Hello!  I'm utilizing a multiselect widget within a detail template for a standard grid.

Currently, the widget loads and can be interacted with just fine, but I can't seem to load default values into from the model.  When the detail template is opened, no values are selected and just the placeholder text is present.  Let me know if you require any more info.  Thanks!

Current Build: v2013.1.514

Code inside the detail template (Does NOT work):
<table>
    <tr valign="top">
        <td style="width:1%;">@Html.Label("RoleOperations", "Operations")</td>
        <td>
            @(Html.Kendo().MultiSelect()
                .Name("AuthRoleOperationMultiselect_#=RoleID#")
                .BindTo(ViewBag.AuthOperationListing)
                .Placeholder("Select Operations...")
                .DataTextField("Description")
                .DataValueField("ID")
                .Value("#=AuthOperationIDs#") //Type: List<int>
                .ToClientTemplate()
            )
        </td>
    </tr>
</table>

Code outside detail template (DOES work):
@(Html.Kendo().MultiSelect()
    .Name("AuthRoleOperationMultiselect")
    .Events(events =>
    {
        events.DataBound("ConfigureMultiselect");
    })
    .BindTo(ViewBag.AuthOperationListing)
    .Placeholder("Select Operations...")
    .DataTextField("Description")
    .DataValueField("ID")
    //Just selecting the info of the first item in the grid
    .Value(Model.AdminModel.AuthorizationModel.AuthRoleOperationList[0].AuthOperationIDs) //Type: List<int>
)


Grid Code + Detail Template code:
<div id="AuthRoleOperationContainer">
    <h3 style="margin:1px;">Roles & Operations</h3>
    @(Html.Kendo().Grid(Model.AdminModel.AuthorizationModel.AuthRoleOperationList)
        .Name("AuthRoleOperationGrid")
        .Columns(columns =>
        {
            columns.Bound(i => i.Description);
            columns.Command(command =>
            {
                command.Destroy();
            }).Width(100);
        })
        .ClientDetailTemplateId("AuthRoleOperationDetails")
        .ToolBar(toolbar =>
        {
            toolbar.Template(@<text>
                <a class="k-button k-button-icontext k-grid-add" href="#_">
                    <span class="k-icon k-add"></span>Add new item
                </a>
                <a class="k-button k-button-context" onclick="SaveAuthRoleOperations();" href="#">
                    <span class="k-icon k-add"></span>Save changes
                </a>
                <a class="k-button k-button-icontext k-grid-cancel-changes" href="#">
                    <span class="k-icon k-cancel"></span>Cancel changes
                </a>
            </text>);
        })
        .Editable(editable => editable.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Bottom))
        .Navigatable(navigatable => navigatable.Enabled(true))
        .Pageable()
        .Sortable()
        .Filterable()
        .Resizable(resize => resize.Columns(true))
        .DataSource(dataSource => dataSource
            .Ajax()
            .Batch(true)
            .ServerOperation(false)
            .Sort(sort => sort.Add("Description").Ascending())
            .Model(model =>
            {
                model.Id(i => i.RoleID);
            })
            .Read(read => read.Action("GetAuthRoleOperations", "Authorization"))
            .Create(create => create.Action("CreateAuthRoleOperations", "Authorization"))
            .Update(update => update.Action("UpdateAuthRoleOperations", "Authorization"))
            .Destroy(destroy => destroy.Action("DeleteAuthRoleOperations", "Authorization"))
        )
    )
</div>
 
<script id="AuthRoleOperationDetails" type="text/kendo-tmpl">
    @Html.Partial("DetailTemplates/AuthRoleOperationDetails")
</script>

19 Answers, 1 is accepted

Sort by
0
Accepted
Jark Monster
Top achievements
Rank 1
answered on 31 May 2013, 03:11 PM
Though I am still curious if the code I posted was an error on my part or if the template should pass the values to the multiselect, I have found a workaround.

I pass the values to the multiselect manually when the detail template is initialized.

Changes to detail template:
.Value("#=AuthOperationIDs#") //REMOVE THIS LINE
Add DetailInit function to grid:
.Events(events =>
{
     events.DetailInit("LoadMultiSelectData"); 
})
Add function to inject the data when the detail template is initialized:
function LoadMultiSelectData(e) {
     var multiSelect = $("#AuthRoleOperationMultiselect_" + e.data.uid)
          .data("kendoMultiSelect");
     multiSelect.value(e.data.AuthOperationIDs);
}
0
Daniel
Telerik team
answered on 03 Jun 2013, 05:52 PM
Hello,

The Value method cannot be used to set the value in this case because it is executed on the server and the template is evaluated on the client. Using the detailInit event to set the value via JavaScript will be needed for this scenario.

Regards,
Daniel
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Samuel
Top achievements
Rank 2
answered on 13 Dec 2013, 01:51 AM
I apologize for reviving an old thread, but I'm having a similar issue and I've been using this thread to work my way through it. The issue I'm having is that my values are in an enumerable with a name and Id and I can't seem to figure out how to push them in. In desperation, I've flattened it into a comma delimited string. Is there a better way? If I pass a simple list or enumerable instead of something more complex will it just take care of it for me? I don't really need the names now that I'm grabbing my available values elsewhere. Suggestions?

My View:
@model IEnumerable<Datamart.Models.UserMaintenanceViewModel>
 
@(Html.Kendo().Grid(Model)
        .Name("Users")
        .Columns(col =>
        {
            col.Bound(c => c.UserName);
            col.Bound(c => c.Email);
            col.Bound(c => c.Phone1);
            col.Bound(c => c.isConfirmed);
            col.Bound(c => c.HasCertify);
            col.Bound(c => c.EntityCount);
            col.Template(@<text></text>)
            .ClientTemplate(Html.ActionLink("Force Confirmation", "AdminConfirm", "Account", new { id = "#: id #" }, new { @class = "k-button" }) + "<br />" + Html.ActionLink("Can Certify", "CanCertify", "Account", new { id = "#: id #" }, new { @class = "k-button" }).ToHtmlString())
                .Title("<b>Actions</b>");
 
        })
        .ClientDetailTemplateId("UserLEADetails")
        .DataSource(ds => ds
            .Ajax()
            .Model(m => m.Id(pk => pk.id))
            .Read(read => read.Action("GetUserMaintenance", "Account"))
            )
        .Events(events =>
            {
                events.DetailInit("LoadMultiSelectData");
            })
        .Pageable(page => page.PageSizes(new int[] { 10, 25, 50, 100 }).Enabled(true))
        .Sortable(s => s.Enabled(true))
        .Filterable(f => f.Enabled(true))
)
 
<script id="UserLEADetails" type="text/kendo-tmpl">
    <table>
        <tr>
            <td style="width:1%;">@Html.Label("Entities", "Associated LEAs")</td>
            <td>
                @(Html.Kendo().MultiSelect()
        .Name("multi_#=id#")
        .Placeholder("Select LEAs...")
        .DataTextField("EntityName")
        .DataValueField("EntityId")
        .Filter(FilterType.Contains)
        .AutoBind(false)
        .DataSource(source =>
        {
            source.Read(read =>
            {
                read.Action("GetAllEntities", "Account");
            });
        })
                        //.Value("#=Entities#")
        .ToClientTemplate()
 
                )
            </td>
        </tr>
    </table>
</script>
<script>
    function LoadMultiSelectData(e) {
        var multiSelect = $("#multi_" + e.data.id).data("kendoMultiSelect");
        //multiSelect.value(["9", "115"]); // this works
        multiSelect.value([e.data.EntitiesCSV]);
        debugger;
        //multiSelect.value(e.data.Entity);  // this does not work
    }
</script>
My model:
/// <summary>
/// ViewModel for user maintenance
/// </summary>
public class UserMaintenanceViewModel
    {
    /// <summary>
    /// internal identifier for user (from Datamart_User)
    /// </summary>
    public int id { get; set; }
    /// <summary>
    /// username
    /// </summary>
    public string UserName { get; set; }
    /// <summary>
    /// email address
    /// </summary>
    public string Email { get; set; }
    /// <summary>
    /// primary phone number (required)
    /// </summary>
    public string Phone1 { get; set; }
    /// <summary>
    /// whether the user is confirmed or not
    /// </summary>
    public bool isConfirmed { get; set; }
    /// <summary>
    /// whether the user has Certify role
    /// </summary>
    public bool HasCertify { get; set; }
 
    /// <summary>
    /// number of entities in Entities collection
    /// </summary>
    [Display(Name = "# of LEAs")]
    public int EntityCount { get; set; }
 
    /// <summary>
    /// list of entities linked
    /// </summary>
    public IEnumerable<UserMaintenanceEntitiesViewModel> Entities { get; set; }
 
    public string EntitiesCSV { get; set; }
    }
 
public class UserMaintenanceEntitiesViewModel
    {
    public int EntityId { get; set; }
    public string EntityName { get; set; }
    }
Controller code:
public IEnumerable<UserMaintenanceViewModel> _GetAllUsers()
    {
    var tmp = (from d in db.Datamart_User
             from web in db.webpages_Membership
             && d.UserId == web.UserId
             select new UserMaintenanceViewModel
             {
                 id = d.UserId,
                 UserName = d.UserName,
                 Email = d.Email,
                 Phone1 = d.Phone1,
                 HasCertify = d.webpages_Roles.Any(a => a.RoleName == "CertifyDraft"),
                 isConfirmed = (bool)web.IsConfirmed,
                 Entities = d.ct_Entity.Select(s => new UserMaintenanceEntitiesViewModel
                 {
                     EntityId = s.entity_id,
                     EntityName = s.entity_name
                 }),
                 EntityCount = d.ct_Entity.Count
             }).AsEnumerable();
 
    var Users = tmp.Select(s => new UserMaintenanceViewModel
    {
        id = s.id,
        UserName = s.UserName,
        Email = s.Email,
        Phone1 = s.Phone1,
        HasCertify = s.HasCertify,
        isConfirmed = s.isConfirmed,
        Entities = s.Entities,
        EntityCount = s.EntityCount,
        EntitiesCSV = string.Join(",", s.Entities.Select(s2 => s2.EntityId))
    });
    return Users;
    }
0
Petur Subev
Telerik team
answered on 13 Dec 2013, 12:48 PM
Hello Samuel,

I posted an answer in the other support ticket that you opened on the same subject.

The value method of the MultiSelect accepts array of numbers, which means any Array, IEnmurable or ICollection of Integeres should be serialized in a way so it can be directly passed as a value.

Feel free to continue our conversation here or in the other support ticket.

Kind Regards,
Petur Subev
Telerik
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Samuel
Top achievements
Rank 2
answered on 14 Dec 2013, 02:39 AM
That was very helpful! Once I changed my Entity to a straight IEnumerable<int>, it populated without a problem (and I was able to use LINQ to Entities instead of switching to LINQ To Objects, which was a nice bonus)

When I set the view to AutoSync, I noticed that the values in the multiselect don't seem to get passed into the controller nor does it trigger a save. I assume that the two issues are linked, but I'm not sure how to resolve them. When I trigger the autosync by changing something else on the record, the Entities (from the Multiselect in the detail template) are always null. Do I need to pass the detail template as additionalData?

My View:
@model IEnumerable<Datamart.Models.UserMaintenanceViewModel>
 
@(Html.Kendo().Grid(Model)
        .Name("Users")
        .Columns(col =>
        {
            col.Bound(c => c.UserName);
            col.Bound(c => c.Email);
            col.Bound(c => c.Phone1);
            col.Bound(c => c.isConfirmed);
            col.Bound(c => c.HasCertify);
            col.Bound(c => c.EntityCount);
            col.Template(@<text></text>)
                .ClientTemplate(Html.ActionLink("Force Confirmation", "AdminConfirm", "Account", new { id = "#: id #" }, new { @class = "k-button" }) + "<br />" + Html.ActionLink("Can Certify", "CanCertify", "Account", new { id = "#: id #" }, new { @class = "k-button" }).ToHtmlString())
                .Title("<b>Actions</b>");
 
        })
        .ClientDetailTemplateId("UserLEADetails")
        .DataSource(ds => ds
            .Ajax()
            .AutoSync(true)
            .Model(m => m.Id(pk => pk.id))
            .Read(read => read.Action("GetUserMaintenance", "Account"))
            .Update(update => update.Action("UpdateUserMaintenance","Account"))
            .Batch(true)
            )
        .Events(events =>
            {
                events.DetailInit("LoadMultiSelectData");
            })
        .Pageable(page => page.PageSizes(new int[] { 10, 25, 50, 100 }).Enabled(true))
        .Sortable(s => s.Enabled(true))
        .Filterable(f => f.Enabled(true))
        .Editable(e => e.Mode(GridEditMode.InCell))
)
 
<script id="UserLEADetails" type="text/kendo-tmpl">
    <table>
        <tr>
            <td style="width:1%;">@Html.Label("Entities", "Associated LEAs")</td>
            <td>
                @(Html.Kendo().MultiSelect()
        .Name("multi_#=id#")
        .Placeholder("Select LEAs...")
        .DataTextField("EntityName")
        .DataValueField("EntityId")
        .Filter(FilterType.Contains)
        .AutoBind(false)
        .DataSource(source =>
        {
            source.Read(read =>
            {
                read.Action("GetAllEntities", "Account");
            });
        })
        .ToClientTemplate()
 
                )
            </td>
        </tr>
    </table>
</script>
<script>
    function LoadMultiSelectData(e) {
        var multiSelect = $("#multi_" + e.data.id).data("kendoMultiSelect");
        multiSelect.value(e.data.Entities);
        //debugger;
    }
</script>
 
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}
0
Luis
Top achievements
Rank 1
answered on 16 May 2016, 10:57 PM

Hello

I was having the same issue and try to solve it using the LoadMultiSelectData function.

However, when getting to the line where we are actually setting the values to the multi select I am getting redirected to my default page in my application. This is really weird and I dont now why this is happening. Here is my function

LoadMultiSelectData = function (e) {
            var multiSelect = $("#default_recipients_"+e.data.MessageTypeId).data("kendoMultiSelect");
            multiSelect.value(e.data.DefaultRecipients); //redirected after this line.
        }

 

 

0
Luis
Top achievements
Rank 1
answered on 16 May 2016, 11:03 PM
[quote]Luis said:

Hello

I was having the same issue and try to solve it using the LoadMultiSelectData function.

However, when getting to the line where we are actually setting the values to the multi select I am getting redirected to my default page in my application. This is really weird and I dont now why this is happening. Here is my function

LoadMultiSelectData = function (e) {
            var multiSelect = $("#default_recipients_"+e.data.MessageTypeId).data("kendoMultiSelect");
            multiSelect.value(e.data.DefaultRecipients); //redirected after this line.
        }

[/quote]

I investigated a little more into the issue. It seems that on the .value command, the read action is being performed. I had a custom function tomanipulate data passed to the action method and that was originating an exception.

 

0
Luis
Top achievements
Rank 1
answered on 17 May 2016, 04:22 PM

I just cannot make it work.My template code is as follows.

<script id="detail-template" type="text/kendo-tmpl">   
                @(Html.Kendo().MultiSelect()
                  .Name("default_recipients_#=MessageTypeId#")
                  .DataValueField("RecipientId")
                  .DataTextField("Name")
                  .AutoBind(false)
                  .MinLength(3)                 
                  .DataSource(source =>
                  {
                      source.Read(read =>
                      {
                          read.Action("GetEmployees", "Message", new {area = "Admin"}).Data("MessageTypeGridProperties.DefaultRecipientsEditorReadActionData");
                      })
                      .ServerFiltering(true);
                  })
                  .ToClientTemplate()
                      )   
            </div>          
</script>     

0
Luis
Top achievements
Rank 1
answered on 17 May 2016, 04:25 PM

Sorry My previous post was incomplete. If you see, I used a custom data function to pass the values typed into the multiselect to the action method. 

MessageTypeGridProperties.DefaultRecipientsEditorReadActionData = function (event) {
            if (event.filter != undefined) {
                return {
                    employeeName: event.filter.filters[0].value
                };
            }
            return event;
        }

I have correctly bound to the DetailIniti event on my grid as follows:

events.DetailInit("MessageTypeGridProperties.DetailInit");

 

MessageTypeGridProperties.DetailInit = function (e) {
            var multiSelect = $("#default_recipients_"+e.data.MessageTypeId).data("kendoMultiSelect");
            multiSelect.value(e.data.DefaultRecipients); //THIS DOES NOT WORK
        }

However, after the detail init action fires, the DefaultRecipientsEditorReadActionData  fires too. Is there a way I can avoid this? Besides from this, could it be this issue the one causing the values not to bind?. I am passing a List of objects with the following definition:

public class ReplyRecipient
    {
        public int RecipientId { get; set; }
        public bool IsRecipientClient { get; set; }
        public string Name { get; set; }
    }

 

 

0
Dimitar
Telerik team
answered on 18 May 2016, 04:40 PM
Hello,

I am afraid that I cannot achieve this behavior on my side with the snippets provided. In order to assist you in the most efficient way I would suggest that you provide a very simplified runnable project that demonstrates the behavior that you describe. Thus, we could test your exact scenario locally and determine what might be causing the issue that you are experiencing.

Regards,
Dimitar
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Luis
Top achievements
Rank 1
answered on 18 May 2016, 04:43 PM

Thank you Dimitar. I have just solved the issue. The problem was that even though I was calling the value() method, my data source was empty. I solved it by setting my data source by using 

multiSelect.dataSource.data(e.data,DefaultRecipients);

and then passing an array of the ids to the value method. I also had to set the .AutoBind property on the multiselect to false, otherwise the values were being deleted.

Greetings

Luis.

 

0
Dimitar
Telerik team
answered on 18 May 2016, 04:53 PM
Hi Luis,

Thank you for the update. I'm glad to know that you have solved the issue faced.

Best regards,
Dimitar
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Alexandra
Top achievements
Rank 1
answered on 16 Aug 2016, 12:42 PM

Hello, I have a problem implementing "selectall" functionality in MultiSelectFor editor in grid.

I have a grid with a column:

columns.Bound(userRole => userRole.SelectedCostCenters). EditorTemplateName("CostCenterMultiSelectEditor"). ClientTemplate("#=listTemplateCodeNameParams(SelectedCostCenters)#");

 

Template looks like this:

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

 

I also have an editor:

@model IEnumerable<CostCenterInfo>
<script type="text/javascript">
    function onSelectAllClick()
    {
        var multiselect = $("#SelectedCostCenters").kendoMultiSelect().data("kendoMultiSelect");
        multiselect.wrapper.find(".k-multiselect-wrap").removeClass("floatWrap").addClass("k-floatwrap");
        var all = $.map(multiselect.dataSource.data(), function (dataItem) {

            return dataItem.value;
        });

        multiselect.value(6120);  //just for examle do not work
        //multiselect.value(all); //same problem as with simple integer
        multiselect.trigger("change");
        
    }
</script>
<table>
    <tr>
        <td width="90%" style="padding-right: 1px; padding-left: 1px;">
            @(Html.Kendo().MultiSelectFor(m => m)

                  .Name("SelectedCostCenters")
                  .DataValueField("Code")
                  .DataTextField("Name")
                  .AutoClose(false)
                  .Placeholder("Select projects....")
                  .DataSource(source =>
                  {
                      
                      source.Read(read =>
                      {
                          read.Action("GetCostCentersForCompany", "Dictionary").Data("getSelectedCompanyFilterParameter");
                      });                     
                  })
                  )
        </td>
        <td width="10%" style="padding-right: 1px; padding-left: 1px;">
            @(Html.Kendo().Button()
            .Name("selectAllButton")
            .Content("ALL").Events(events=>events.Click("onSelectAllClick"))
            .HtmlAttributes(new {style = "min-width:3em", type="button"}));
        </td>
    </tr>
</table>

 

When I edit cell everything works perfect, values in a grid and editor are in sync and showing right values (they are similar to declared model structure). But when I press my "selectAllButton" the edit control fills fine, expect it duplicates items which were already selected. But when I finish editing, my grid client template gets values of type {value: "", text: ""} instead of   declared model  and shows list of undefined. I tried to insert simple integer in value function of  multiselect, but got similar result with exception that list contained only one item.

0
Dimitar
Telerik team
answered on 18 Aug 2016, 08:16 AM
Hello Alexandra,

I would suggest you to follow the approach described in the following forum post. It should help you resolve the issue.

Regards,
Dimitar
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Alexandra
Top achievements
Rank 1
answered on 18 Aug 2016, 07:42 PM

Dimitar, thanks for your answer. I have already read the post you provided. Unfortunately as far  as i see, now this control works different and I have another.

This piece of code I use to get items from datasource, but it  generates dataitems of type {text: "", value : "" }:

  var multiselect = $("#SelectedCostCenters").kendoMultiSelect().data("kendoMultiSelect");
        multiselect.wrapper.find(".k-multiselect-wrap").removeClass("floatWrap").addClass("k-floatwrap");
        var all = $.map(multiselect.dataSource.data(), function (dataItem) {

            alert(JSON.stringify(dataItem));
            return dataItem.Code;
        });

 

It is not of my model type, my control works with fields Code and Name:

@(Html.Kendo().MultiSelectFor(m => m)

                  .Name("SelectedCostCenters")
                  .DataValueField("Code")
                  .DataTextField("Name")
                  .AutoClose(false)
                  .Placeholder("Select projects....")
                  .DataSource(source =>
                  {
                      
                      source.Read(read =>
                      {
                          read.Action("GetCostCentersForCompany", "Dictionary").Data("getSelectedCompanyFilterParameter");
                      });
                      
                  })

And when I use function multiselect.value(....)  to set values via javascript multiselect control return data to parent grid with type {text:"",value:""} not in type {Name:"",Code:""}. If I simply check values via user interface it works fine.

I tried to hard code parameter to value(....) function and as far sa I call it, items  which are returned from edit control to grid change type from {Code:"", Name:""} to {value:"",text:""}.

 

0
Dimitar
Telerik team
answered on 19 Aug 2016, 10:33 AM
Hi Alexandra,

This behavior comes from the way you get your multiselect variable. In order to have an object with type Name and Code, you should define the multiselect variable as:

var multiselect = $("#SelectedCostCenters").data("kendoMultiSelect");

instead of:

var multiselect = $("#SelectedCostCenters").kendoMultiSelect().data("kendoMultiSelect");

as the second way would create a MultiSelect from the select HTML element, which would have default text and value fields. Please give it a try on your end and check if the select all works then as expected.

Regards,
Dimitar
Telerik by Progress
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Alexandra
Top achievements
Rank 1
answered on 19 Aug 2016, 08:26 PM

Oh...)) I've had a feeling that it is some sort of idiotic copy-paste mistake.

Thank you very much.

0
Graham
Top achievements
Rank 1
answered on 04 May 2017, 12:02 PM

Hi

I am having an issue with the mutliselect not being populated.  Here is my read action which is used to populate the user grid with a list of users.  Each of the users can have one or more roles.  The RoleId is not an interger.

public ActionResult User_Read([DataSourceRequest] DataSourceRequest request)
        {
            var adminRole = RoleManager.FindByNameAsync("Admin").Result;
            var roles = RoleManager.Roles;
 
            var currentUser = HttpContext.User;
            var isAdmin = currentUser.IsInRole("Admin");
 
            IQueryable<ApplicationUser> users;
 
            if (isAdmin)
                users = UserManager.Users;               
            else
                users = UserManager.Users.Where(e => e.Roles.Any(r => r.RoleId != adminRole.Id));
 
            var result = users.Select(
                    u =>
                    new UserViewModel
                    {
                        Id = u.Id,
                        FirstName = u.FirstName,
                        LastName = u.LastName,
                        Email = u.Email,
                        EmailConfirmed = u.EmailConfirmed,
                        IsAccountLocked = u.LockoutEndDateUtc == null ? false : u.LockoutEndDateUtc > DateTime.Now,
                        RolesList = u.Roles.Select(ur =>
                            new SelectListItem {
                                Value = ur.RoleId,
                                Text = (roles.FirstOrDefault(r => r.Id == ur.RoleId).Name)
                            }
                        )
                    });
 
            return Json(result.ToDataSourceResult(request));
        }
@(Html.Kendo().Grid<iTrak.Web.Models.UserViewModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.FirstName);
            columns.Bound(p => p.LastName);
            columns.Bound(p => p.Email);
            columns.Bound(p => p.EmailConfirmed);
            columns.Bound(p => p.IsAccountLocked);
            columns.Bound(p => p.RolesList).Hidden(true);
            columns.Command(command => { command.Edit(); command.Destroy(); }).Width(250);
        })
        .ToolBar(toolbar =>
        {
            //toolbar.Create();
            toolbar.Template(@<text>
                <a class="k-button k-button-icontext k-grid-add" href="/iTrak/UsersAdmin/User_Read?grid-mode=insert"><span class="k-icon k-i-add"></span>Add</a>
            </text>);
        })
                    .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("User").Window(w => w.Title("Edit User").Width(700).Height(500)))
            .Pageable()
            .Sortable()
            .Scrollable()
            .HtmlAttributes(new { style = "height:550px;" })
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(20)
                .Events(events =>
                {
                    events.Error("onErrorHandler");
                    events.RequestEnd("onGridRequestEnd");
                })
                .Model(model => model.Id(p => p.Id))
                .Create(update => update.Action("User_Create", "UsersAdmin").Data("onUserCreate"))
                .Read(read => read.Action("User_Read", "UsersAdmin"))
                .Update(update => update.Action("User_Update", "UsersAdmin"))
                .Destroy(update => update.Action("User_Destroy", "UsersAdmin"))
            )
)

 

Here is my grid

@(Html.Kendo().Grid<iTrak.Web.Models.UserViewModel>()
        .Name("grid")
        .Columns(columns =>
        {
            columns.Bound(p => p.FirstName);
            columns.Bound(p => p.LastName);
            columns.Bound(p => p.Email);
            columns.Bound(p => p.EmailConfirmed);
            columns.Bound(p => p.IsAccountLocked);
            columns.Bound(p => p.RolesList).Hidden(true);
            columns.Command(command => { command.Edit(); command.Destroy(); }).Width(250);
        })
        .ToolBar(toolbar =>
        {
            //toolbar.Create();
            toolbar.Template(@<text>
                <a class="k-button k-button-icontext k-grid-add" href="/iTrak/UsersAdmin/User_Read?grid-mode=insert"><span class="k-icon k-i-add"></span>Add</a>
            </text>);
        })
                    .Editable(editable => editable.Mode(GridEditMode.PopUp).TemplateName("User").Window(w => w.Title("Edit User").Width(700).Height(500)))
            .Pageable()
            .Sortable()
            .Scrollable()
            .HtmlAttributes(new { style = "height:550px;" })
            .DataSource(dataSource => dataSource
                .Ajax()
                .PageSize(20)
                .Events(events =>
                {
                    events.Error("onErrorHandler");
                    events.RequestEnd("onGridRequestEnd");
                })
                .Model(model => model.Id(p => p.Id))
                .Create(update => update.Action("User_Create", "UsersAdmin").Data("onUserCreate"))
                .Read(read => read.Action("User_Read", "UsersAdmin"))
                .Update(update => update.Action("User_Update", "UsersAdmin"))
                .Destroy(update => update.Action("User_Destroy", "UsersAdmin"))
            )
)

 

I have a user template which is used to edit the user

@model iTrak.Web.Models.UserViewModel
<div>
    @Html.HiddenFor(m => m.Id)
    <div class="form-group">
        @Html.LabelFor(m => m.FirstName, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.Kendo().TextBoxFor(m => m.FirstName).HtmlAttributes(new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.LastName, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.Kendo().TextBoxFor(m => m.LastName).HtmlAttributes(new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.Kendo().TextBoxFor(m => m.Email).HtmlAttributes(new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.EmailConfirmed, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @Html.Kendo().CheckBoxFor(m => m.EmailConfirmed).HtmlAttributes(new { @class = "form-control" })
        </div>
    </div>
    <div class="form-group">
        @Html.LabelFor(m => m.RolesList, new { @class = "col-md-2 control-label" })
        <div class="col-md-10">
            @(Html.Kendo().MultiSelectFor(m => m.RolesList)  
            .HtmlAttributes(new { style = "width: 250px" })
            .ClearButton(true)
            .AutoClose(false)
 
            .DataTextField("RoleName")
            .DataValueField("RoleId")           
            .DataSource(source =>
            {
                source.Read(read =>
                {
                    read.Action("Role_Read", "RolesAdmin");
                });
            })
            )
        </div>
 
 
    </div>
</div>

 

Role read action to populate the list

public ActionResult Role_Read()
{
    IQueryable<IdentityRole> roles = RoleManager.Roles;
     
    var result = roles.Select(n => new
    {
        RoleId = n.Id,
        RoleName = n.Name
    }).OrderBy(o => o.RoleName);
 
    return Json(result, JsonRequestBehavior.AllowGet);
}

 

UserViewModel

public class UserViewModel
{
    public string Id { get; set; }
 
    [DisplayName("First Name")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "First Name required")]
    public string FirstName { get; set; }
 
    [DisplayName("Last Name")]
    [Required(AllowEmptyStrings = true, ErrorMessage = "Last Name required")]
    public string LastName { get; set; }
 
    [DisplayName("Email")]
    [Required(AllowEmptyStrings = false, ErrorMessage = "Email required")]
    [Display(Name = "Email")]
    [EmailAddress]
    public string Email { get; set; }
 
    [DisplayName("Email Confirmed")]
    public bool EmailConfirmed { get; set; }
 
    [DisplayName("Is Account Locked")]
    public bool IsAccountLocked { get; set; }
 
    [DisplayName("Roles")]
    public IEnumerable<SelectListItem> RolesList { get; set; }
}

 

The MultiSelectFor is populated with the list of roles from the database, but I can't get the list populated with the selected values from the user.  I have tried the value but this is expecting a list of integers.  How do i populate the MultiSelect when the user edits a user? Also do i need to have the hidden roles column in the grid?

Regards

Graham

 

0
Konstantin Dikov
Telerik team
answered on 08 May 2017, 10:58 AM
Hi Graham,

One option for binding the selected values to the MultiSelect would be by storing an array with the selected "value" field values only or by binding the MultiSelect to a collection with SelectItems (the same as the collection from the Grid, where the Value and Text data fields are the same).

Please give this a try and let me know if the issue is resolved.


Regards,
Konstantin Dikov
Telerik by Progress
Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Tags
MultiSelect
Asked by
Jark Monster
Top achievements
Rank 1
Answers by
Jark Monster
Top achievements
Rank 1
Daniel
Telerik team
Samuel
Top achievements
Rank 2
Petur Subev
Telerik team
Luis
Top achievements
Rank 1
Dimitar
Telerik team
Alexandra
Top achievements
Rank 1
Graham
Top achievements
Rank 1
Konstantin Dikov
Telerik team
Share this question
or