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

Multiselect does not send data to controller method

8 Answers 2390 Views
MultiSelect
This is a migrated thread and some comments may be shown as answers.
Ruben
Top achievements
Rank 1
Ruben asked on 22 Sep 2017, 03:09 PM

Hi, I've been working at this for some time to no avail. Here is my code: 

// view models

 

public class RegisterViewModel
{
    [Required]
    [Display(Name = "Roles")]
    public List<RoleModel> RolesList { get; set; }
}
 
public class RoleModel
{
    public string Id { get; set; }
    public string Name { get; set; }
}

 

// view

 

@model ERMgtProgram.Models.RegisterViewModel
@using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    <div class="form-group">
    @Html.LabelFor(m => m.RolesList)
    @(Html.Kendo().MultiSelectFor(m => m.RolesList)
        .Name("RolesList")
        .Placeholder("Select roles")
        .DataTextField("Name")
        .DataValueField("Id")
        .HtmlAttributes(new { style = "width: 485px;" })
        .IgnoreCase(true)
        .AutoBind(true)
                .DataSource(datasource =>
                {
                    datasource.Read(read => read.Action("ReadRolesList", "Manage"));
                })
    )
    </div>
     
    <div class="form-group">
        <div class="col-md-offset-2 col-md-10">
            <input type="submit" class="k-button" value="Register" />
        </div>
    </div>
}
<script>
$(document).ready(function () {
    var multiSelect = $("#RolesList").data("kendoMultiSelect");
});
</script>

 

//  Controller method for reading data

 

[Authorize(Roles = "DM_Admin")]
public async Task<ActionResult> ReadRolesList()
{
    var dmRoles = await RoleManager.Roles.Where(r =>
        r.Name.Contains("DM_")).ToListAsync();
    var roles = dmRoles.Select(u => new RoleModel
                    {
                    Id = u.Id,
                    Name = u.Name
        }).ToList();
 
    return Json(roles, JsonRequestBehavior.AllowGet);
}

 

// controller method that widget posts back to
 
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        // additional code
    }
    // additional code
}

 

So, in the view, the MultisSelect widget populates with the correct list of roles, and I am able to select them and everything is fine, and when I click the button to submit the form the correct "Register" controller method is called.

However, ModelState.IsValid == false and my model.RolesList is empty

Additionally, I receive this exception:

Exception {"The parameter conversion from type 'System.String' to type 'ERMgtProgram.Models.RoleModel' failed because no type converter can convert between these types."} System.Exception {System.InvalidOperationException}
When debugging I can see that the attempted value was: "AttemptedValue "2" string"

Why is the MultiSelect widget not posting back to the controller with type: List<RoleModel>, and what is an efficient fix for this issue?

 

Thanks for all the help!
Ruben

Antony
Top achievements
Rank 1
Iron
commented on 27 Jul 2021, 01:44 AM

Not directly answering the question above, but if like me you are investigating how to insert a database record which includes data from a multiselect in your form, this is what I have done:
The model includes a List which is used by the multiselect, but I convert that list to a comma delimited string before insert ..
MODEL
public List<string> StructureCodes { get; set; }
public string StructurePoint { get; set; }
CONTROLLER
main.StructurePoint = string.Join(", ", main.StructureCodes);
So it is string.Join that converts the List into a string - choose your own delimiter.

8 Answers, 1 is accepted

Sort by
0
Ruben
Top achievements
Rank 1
answered on 25 Sep 2017, 07:56 PM
Any feedback would be greatly appreciated. 
0
Dimitar
Telerik team
answered on 26 Sep 2017, 08:04 AM
Hello Ruben,

I am attaching an ASP.NET MVC solution, where a similar scenario to the one described is demonstrated (Binding Kendo UI MultiSelect to model).

I have created the above solution based on the code sample provided and I have made a few modifications in order to achieve the desired result:

