Hi,
I have a Kendo Tabstrip in which I use LoadContentFrom to load content from a controller action that return a PartialView. The code is
<% Html.Kendo().TabStrip()
.Name("TabStrip")
.Items(tabstrip =>
{
foreach (var pillar in Model.Evaluation.Pillars)
{
tabstrip.Add()
.Text("Name")
.LoadContentFrom("EvaluationFormPillar", "Evaluations", new { id = Model.Evaluation.Id, pillarId = pillar.Id,
hasActionItem = Model.Editable , editable = Model.Editable
});
}
})
.SelectedIndex(Model.SelectedTabIndex)
.Render();
%>
public ActionResult EvaluationFormPillar(int id, string pillarId, bool hasActionItem, bool editable)
{
var model = new EvaluationPillarViewModel();
Evaluation evaluation = this._evaluationsBL.GetEvaluation(id);
......
return PartialView(model);
}
But strangely enough, LoadContentFrom can't go to action "EvaluationFormPillar". It just displays a empty tabstrip with correct tab (set by SelectedIndex). Can anyone help me on this problem? Thanks.
7 Answers, 1 is accepted
I tried to reproduce the problem locally but to no avail – everything is working as expected on our side (as seen in this screencast). Could you please provide runable project where the issue is reproduced? This would help us pinpoint the exact reason for this behavior.
Vladimir Iliev
Telerik
Hi Vladimir,
I attach a sample project named MVC_Controls_Kendo as well as
MVC_Controls_Kendo Database to show you the problem. Because of the size
limit, I remove the package in the
project. The package include, Kendo MVC (2015.1.429.440.Trial), MVC 4
and many others. The simplest way to recreate the solution is to create
new Telerik MVC project (name: MVC_Controls_Kendo) and select .Net 4 and
ASPX (not razor), and add the source files attached.
Please add the OTPTEST.mdf in attached MVC_Controls_Kendo Database
to the Data folder for SQL Server Express on the your pc and attach it
in SQL management studio. Then modify the connection string in Webconfig
in MVC_Controls_Kendo project and App.Config file in Data project.
Currently it is:
<add name="OTPTESTEntities"
connectionString="metadata=res://*/Model3.csdl|res://*/Model3.ssdl|res://*/Model3.msl;provider=System.Data.SqlClient;provider
connection string="data source=ZHANG-PC\SQLEXPRESS;initial
catalog=OTPTEST;integrated
security=True;multipleactiveresultsets=True;App=EntityFramework""
providerName="System.Data.EntityClient" />
Replace ZHANG-PC with your pc name. After launching the project, just click on "Action Items", which
will go to ActionItems.aspx.
Click any link in "Type Desc" column and it will redirect to EvaluationForm.aspx which will display a Kendo TabStrip. In each of its tab, it supposes to display a Kendo Grid defined in EvaluationFormTab_....ascx files (there are total 7 of them). For example, after clicking "Overall" tab, EvaluationFormTab_Overall controller will return Partialview(model) to EvaluationFormTab_Overall.ascx file in which a a Kendo Grid is defined.
The problem is that while it can go to EvaluationFormTab_Overall controller correctly, it can't access EvaluationFormTab_Overall.ascx somehow, i.e. it won't execute EvaluationFormTab_Ajax, the Read action for the Grid. I can not solve this problem and need your help. Thanks.
Thank you for the provided project. After inspecting it it appears that the reason for current behavior is related to the following points:
- The use of "Model.Evaluation.SportId" inside the tab partial views throws error - this is error is thrown as there is no such field "Evaluation" in the view model.
- Event handlers are added after the Grid code - this throws JavaScript error as the widget JavaScript code is executed before the event handlers are loaded. Moving the event handlers to the top of the view will fix the errors.
For convenience I applied the above fixes to the "Benchmarks" view:
<%@ Control Language=
"C#"
Inherits=
"System.Web.Mvc.ViewUserControl<Models.EvaluationPillarViewModel>"
%>
<script type=
"text/javascript"
>
function onPillarQuestionsRequestEnd(e) {
if
(e.type ==
"create"
|| e.type ==
"update"
|| e.type ==
"destroy"
) {
this
.read();
}
}
function onEditQuestionGrid(e) {
// var sportId = '<%: Model.Evaluation.SportId %>';
// var canEditSportQuestions = <%: Model.CanEditSportQuestions.ToString().ToLower() %>;
}
</script>
<div>
<%= Html.Kendo().Grid<Models.EvaluationQuestion>()
.Name(
"QuestionsGrid"
+ Model.Pillar.Id)
.TableHtmlAttributes(
new
{ style =
"font-size:8pt;"
})
.HtmlAttributes(
new
{ style =
"height:400px"
})
.DataSource(dataSource => dataSource
.Ajax()
.Model(model => model.Id(a => a.Id))
.ServerOperation(
true
)
.Events(e => e.RequestEnd(
"onPillarQuestionsRequestEnd"
))
.Create(create => create.Action(
"InsertEvaluationFormTab_Ajax"
,
"Home"
,
new
{ preEvaluationId = Model.EvaluationId, prePillarId = Model.Pillar.Id, preEvaluationSportId = Model.SportId }))
.Read(read => read.Action(
"EvaluationFormTab_Ajax"
,
"Home"
,
new
{ id = Model.EvaluationId, pilId = Model.Pillar.Id }))
.Update(update => update.Action(
"UpdateEvaluationFormTab_Ajax"
,
"Home"
,
new
{ evaluationId = Model.EvaluationId, pillarId = Model.Pillar.Id, evaluationSportId = Model.SportId }))
)
.Editable(e => e.Mode(Kendo.Mvc.UI.GridEditMode.InLine).Enabled(
true
))
.Events(e => e.Edit(
"onEditQuestionGrid"
)
)
.Pageable(pager => pager.Input(
true
)
.Refresh(
true
)
.PageSizes(
new
[] { 10, 20, 30 })
)
.Scrollable(scrolling => scrolling.Height(380))
.Resizable(resize => resize.Columns(
true
))
.Sortable()
.Selectable()
.Filterable()
.ToolBar(t =>
{
t.Create();
})
.Columns(columns =>
{
columns.Bound(s => s.SortOrder)
.Width(40);
columns.Bound(s => s.Question)
.Width(150);
columns.Bound(s => s.NotApplicable)
.Width(75)
.HtmlAttributes(
new
{ style =
"text-align:center"
});
columns.Bound(s => s.InitialAssessment)
.Visible(!Model.CurrentStatusVisible)
.Width(70);
columns.Bound(s => s.CurrentAssessment)
.Visible(!Model.CurrentStatusVisible)
.Width(70);
columns.Bound(r => r.InitialStatus)
//.ClientTemplate("<div class='sprite sprite-StopLight_#=InitialStatus#'></div>")
.Filterable(
false
)
.Sortable(
false
)
.HtmlAttributes(
new
{ style =
"text-align:center"
})
.Width(100);
columns.Bound(r => r.CurrentStatus)
.Visible(Model.CurrentStatusVisible)
//.ClientTemplate("<div class='sprite sprite-StopLight_#=CurrentStatus#'></div>")
.Filterable(
false
)
.Sortable(
false
)
.HtmlAttributes(
new
{ style =
"text-align:center"
})
.Width(100);
columns.Bound(s => s.HasComments)
.HeaderHtmlAttributes(
new
{ title =
"Comment"
})
.ClientTemplate(
"<div class='sprite sprite-note commentQuestionsGridWindow'></div>"
)
.HtmlAttributes(
new
{ style =
"text-align:center"
})
.Width(50);
columns.Command(commands =>
{
commands.Edit();
})
.Width(170)
.Title(
"Command"
);
//.HtmlAttributes(new { style = "white-space:nowrap;float:right;" });
})
%>
</div>
Regards,
Vladimir Iliev
Telerik
I use the Chrome dev tools to track down the source of the issue by inspecting the console and the stack trace of the exception. For details on the matter you can check the following additional resources:
Also you may find helpful this tool which can be used to beautify minified code (like the one that the MVC wrappers output).
Regards,
Vladimir Iliev
Telerik
Thanks, Vladimir.
I also use Chrome Javascript Debugger. One thing I don't understand is that if Kendo grid is not displayed correctly or not displayed at all (in this case it is due to <script type="text/javascript"> is placed after Kendo Grid), how do you know it in debugger? Where do you set the break point? I know Javascript is often very tricky, i.e. slight problems (in unexpected places) could cause total collapse of program. But I am often not sure how to find it in through debugger by inspecting the console and the stack trace of the exception.
Hello,
In the case of event handlers defined at the wrong place, an error like "Uncaught ReferenceError: dataBound is not defined" will be thrown. This is a hint that this event handler should be placed before the widget code, so they are already loaded during initialization.
I hope this information helps. Have a happy holidays!
Dimiter Madjarov
Telerik