Search code examples
asp.net-mvckendo-uikendo-multiselect

Unable to load items into Kendo().MultiSelect


I am developing an ASP.net MVC application with EF Scaffolding using the code first approach. One of the view using Kendo MultiSelect is unable to load the items. At run time, the MultiSelect only displays the text "undefined".

Here is the Model

  public class SessionStudent
{
    public int SessionStudentID { get; set; }


    public int SessionID { get; set; }
    [Display(Name = "Session")]
    public virtual Session Session { get; set; }


    public IEnumerable<int> SelectedStudentIDs { get; set; }
    public IEnumerable<Student> Student { get; set; }


    public int GradeID { get; set; }
    [Display(Name = "Grade")]
    public virtual Grade Grade { get; set; }
}

Here is the Get and Post methods in Controller

   // GET: SessionStudents/Create
    public ActionResult Create()
    {
        ViewBag.GradeID = new SelectList(db.Grades, "GradeID", "GradeName");
        ViewBag.SessionID = new SelectList(db.Sessions, "SessionID", "SessionName");
        ViewBag.StudentID = new SelectList(db.Students, "StudentID", "FName");
        return View();
    }

    // POST: SessionStudents/Create

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "SessionStudentID,SessionID,GradeID")] SessionStudent sessionStudent)
    {
        if (ModelState.IsValid)
        {
            db.SessionStudents.Add(sessionStudent);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        ViewBag.GradeID = new SelectList(db.Grades, "GradeID", "GradeName", sessionStudent.GradeID);
        ViewBag.SessionID = new SelectList(db.Sessions, "SessionID", "SessionName", sessionStudent.SessionID);
        return View(sessionStudent);
    }

And here is the MultiSelect in the view

 <div class="form-group">
        @Html.LabelFor(model => model.SessionStudentID, "StudentID", htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.Kendo().MultiSelectFor(model => model.SessionStudentID).BindTo((SelectList)ViewBag.StudentID).DataTextField("FName").DataValueField("StudentID").Name("SelectedStudentIDs")



            @Html.ValidationMessageFor(model => model.SessionStudentID, "", new { @class = "text-danger" })
        </div>
    </div>

Any help in this regard is highly appreciated.


Solution

  • The problem is a misunderstanding of the SelectList contruction.

    When you create a SelectList with

    ViewBag.StudentID = new SelectList(db.Students, "StudentID", "FName");
    

    "StudentID" and "FName" are the mapping fields in the db.Students collection, NOT the accessor field names in the SelectList. The SelectList will still contain items with "Text" and "Value" fields mapped from "FName" and "StudentID".

    So, when you then bind the MultiSelect to

    @Html.Kendo().MultiSelectFor(model => model.SessionStudentID)
        .BindTo((SelectList)ViewBag.StudentID)
        .DataTextField("FName")
        .DataValueField("StudentID")
        .Name("SelectedStudentIDs")
    

    You are saying "Bind to the list ViewBag.StudentID with "FName" as the text field and "StudentID" as the value field. BUT ViewBag.StudentID is a SelectList, which uses Text and Value by definition.

    Removing the DataTextField and DataValueField specifiers should fix it for you, as then the MultiSelectFor will use the defaults of "Text" and "Value".

    You would only need to use the DataTextField and DataValueField if you BindTo() an arbitrary Enumerable that didn't use Text and Value as the accessors, i.e. if you didn't convert db.Students to a SelectList such that ViewBag.StudentID was an IEnumerable, then you would need to tell the MultiSelect to use FName and StudentID to access the items in the bound enumerable.