1) When the widget is initialized via a [WidgetName]For method, the id and name for the element are automatically set and there is no need to set the Name() option. More information can be found in the Fundamentals article.

2) The MultiSelect widget uses a <select> element under the hood to pass its values to the controller method. Therefore, we are able to pass the selected values as List<string> RolesList { get; set; }. In case the RoleModel has an integer Id, then the parent will also have to be modified accordingly - List<int> RolesList { get; set; } .

In the provided solution, a breakpoint can be set in the beginning of the Save method in the HomeController to verify that the selected values are being successfully received.

Regards,
Dimitar
Progress Telerik
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.
0
Ruben
Top achievements
Rank 1
answered on 26 Sep 2017, 12:28 PM
Thank you for the help and explanation!
0
K.Ramadan
Top achievements
Rank 2
Veteran
answered on 09 Apr 2020, 01:50 PM

Hello Dimitar,

I downloaded your project and run it .. it works like a charm but, i can't figure out what the problem with my project is ...

so this is what i did ..

i Have

a Class Kommunikation with 20 properties,

Kendo MultiSelect :

@model WebCalendar_09K.Models.KommunikationViewModel
panelBar.Add().Text("Einladung")
            .Content(@<text>
                  
       @using (Html.BeginForm("Save", "Einladung",FormMethod.Post))
        {  
        <div class="form-group">
 
                @(Html.Kendo().MultiSelectFor(model => model.MitarbeiterCRM_Einladung)
                 .Name("Einladung")
                 .Placeholder("Auswählen ...")
                 .DataTextField("CrmUserNameZuordnung")
                 .DataValueField("ID")
                 .IgnoreCase(true)
                 .AutoBind(true)
                 .ValuePrimitive(false)
                 .Filter(FilterType.Contains)
                 .DataSource(source =>
                 {
                     source.Custom()
                     .ServerFiltering(true)
                     .Type("aspnetmvc-ajax")
                     .Transport(transport =>
                     {
                         transport.Read("CRM_USERNAME_ZUORDNUNG_CALL", "User");
                     })
                     .Schema(schema =>
                     {
                         schema.Data("Data")
                                 .Total("Total")
                                 .Errors("Errors");
                     });
                 })
                )
            </div>
            <input type="submit"  value="Save" />
            }
</text> 
);

 

3-ActionMethod :

[HttpPost]
public ActionResult Save ([DataSourceRequest]DataSourceRequest request,KommunikationViewModel model)
{
    EinladungViewModel einladungViewModel = new EinladungViewModel();
    string CrmUnameLocal = UserController.Global_CRMusername;
    using (var db = new cRM_FM_v2_KARAMEntities())
    {
 
        foreach (var item in model.MitarbeiterCRM_Einladung)
        {
            if (item != null)
            {
                var Entity = new TERMINEINLADUNGEN()
                {
                    SID_TERMINEINLADUNGEN = Guid.NewGuid(),
                    RECID_MITARBEITER     = db.MITARBEITER.Where(x => x.CRMUSERNAME == item).Select(q => q.SID_MITARBEITER).FirstOrDefault(),
                    ERFUSER = CrmUnameLocal,
                    ERFDAT = DateTime.Now,
                    LASTUSER = CrmUnameLocal,
                    LASTDAT = DateTime.Now,
                    ZUSAGE = einladungViewModel.Zusage,
                    ABSAGE = einladungViewModel.Absage,
                    VORBEHALT = einladungViewModel.Vorbehalt
                    //Sid_termineinladungen
                    //Recid_kommunikationen
 
                };
                db.TERMINEINLADUNGEN.Add(Entity);
                db.SaveChanges();
            }
        }
        return Json(new[] { model }.ToDataSourceResult(request));
 
    }
}

 

 

0
Dimitar
Telerik team
answered on 13 Apr 2020, 04:44 AM

Hello,

From the provided code snippet it is not clear what the problem with the MultiSelect is. That being said, could you elaborate a bit more on what is the exact issue that you  are experiencing?

