Hi,
I have a form with a MultiSelect displaying 'Exercises'. When the form is submitted the Exercise data is passed to the model as part of the form data (e.g.Exercises:"f86a60ce-04dc-4208-a2b6-a5ee00a1990f")
However when nothing is selected in the list, the 'Exercises' parameter is excluded from the post data. As the Exercise data is not included, the model.Entity.Exercises remains unchanged and contains the original selected values.
Is there any way the Kendo MultiSelect can pass in a null value when posting an empty list, so that the form data includes the Exercise parameter? e.g. Exercises:Null
@{if (edit){ @(Html.Kendo().MultiSelect() .Name("Exercises") .Placeholder(" ") .BindTo(ViewBag.Exercises) .HtmlAttributes(new { @class = "universalWidth" }))}
[HttpPost][ActionName("CourseEdit")]public ActionResult CourseEditPost(TypedModel<Course> model, string mode){ if (mode != "view") { if (UserController.EffectiveUser.GetClassAccess(typeof(Course)).Allows(Access.Update)) { // Save Mode if (mode == "new") { } else if (mode == "edit") { CourseService service = new CourseService(this.DbSession, new ModelStateWrapper(this.ModelState)); if (service.Save(model)) //model.Entity.Exercises error when no exercises selected in list { //Sucessfully saved DbSession.Flush(); } } } } CourseEditHelper(model); return View(model);}6 Answers, 1 is accepted
I am afraid that I was unable to locally replicate the described issue. This is why, I would like to ask you to send us a runnable sample, so we could investigate and test the exact implementation that you have at your end and pin down the reason for the experienced issue.
Regards,
Nencho
Telerik
Hi,
Having problems reducing demo zip to 2Mb. Here is a code sample that works...
View
@{ ViewBag.Title = "Home Page";}@model TelerikMvcApp1.Models.SimpleModel@using (Html.BeginForm("Save", "Home", FormMethod.Post )){ @(Html.LabelFor(model => model.Notes)) @(Html.TextBoxFor(model => model.Notes)) @(Html.LabelFor(model => model.Exercises)) @(Html.Kendo().MultiSelect() .Name("Exercises") .Placeholder(" ") .ValuePrimitive(true) .BindTo(ViewBag.VbExercises) .HtmlAttributes(new { @class = "universalWidth" })) <div> <input type="submit" value="Save" class="k-button" /> </div>}Controller
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;using TelerikMvcApp1.Entity;using TelerikMvcApp1.Models;namespace TelerikMvcApp1.Controllers{ public class HomeController : Controller { public ActionResult Index() { ViewBag.Message = "Welcome to ASP.NET MVC!"; ViewBag.VbExercises = MultiExercise(); return View(); } [HttpPost] public ActionResult Save(FormCollection form) { // if (form != null) { string selectedValues = form["Exercises"]; return Content("Selected Ids:" + selectedValues); } return new EmptyResult(); } private static MultiSelectList MultiExercise() { IList<Exercise> list = new List<Exercise>(); Exercise ex1 = new Exercise("Exercise 1", new Guid("180f12af-2155-4c1a-a915-32e13b7f6243")); Exercise ex2 = new Exercise("Exercise 2", new Guid("fc7989cd-7b10-47b5-b474-72083f2673c4")); Exercise ex3 = new Exercise("Exercise 3", new Guid("4334a7f1-8066-4c61-ad18-89f2c0933cdf")); list.Add(ex1); list.Add(ex2); list.Add(ex3); MultiSelectList result = new MultiSelectList(list, "Oid", "Title", list.Select(s => new Guid("180f12af-2155-4c1a-a915-32e13b7f6243").ToString()).ToList()); return result; } }}Model
using System;using System.Collections.Generic;using System.Linq;using System.Web;using TelerikMvcApp1.Entity;namespace TelerikMvcApp1.Models{ public class SimpleModel { private IList<Exercise> exercises; public virtual string Notes { get; set; } /// <summary> /// Exercise /// </summary> public virtual IList<Exercise> Exercises { get { return exercises; } set { exercises = value; } } }}Entity
using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace TelerikMvcApp1.Entity{ public class Exercise { /// <summary> /// Title /// </summary> public virtual string Title { get; set; } /// <summary> /// Oid /// </summary> public virtual Guid Oid { get; set; } public Exercise(string title, Guid oid) { this.Title = title; this.Oid = oid; } }}
Ideally the Html.Kendo().MultiSelect() component would have a setting that when set to true, will submit an empty string when the multi-select is empty.
I understand your concerns, however this is the pattern on how the FormCollection works - if there is no data selected/filled for the control - it is never initialized.
In order to achieve your scenario, you can verify whether the value for form["Exercises"] is null and use an empty string in the subsequent logic of your application.
Please let us know, should you have any further questions.
Regards,
Nencho
Telerik
Hi,
The custom framework we have implement merges data posted in the form with a pre loaded object and this seems to be the multi-select seems to be the only component causing issues. I understand not everyone will have this requirement. For anyone that needs an empty value posted by the form, I have created a JavaScript function to do this. Thanks for your help.
<script type="text/javascript" language="javascript">function saveCourseForm() { $('#courseEditForm select').each( function (index) { var input = $(this); if (input.val() == null) { var selectName = input.attr('name'); var selectNameHidden = $('input:hidden[name=' + selectName + ']').val(); if (selectNameHidden == null) { $('<input />').attr('type', 'hidden') .attr('name', selectName) .attr('value', "") .appendTo('#courseEditForm'); } } } ) $("#courseEditForm").submit();}</script>
@{if (edit){ @(Html.Kendo().MultiSelect() .Name("Prerequisites") .Placeholder(" ") .BindTo(ViewBag.Prerequisites) .HtmlAttributes(new { @class = "universalWidth" }))}<div class="float-right"> <input type="button" value="Save" class="k-button" onclick="javascript: saveCourseForm()" /> <input type="button" value="Close" class="k-button" onclick="javascript: cancelEditor('editCourseWindow')" /></div>Thank you for sharing your solution with the community.
Regards,
Nencho
Telerik
