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