The grid and popup work fine except the values I enter in create mode do not get passed back to my controller. Looking at the JS Console shows no errors. Monitoring the create process in Fiddler also shows no values being passed, although my form elements do show.
While debugging, the model in my controller is empty.
Here's the grid definition:
@(Html.Kendo().Grid<MyApp.Domain.Entities.TaktInterruptionViewModel>()
.Name("Interruptions")
.Columns(columns =>
{
columns.Bound(i => i.TaktInterruptionId).Hidden().IncludeInMenu(false);
columns.Bound(i => i.DateCreated).Title("Date").Width(75).Format("{0:d}");
columns.Bound(i => i.ActionCount).Title("Actions").Width(50).Hidden(true);
columns.Bound(i => i.MeetingType).Title("Meeting Type").Width(100).Hidden(true);
columns.Bound(i => i.AreaName);
columns.Bound(i => i.TypeName);
columns.Bound(i => i.Responsible);
columns.Bound(i => i.Description).Width(300);
columns.Bound(i => i.Interruption).Width(75).Hidden(true);
columns.Bound(i => i.TaktMissed).Title("Missed").Width(75);
})
.ClientDetailTemplateId("ActionsTemplate")
.ToolBar(toolbar => toolbar.Create().Text("Add Interruption"))
.Editable(edit => edit.Mode(GridEditMode.PopUp).TemplateName("Create").Window(w => w.Title("Interruption").Name("addInterruption").Modal(true)))
.DataSource(datasource => datasource.Ajax()
.Model(model => model.Id(p => p.TaktInterruptionId))
.ServerOperation(false)
.PageSize(5)
.Create(create => create.Action("Create", "Home"))
.Read(read => read.Action("GetInterruptions", "Home")))
.Groupable()
.Pageable()
.Sortable()
.Filterable()
.ColumnMenu()
.Selectable(s => s.Mode(GridSelectionMode.Multiple))
.Reorderable(reorder => reorder.Columns(true))
.Resizable(resize => resize.Columns(true))
.Events(events => events.Change("displayChart"))
)
My create editor template is as follows:
@model MyApp.Domain.Entities.TaktInterruptionViewModel
@{
ViewBag.Title = "Index";
}
<div class="span-14" style="padding: 10px;">
@Html.ValidationSummary(true)
<hr class="space" />
<div>
@Html.LabelFor(model => model.DateCreated)<br />
@(Html.Kendo().DatePicker().Name("DateCreated").Value(DateTime.Today))
<br />
@Html.ValidationMessageFor(model => model.DateCreated, null, new { style = "color:red;" })
</div>
<hr class="space" />
<div class="span-7">
@Html.LabelFor(model => model.AreaId)<br />
@(Html.Kendo().DropDownListFor(model => model.AreaId)
.Name("AreaId")
.HtmlAttributes(new { style = "width:200px" })
.OptionLabel("Select Area...")
.DataTextField("AreaName")
.DataValueField("AreaId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetAreas", "Area");
});
})
)
<br />
@Html.ValidationMessageFor(model => model.AreaId)
</div>
<div class="span-6">
@Html.LabelFor(model => model.TaktInterruptionTypeId)<br />
@(Html.Kendo().DropDownListFor(model => model.TaktInterruptionTypeId)
.Name("TaktInterruptionTypeId")
.HtmlAttributes(new { style = "width: 200px" })
.OptionLabel("Select Type...")
.DataTextField("TypeName")
.DataValueField("TaktInterruptionTypeId")
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetTypes", "Area").Data("filterTypes");
}).ServerFiltering(true);
})
.Enable(false)
.AutoBind(false)
.CascadeFrom("AreaId")
)
<br />
@Html.ValidationMessageFor(model => model.TaktInterruptionTypeId, null, new { style = "color:red;" })
</div>
<hr class="space" />
<div class="span-11">
@Html.LabelFor(model => model.Description)<br />
@Html.TextAreaFor(model => model.Description, new { @class = "multi-line" })
<br />
@Html.ValidationMessageFor(model => model.Description, null, new { style = "color:red;" })
</div>
<hr class="space" />
<div class="span-5">
@Html.LabelFor(model => model.Interruption)<br />
@(Html.Kendo().NumericTextBox().Name("Interruption").Format("#.0").Value(0))
<br />
@Html.ValidationMessageFor(model => model.Interruption)
</div>
<div class="span-6">
@Html.LabelFor(model => model.TaktMissed)<br />
@(Html.Kendo().NumericTextBox().Name("TaktMissed").Format("#.0").Value(0))
<br />
@Html.ValidationMessageFor(model => model.TaktMissed)
</div>
<hr class="space" />
<div>
@Html.LabelFor(model => model.Responsible)<br />
@Html.EditorFor(model => model.Responsible, new { @class = "k-input k-textbox" })
<br />
@Html.ValidationMessageFor(model => model.Responsible, null, new { style = "color:red;" })
</div>
<hr class="space" />
<hr class="space" />
</div>
<script type="text/javascript">
function filterTypes() {
return {
AreaID: $("#AreaId").val()
};
}
</script>
And my controller create method is:
[HttpPost]
public ActionResult Create([DataSourceRequest] DataSourceRequest request, MyApp.Domain.Entities.TaktInterruptionViewModel taktInterruption)
{
try
{
if (ModelState.IsValid)
{
// code removed for brevity
}
return Json(ModelState.ToDataSourceResult());
}
catch(Exception ex)
{
// code removed for brevity
}
}
If I remove my editor template from the equation and allow Kendo to do the popup, the information is passed to my controller; however, I want to control the layout of the popup and I also have cascading drop-downs (that work), thus the editor template.
My question is why aren't my values that I enter in the popup being passed to my controller?
17 Answers, 1 is accepted
Is none of the fields bound or only some of them are not bound which makes the model invalid? Since the code you shared looks okey I will need a project to run.
Take a look at this code library - it is similar to yours and might help you find the reason.
Kind Regards,
Petur Subev
the Telerik team
BTW - NONE of my fields are binding.
public class TaktInterruptionViewModel
{
public int TaktInterruptionId { get; set; }
[Display(Name = "Interruption Date")]
public DateTime DateCreated { get; set; }
[Display(Name="Interruption Type")]
public int TaktInterruptionTypeId { get; set; }
[Display(Name="Type")]
public string TypeName { get; set; }
[Display(Name="Area")]
public int AreaId { get; set; }
[Display(Name="Area")]
public string AreaName { get; set; }
[Display(Name = "Meeting Type")]
public string MeetingType { get; set; }
public string Description { get; set; }
public string Responsible { get; set; }
public int Interruption { get; set; }
[Display(Name = "Takt Missed")]
public int TaktMissed { get; set; }
public int ActionCount { get; set; }
}
There should not be any difference if you create or update a record - it should behave the same way. The only reason for such behavior I can think of is if the generated elements are prefixed - could you check with your browser if the name attribute of the input element is just the same as the name of the fields?
If they are the same could you modify the code library project and send it back so we can take a look?
Kind regards,
Petur Subev
the Telerik team
A solution to this post was not posted. I'm having the same issue. None of my fields are binding to the controller. I'm on version 2014.1.403
View Code
@(Html.Kendo().Grid<
FDolType
>()
.Name("grid")
.Columns(col =>
{
col.Bound(c => c.CountyCode);
col.Bound(c => c.FDolTypeCode);
col.Bound(c => c.GeneralDecisionNumber);
col.Bound(c => c.Published);
col.Bound(c => c.Expired);
col.Bound(c => c.EdmsSequence);
col.Command(com => com.Edit());
})
.ToolBar(t => t.Create())
.Editable(e => e.Mode(GridEditMode.PopUp))
.DataSource(d => d
.Ajax()
.Model(model => model.Id(p => p.Id))
.Read(r => r.Action("GetDecision", "Admin"))
.Update(u => u.Action("DescisionUpdate", "Admin"))
.Create(update => update.Action("DescisionCreate", "Grid"))
))
Could you please demonstrate your case so I can tell you exactly what goes wrong? We have multiple examples where it is working as expected, feel free to pick any of them to demonstrate your case:
http://www.telerik.com/support/code-library/aspnet-mvc/grid
Kind Regards,
Petur Subev
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
I am also experiencing this kind of problem with the custom pop-up template. When I submit in create mode, some values are not passed to my controller. Upon further investigation, it seems that nullable values in my model are the ones that have no values passed. So I tried to change a bit of code in your sample project in the code library just to check if this just happens in my code. http://www.telerik.com/support/code-library/custom-popup-editor. I changed the BirthDate field into a nullable datetime as below:
public class Person
{
public int PersonID { get; set; }
public string Name { get; set; }
public DateTime? BirthDate { get; set; }
}
After changing Birthdate to a nullable date, when I submit during edit and trace in my controller, the value is no longer passed. I hope you can look into this. Thanks.
Jessa
I tried to reproduce the problem locally but to no avail – everything is working as expected on our side. Could you please make sure the project is using the same culture on both the client and the server side and let us know of the result? You can check the following help article for more information about how to achieve it:
Regards,
Vladimir Iliev
Telerik
Check out the Telerik Platform - the only platform that combines a rich set of UI tools with powerful cloud services to develop web, hybrid and native mobile apps.
I am having this same problem (although I am using in-line editing).
Has there ever been a resolution for this?
Here is the Form Data that is being sent:
sort=&group=&filter=&ticketId=50757&weekStart=4%2F12%2F2015+12%3A00%3A00+AM&TicketGridRowId=28f09131-82d3-478f-95b1-dd2daad59028&Task=1060&SundayHours.TimeEntryId=0&SundayHours.WorkDay=%2FDate(1428811200000)%2F&SundayHours.Hours=&SundayHours.Comment=&MondayHours.TimeEntryId=179623&MondayHours.WorkDay=%2FDate(1428897600000)%2F&MondayHours.Hours=9&MondayHours.Comment=Test&TuesdayHours.TimeEntryId=179624&TuesdayHours.WorkDay=%2FDate(1428984000000)%2F&TuesdayHours.Hours=8&TuesdayHours.Comment=&WednesdayHours.TimeEntryId=179625&WednesdayHours.WorkDay=%2FDate(1429070400000)%2F&WednesdayHours.Hours=8&WednesdayHours.Comment=&ThursdayHours.TimeEntryId=0&ThursdayHours.WorkDay=%2FDate(1429156800000)%2F&ThursdayHours.Hours=&ThursdayHours.Comment=&FridayHours.TimeEntryId=0&FridayHours.WorkDay=%2FDate(1429243200000)%2F&FridayHours.Hours=&FridayHours.Comment=&SaturdayHours.TimeEntryId=0&SaturdayHours.WorkDay=%2FDate(1429329600000)%2F&SaturdayHours.Hours=&SaturdayHours.Comment=&Task.Completion=0
Here is my Update Method:
[HttpPost]
public
ActionResult TaskGrid_Update([DataSourceRequest] DataSourceRequest request, TicketGridViewModel task,
int
ticketId, DateTime weekStart)
{
task.SetDailyHoursDates(weekStart);
return
null
;
}
Here is TicketGridViewModel (Properties Only)
public
Guid TicketGridRowId {
get
;
set
; }
[UIHint(
"TaskEditor"
)]
public
TaskViewModel Task {
get
;
set
; }
[UIHint(
"HoursEditor"
)]
public
DailyHoursViewModel SundayHours {
get
;
set
; }
[UIHint(
"HoursEditor"
)]
public
DailyHoursViewModel MondayHours {
get
;
set
; }
[UIHint(
"HoursEditor"
)]
public
DailyHoursViewModel TuesdayHours {
get
;
set
; }
[UIHint(
"HoursEditor"
)]
public
DailyHoursViewModel WednesdayHours {
get
;
set
; }
[UIHint(
"HoursEditor"
)]
public
DailyHoursViewModel ThursdayHours {
get
;
set
; }
[UIHint(
"HoursEditor"
)]
public
DailyHoursViewModel FridayHours {
get
;
set
; }
[UIHint(
"HoursEditor"
)]
public
DailyHoursViewModel SaturdayHours {
get
;
set
; }
Here is TaskViewModel (Properties Only)
public
int
TaskId {
get
;
set
; }
public
string
TaskName {
get
;
set
; }
public
double
Completion {
get
;
set
; }
Here is DailyHoursViewModel (Properties Only)
public
int
TimeEntryId {
get
;
set
; }
public
DateTime WorkDay {
get
;
set
; }
public
double
? Hours {
get
;
set
; }
public
string
Comment {
get
;
set
; }
Here is my grid
@(Html.Kendo().Grid<
TicketGridViewModel
>(Model.Tasks)
.Name("TaskGrid_" + Model.TicketID)
.Columns(columns =>
{
columns.Bound(t => t.Task).ClientTemplate("#=Task.TaskName#").Title("Task");
columns.Bound(t => t.Task.Completion).Format("{0:p}").Width(75);
columns.Bound(t => t.SundayHours).ClientTemplate("#= FormatHours(SundayHours.Hours) #").Title("Sun").Width(60);
columns.Bound(t => t.MondayHours).ClientTemplate("#= FormatHours(MondayHours.Hours) #").Title("Mon").Width(60);
columns.Bound(t => t.TuesdayHours).ClientTemplate("#= FormatHours(TuesdayHours.Hours) #").Title("Tue").Width(60);
columns.Bound(t => t.WednesdayHours).ClientTemplate("#= FormatHours(WednesdayHours.Hours) #").Title("Wed").Width(60);
columns.Bound(t => t.ThursdayHours).ClientTemplate("#= FormatHours(ThursdayHours.Hours) #").Title("Thu").Width(60);
columns.Bound(t => t.FridayHours).ClientTemplate("#= FormatHours(FridayHours.Hours) #").Title("Fri").Width(60);
columns.Bound(t => t.SaturdayHours).ClientTemplate("#= FormatHours(SaturdayHours.Hours) #").Title("Sat").Width(60);
columns.Command(command =>
{
command.Edit().HtmlAttributes(new { style = "min-width: 30px" }).Text(" ").UpdateText(" ").CancelText(" ");
command.Destroy().HtmlAttributes(new { style = "min-width: 30px" }).Text(" ");
}).Width(138);
})
.ToolBar(toolbar => toolbar.Create())
.Editable(editable => editable.Mode(GridEditMode.InLine))
.DataSource(ds => ds
.Ajax()
.Model(model =>
{
model.Id(t => t.TicketGridRowId);
model.Field(t => t.TicketGridRowId).Editable(false).DefaultValue(Guid.NewGuid());
model.Field(t => t.Task).DefaultValue(new Evolve2.Web.Models.TimeEntry.TaskViewModel());
model.Field(t => t.Task.Completion).Editable(false);
model.Field(t => t.SundayHours).DefaultValue(new DailyHoursViewModel(Model.WeekStart));
model.Field(t => t.MondayHours).DefaultValue(new DailyHoursViewModel(Model.WeekStart.AddDays(1)));
model.Field(t => t.TuesdayHours).DefaultValue(new DailyHoursViewModel(Model.WeekStart.AddDays(2)));
model.Field(t => t.WednesdayHours).DefaultValue(new DailyHoursViewModel(Model.WeekStart.AddDays(3)));
model.Field(t => t.ThursdayHours).DefaultValue(new DailyHoursViewModel(Model.WeekStart.AddDays(4)));
model.Field(t => t.FridayHours).DefaultValue(new DailyHoursViewModel(Model.WeekStart.AddDays(5)));
model.Field(t => t.SaturdayHours).DefaultValue(new DailyHoursViewModel(Model.WeekStart.AddDays(6)));
})
.Update(update => update.Action("TaskGrid_Update", "TimeEntry").Data("GetTicketData(" + @Model.TicketID + ", '" + @Model.WeekStart + "')"))
.Destroy(destroy => destroy.Action("TaskGrid_Destroy", "TimeEntry").Data("GetTicketData(" + @Model.TicketID + ", '" + @Model.WeekStart + "')"))
.Create(create => create.Action("TaskGrid_Create", "TimeEntry").Data("GetTicketData(" + @Model.TicketID + ", '" + @Model.WeekStart + "')"))
)
)
From the provided information it seems that the "kendo.aspnetmvc.min.js" script is not included in the project - could you make sure it's correctly loaded after the "kendo.all.min.js" script? If the described behavior is still reproducible after this change could you please open a new support ticket / forum post and provide runable example where the issue is reproduced?
Regards,
Vladimir Iliev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
I too am having problems with this. In my case, I have several kendo bound controls on my popup and one of them is not populating the model.
@(Html.Kendo().DropDownListFor(m => m.ProductClass)... --> Works
@(Html.Kendo().MultiSelectFor(m => m.ProgramSelectedList)... --> DOES NOT UPDATE MODEL!
@(Html.Kendo().AutoCompleteFor(m => m.ProjectNum)... --> Works
I am finding the support and docs to be good but unwilling to look at anything outside of known good working examples. Yes, people get these controls to work - after a ton of hair pulling when their situation is *similar* to but not exactly like the samples. I find myself in that category with the project I am currently on. And no, I cannot give you source code as I work behind a firewall on proprietary data and applications.
So, back to the grid popup (MVC).
When I first pop-up the form everything is bound to the row data correctly. I now change my data via DropDowns, AutoCompletes and MultiSelects then click submit on the pop-up. The Ajax controller/update action is called and I inspect the model being passed in. Everything is as expected *EXCEPT* the MultiSelects. Those 2 properties still contain the original values.
Here is how I defined one of the MultiSelcts in the pop-up form:
<div class="col-xs-4 col-sm-4">
<span>
@Html.LabelFor(model => model.ProgramSelectedList)
</span>
@(Html.Kendo().MultiSelectFor(m => m.ProgramSelectedList)
.Placeholder("Select program...")
.HtmlAttributes(new { style = "width:200px" })
.DataSource(source =>
{
source.Read(read =>
{
read.Action("GetLookups", "AjaxProductReuse", new { id = "Program" });
});
})
)
<div style="font-weight:normal;">
@Html.ValidationMessageFor(model => model.ProgramSelectedList)
</div>
</div>
Here is the Select as shown in the browser:
<select name="ProgramSelectedList" id="ProgramSelectedList" aria-disabled="false" aria-readonly="false" style="width: 200px; display: none;" multiple="multiple" data-val-required="Please select at least 1 Program" data-val="true" data-role="multiselect" data-bind="value:ProgramSelectedList">
<option value="Obfuscated 1">Obfuscated 1</option>
<option value="Obfuscated 2">Obfuscated 2</option>
</select>
The list of values is stored in the DB as a comma delimited list. So this is what that portion of the model looks like:
[MetadataType(typeof(BomViewModelMetaData))]
public class BomViewModel
{
public string Program {get; set; }
public List<string> ProgramSelectedList { get { return Program.ToList(); } set { Program = value.ToDelimitedString(); } }
}
What am I missing?
From the provided information it's not clear for us what is the exact reason for current behavior - could you please open a new support ticket / forum post and provide runable example where the issue is reproduced? This would help us advice you better how to proceed.
Regards,
Vladimir Iliev
Telerik
I got it figured out... StackOverflow is where I posted the question and answer.
I was having this issue, but with model data attribute set to Editable(false)...
For e.g.
Have in modelview:
[Required]
[Editable(false)]
[UIHint("ValueViewReadonly")]
[Display(Name = "Approval Country", Order = 2)]
public int ApprovalCountryId { get; set; }
In the grid the column is defined as:
columns.ForeignKey(o => o.ApprovalCountryId, (System.Collections.IEnumerable)ViewData["ApprovalCountryId" + ValuesSuffix], "Id", "Value")
.EditorTemplateName("ValueViewReadonly");
And the field is set with default value in:
.Model(model =>
{
model.Id(o => o.ID);
model.Field(o => o.ApprovalCountryId).DefaultValue(ApprovalViewModelDefaults.DefaultApprovalCountryId);
})
And the controller is:
[HttpPost]
public ActionResult Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<ApprovalViewModel> models)
{
var results = new List<ApprovalViewModel>();
if (models != null && ModelState.IsValid)
{
foreach (var model in models)
{
dataService.Create(model);
results.Add(model);
}
}
return Json(results.ToDataSourceResult(request, ModelState));
}
I set the Editable(false) because it's a readonly field. By removing this attribute the default value that the field is set to is sent back to the controller. So workaround (for me) was to remove this data attribute and control the readonly behavior at the UI level.
I have noticed that the Editable(false) attribute is present, meanwhile, an editor template is used for the same column. When the column is marked as non-editable, then the cells within the column will not be opened for editing. Thus, the editor template will not be invoked.
Also, if somehow the cell's value is modified explicitly, the modification will not take place in the data source. This is due to the fact that the Data source is a separate component from the Grid. Setting the editable property to false at a data source level, the field will not be editable.
As per the default value, when a new item is created, the value specified in the DefaultValue setting will be used. It will not be a subject to editing, hence, the default value will be sent to the server.
Can you clarify what are exactly the differences between having the editable property set to true and false? What are the values that are sent to the controller? If it is possible, can you send me a runnable sample where the issue with sending the default values is present? This would enable me to obtain the big picture of your project and provide suggestions accordingly.
Kind regards,
Tsvetomir
Progress Telerik
Hi Tsvetomir, im also having the same issue where my model only returns values from two models. i Have a grid where when you click add new sitecode. A custom pop up window opens where inside the pop up window there's a tabstrip with partial views for each tabs.
i will post how i solved this issue. Make sure your class is matching with the names of your controls and defining the name attribute for your input controls.
in my case, i have custom popup window which adds a new record using a tabstrip. each tab has its own view. The pop up uses editor template called create. In the create template i had defined it with a form tag which does a post to a controller like below
@using (Html.BeginForm("sitecode_SaveCreate", "SiteCodes", FormMethod.Post, new { @class = "form-horizontal", role = "form", id = "SiteCodeform", autocomplete="off" }))
{
@Html.AntiForgeryToken()
@(Html.Kendo().TabStrip()
.Name("tabstrip")
.Items(tabstrip =>
{
tabstrip.Add().Text("SiteCodeType information")
.Selected(true) // select the first tab
// Set the tab content to a partial view using a strongly typed model
.Content(@<text> @Html.Partial("_SiteCodeTypeInformation", Model)</text>);
tabstrip.Add().Text("Company information")
.Enabled(false) // Disable the tab to prevent skipping ahead.
.Content(@<text> @Html.Partial("_SiteCodeCompanyInfor", Model)</text>);
tabstrip.Add().Text("Submit")
.Enabled(false)
.Content(@<text> @Html.Partial("_SiteCodeComplete", Model)</text>);
})
.Events(ev =>
{
ev.Select("onSelect");
// ev.Show("onShow");
})
.ToClientTemplate()
)
}
inside each tab as mentioned i had defined partial views inside which had another <form tags> inside. after removing the form tags inside the partial views and defining the the views as simple as possible and making sure the name attributes for input controls matching the properties defined in the class. like so below...
<label for="SiteCodeNumber" class="k-form-label">Site Code Nr</label>
<br />
<span class="k-form-field-wrap">
@(Html.Kendo().TextBox()
.Name("SiteCodeNumber") --> input attribute this is very important. you welcome to test it on debug on browser and try to edit and change the input attribute "name". it will pass null value.
.HtmlAttributes(new { required = "required", @readonly = "true" })
.ToClientTemplate())
</span>
my class looks like this below...
public class SiteCodeModelView
{
public int ID { get; set; }
public string MineCode { get; set; }
[Required]
public int SiteCode { get; set; }
public int SiteCodeNumber { get; set; }
}
hopefully it helps
kind regards
Tony
thanks guys
Hi, Tony, I am happy to hear that you have managed to resolve the case. It would be very helpful if you could edit your initial response to feature the before and after code snippets. You could remove anything that might be confidential.
It would definitely be very helpful to other members of our community who encounter a similar problem.