Regards,
Dimitar
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
K.Ramadan
Top achievements
Rank 2
Veteran
answered on 15 Apr 2020, 08:11 AM

Hello,
So I want to add a MultiSelectto my Scheduler Edit-PopUp (This MultiSelect has Values from a DataBase), So I added a Property to my ClassViewModel.
and then I placed breakPoints in my ActionMethod to see when saving if the Value of this Property is changing, but it's not!
I added the MultiSelect This way, I found the right spot on the edit popup and append it to it.
I used this way because I couldn't find the way to add this to my custom Edit popup.
I added another KendoDropDownList items :

for (resource = 0; resource < resources.length; resource++) {
               if (resources[resource].multiple) {
                   jQuery(kendo.format('<select data-bind="value: {0}" name="{0}">', resources[resource].field))
                       .appendTo(container)
                       .kendoMultiSelect({
                           dataTextField: resources[resource].dataTextField,
                           dataValueField: resources[resource].dataValueField,
                           dataSource: resources[resource].dataSource,
                           valuePrimitive: resources[resource].valuePrimitive,
                           itemTemplate: kendo.format('<span class="k-scheduler-mark" style="background-color:\#= data.{0}?{0}:"None" \#"></span>\#={1}\#', resources[resource].dataColorField, resources[resource].dataTextField),
                           tagTemplate: kendo.format('<span class="k-scheduler-mark" style="background-color:\#= data.{0}?{0}:"none" \#"></span>\#={1}\#', resources[resource].dataColorField, resources[resource].dataTextField)
                       });
 
               } else {
                   jQuery(kendo.format('<select data-bind="value: {0}" name="{0}">', resources[resource].field))
                       .appendTo(container)
                       .kendoDropDownList({
                           dataTextField: resources[resource].dataTextField,
                           dataValueField: resources[resource].dataValueField,
                           dataSource: resources[resource].dataSource,
                           valuePrimitive: resources[resource].valuePrimitive,
                           optionLabel: "auswählen",
                           template: kendo.format('<span class="k-scheduler-mark" style="background-color:\#= data.{0}?{0}:"None" \#"></span>\#={1}\#', resources[resource].dataColorField, resources[resource].dataTextField)
                       });
 
               }
           }

 

and that is working like its life depend on it :-)

But i couldn't figure out how to do it like the way above .. so I'm trying to append it and that is not working..

i just want to someway to achieve this goel (taking the values of the MultiSelect to my Server DataBase)


0
Dimitar
Telerik team
answered on 16 Apr 2020, 05:45 AM

Hello,

To achieve the desired result, a template should be specified for the Scheduler as follows:

.Editable(editable => {
  editable.TemplateName("CustomEditorTemplate");
})

Then, the respective editors should be bound inside the template through the data-bind mvvm attribute pointing to the model field(lowercased):

<div class="k-edit-label">
    @(Html.LabelFor(model => model.Title))
</div>
<div data-container-for="title" class="k-edit-field">
    @(Html.TextBoxFor(model => model.Title, new { @class = "k-textbox", data_bind = "value:title" }))
</div>

There is an available ASP.NET MVC solution that you could use for reference on the above and in general for building a custom edit template for the Scheduler:

Regards,
Dimitar
Progress Telerik

Progress is here for your business, like always. Read more about the measures we are taking to ensure business continuity and help fight the COVID-19 pandemic.
Our thoughts here at Progress are with those affected by the outbreak.
0
K.Ramadan
Top achievements
Rank 2
Veteran
answered on 17 Apr 2020, 07:14 PM
What a Legend you are .. Thank you
Tags
MultiSelect
Asked by
Ruben
Top achievements
Rank 1
Answers by
Ruben
Top achievements
Rank 1
Dimitar
Telerik team
K.Ramadan
Top achievements
Rank 2
Veteran
Share this question
or