I'm fairly new to MVC (and web development in general) and I keep coming across several 'gotchas' which result in unexpected behaviour. I am using Kendo UI for ASP.NET MVC, however I'm 99% certain that my problem is due to my lack of understanding of either Javascript or MVC rather than anything to do with Kendo.
You should be able to reproduce the problem using the following code:
Models:
public
class
DemoClass
{
public
int
id {
get
;
set
; }
public
string
randomData {
get
;
set
; }
public
List<DemoPartyDetails> partyDetails {
get
;
set
; }
public
DemoClass()
{
partyDetails =
new
List<DemoPartyDetails>();
}
}
public
class
DemoPartyDetails
{
public
int
id {
get
;
set
; }
public
string
firstName {
get
;
set
; }
public
string
surname {
get
;
set
; }
public
string
gender {
get
;
set
; }
public
DemoPartyDetails()
{
}
}
Controller:
public
class
DemoController : Controller
{
// GET: Demo
public
ActionResult Index()
{
DemoClass demo =
new
DemoClass();
return
View(demo);
}
[HttpPost]
public
ActionResult Create(DemoClass model)
{
try
{
if
(model.partyDetails[0].gender !=
null
)
Console.WriteLine(
"Party details populated"
);
else
Console.WriteLine(
"Something went wrong..."
);
return
RedirectToAction(
"Index"
);
}
catch
{
return
View();
}
}
}
View:
@model DemoPortal.Models.DemoClass
<
html
>
<
head
>
<
meta
name
=
"viewport"
content
=
"width=device-width"
/>
<
title
></
title
>
</
head
>
<
body
>
@using (Html.BeginForm("Create", "Demo", FormMethod.Post))
{
<
div
>
@Html.EditorFor(model => model.randomData)
</
div
>
<
div
>
<
a
class
=
"k-button k-button-icontext k-add-button"
href
=
"#"
><
span
class
=
"k-icon k-i-add"
></
span
>Add Party</
a
>
@(Html.Kendo().ListView(Model.partyDetails)
.Name("demoListView")
.TagName("div")
.ClientTemplateId("demoTemplate")
.DataSource(dataSource => dataSource
.Model(model => model.Id(x => x.id))
)
.Editable(editable => editable.TemplateName("DemoPartyDetails"))
)
</
div
>
<
input
type
=
"submit"
value
=
"Submit"
/>
}
</
body
>
</
html
>
<
script
type
=
"text/x-kendo-tmpl"
id
=
"demoTemplate"
>
<
div
class
=
"demoParty"
>
<
h3
>#:firstName#</
h3
>
<
span
>#:surname#</
span
>
<
input
type
=
"hidden"
name
=
"PartyDetails[#:index(data)#].firstName"
value
=
"#:firstName#"
/>
<
input
type
=
"hidden"
name
=
"PartyDetails[#:index(data)#].surname"
value
=
"#:surname#"
/>
<
input
type
=
"hidden"
name
=
"PartyDetails[#:index(data)#].gender"
value
=
"#:gender#"
/>
</
div
>
</
script
>
<
script
>
$(function() {
var listView = $("#demoListView").data("kendoListView");
$(".k-add-button").click(function(e) {
listView.add();
e.preventDefault();
});
});
function index(dataItem) {
var data = $("#demoListView").data("kendoListView").dataSource.data();
return data.indexOf(dataItem);
}
function maleClick(e) {
document.getElementById("gender").value = "M";
document.getElementById("randomData").value = "random";
var maleButton = document.getElementById("IsMale");
var femaleButton = document.getElementById("IsFemale");
femaleButton.classList.remove("k-primary");
maleButton.classList.add("k-primary");
};
function femaleClick(e) {
document.getElementById("gender").value = "F";
var maleButton = document.getElementById("IsMale");
var femaleButton = document.getElementById("IsFemale");
maleButton.classList.remove("k-primary");
femaleButton.classList.add("k-primary");
};
</
script
>
DemoPartyDetails Editor Template
@model DemoPortal.Models.DemoPartyDetails
@using (Html.BeginForm())
{
<
div
>
<
div
>
<
label
>Gender:</
label
>
@(Html.Kendo().Button()
.Name("IsMale")
.Content("Male")
.HtmlAttributes(new { type = "button" })
.Events(ev => ev.Click("maleClick")))
@(Html.Kendo().Button()
.Name("IsFemale")
.Content("Female")
.HtmlAttributes(new { type = "button", @class = "k-primary" })
.Events(ev => ev.Click("femaleClick")))
</
div
>
@(Html.HiddenFor(model => model.id))
@(Html.EditorFor(model => model.gender))
@(Html.EditorFor(model => model.firstName))
@(Html.EditorFor(model => model.surname))
<
div
class
=
"btnArea"
>
<
a
class
=
"k-button k-update-button"
href
=
"\\#"
><
span
class
=
"k-icon k-update"
></
span
></
a
>
<
a
class
=
"k-button k-cancel-button"
href
=
"\\#"
><
span
class
=
"k-icon k-cancel"
></
span
></
a
>
</
div
>
</
div
>
}
When running this code, I can click the button to add a new party, the editor template appears as expected and I press the 'Male' button, which populates the gender field with "M".
I then fill in the other two fields with generic "Test" and "Person" data before confirming the entry and then pressing submit.
What I find when I place a breakpoint at the controller however is that the model being passed through has the gender set to null. The first name and surname ("Test" and "Person") are fully populated however. The randomData is also fully populated as expected.
Interestingly, if I go back and manually type something like "Male" into the gender field, that is now also populated. It's only when I try to use javascript to set the value that it's null.
The ultimate goal is to have a hidden field populated by javascript when a button is pressed, so if someone could point out my mistake it would be very much appreciated!