What is the proper location to post issues with the on demand courses?
Looking at the Telerik UI for ASP.NET Core course, comments are rarely responded to.
I'm trying to work through it but encountered an issue and can't really proceed with the course. Made a comment but I'm not sure anyone is really looking at them.
Based on dates displayed in the examples, the course was recorded in 2019 so I'm sure a number of changes have taken place since then.
Thanks,
Here is the scenario: I have a grid that is set to GridEditMode.InCell and Batch=true. I can make changes to up to 15 records in the grid, click save and the data posts back to the controller without issue. However, if I update greater than 15 records and click save, the postback to the controller works but the data is null.
I hope that this isn't a product limitation and I've verified that data being posted back is less than the limit of Json serializer.
A few caveats to my issue:
1. We have purchased the licensed version, but have not gone through internal channels to actually access the licensed version so I am still using the trial version. Is it possible that the trial version has a limitation like this?
2. The grid is a nested hierarchical grid and the data being updated is nested 3 deep.
3. While the grid doesn't display all the data, each record being posted back contains a nested json object (see example of data below). Because of configurable business requirements, the structure cannot be flat.
Any help would be appreciated. Specifically, knowing the save/update method in kendo code that is being called for batch saves with InCell mode.
Here is my grid (higher level nesting is omitted for simplicity):
<
script
id
=
"agents"
type
=
"text/kendo-tmpl"
>
@(Html.Kendo().Grid<
TLCAgentSchedulerShared.Models.AgentDailyScheduleModel
>
()
.Name("agent_#=Id#")
.Columns(columns =>
{
//columns.Command(command => { command.Destroy().Text(" "); }).Width(50);
columns.Command(command => { command.Destroy().Template("<
button
type
=
'button'
onclick
=
'removeAgent(this, setCoEId())'
class
=
'btn btn-danger btn-xs'
><
span
class
=
'glyphicon glyphicon-remove'
title
=
'Delete'
>X</
span
></
button
>").Text(" "); }).Width(50);
columns.Bound(b => b.FullName).Width(100).Title("Agent");
columns.Bound(b => b.Supervisor).Width(100).Title("Supervisor");
columns.Bound(b => b.TimeSlot).Width(50).Title("Schedule");
columns.Bound(b => b.AgentAssignments[0].IsAssigned).Width(70).Title("6:30AM - 8:30AM").EditorTemplateName("Boolean")
.ClientTemplate(@"<
input
type
=
'checkbox'
\\#: AgentAssignments[0].IsAssigned ?
checked
=
'checked'
: '' \\# />");
columns.Bound(b => b.AgentAssignments[1].IsAssigned).Width(70).Title("8:30AM - 3:00PM").EditorTemplateName("Boolean")
.ClientTemplate(@"<
input
type
=
'checkbox'
\\#: AgentAssignments[1].IsAssigned ?
checked
=
'checked'
: '' \\# />");
columns.Bound(b => b.AgentAssignments[2].IsAssigned).Width(70).Title("3:00PM - 5:00PM").EditorTemplateName("Boolean")
.ClientTemplate(@"<
input
type
=
'checkbox'
\\#: AgentAssignments[2].IsAssigned ?
checked
=
'checked'
: '' \\# />");
columns.Bound(b => b.AgentAssignments[3].IsAssigned).Width(70).Title("5:00PM - 7:30PM").EditorTemplateName("Boolean")
.ClientTemplate(@"<
input
type
=
'checkbox'
\\#: AgentAssignments[3].IsAssigned ?
checked
=
'checked'
: '' \\# />");
columns.Bound(b => b.AgentAssignments[0].Comments).Title("Comments").Width(195);
})
.DataSource(dataSource => dataSource
.Ajax()
.Events(events => events.Error("error_handler"))
.Model(model => model.Id(p => p.UserProfileId))
.Batch(true)
.Read(read => read.Action("GetDefaultAgentsByPod", "Grid").Data("setDayOfWeek(#=Id#)"))
.Update(update => update.Action("UpdateDefaultAgentsInPod", "Grid")).Events(events => events.Change("change_handler"))
//.Destroy(destroy => destroy.Action("RemoveDefaultAgentsInPod", "Grid").Data("setCoEId()")).Events(events => events.Change("change_handler"))
)
//.Pageable()
.HtmlAttributes(new { @class = "agentGrid" })
.ToolBar(toolbar =>
{
toolbar.Save();
toolbar.Custom().Text("Assign a New Agent").HtmlAttributes(new { onclick = "assignAgent(#=Id#)" });
})
.Editable(editable => editable.Mode(GridEditMode.InCell).DisplayDeleteConfirmation(false))
.Sortable()
.ToClientTemplate()
)
</
script
>
Here is my controller that works fine when less than 15 records have been updated (some security logic has been omitted to avoid potential confidentiality issues), but the key is that both the request object and the agents object are fully populated when less than 15 records:
[HttpPost]
public async Task<
ActionResult
> UpdateDefaultAgentsInPod([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")] IEnumerable<
AgentDailyScheduleModel
> agents)
{
//Convert incoming to json
string jsonData = JsonConvert.SerializeObject(agents);
using (var client = new HttpClient())
{
using (var response = await client.PostAsync(String.Format("{0}agent/UpdateDefaultAssignmentsByPod/", _baseApiUrl),
new StringContent(jsonData, Encoding.UTF8, "application/json")))
{
string apiResponse = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<
ApiResponse
<List<AgentDailyScheduleModel>>>(apiResponse);
if (result.IsValid)
{
agentList = result.ResponseData;
}
else
{
return BadRequest(String.Format("There was an error proccessing your request. Message: {0}", result.ResponseMessage));
}
}
}
var dsResult = agentList.ToDataSourceResult(request);
return Json(dsResult);
}
Here is what 1 record of data looks like:
[{
"UserProfileId": 150,
"NtLogin": "xxxx",
"FullName": "xxxx",
"Supervisor": null,
"TimeSlot": "7:30-19:00",
"AgentAssignments": [{
"PodId": 2,
"PodName": "PODFREpat",
"DailyAssignmentId": 9070,
"AgentDefaultScheduleId": 12699,
"BlockId": 1,
"IsScheduled": true,
"IsAssigned": true,
"IsDefault": true,
"Date": null,
"IsBlockFullyScheduled": false,
"Comments": null,
"CreatedBy": null,
"UpdatedBy": null,
"CreatedOn": "0001-01-01T00:00:00",
"UpdatedOn": "0001-01-01T00:00:00"
},
{
"PodId": 2,
"PodName": "PODFRE-pat",
"DailyAssignmentId": 9071,
"AgentDefaultScheduleId": 12724,
"BlockId": 2,
"IsScheduled": true,
"IsAssigned": true,
"IsDefault": true,
"Date": null,
"IsBlockFullyScheduled": true,
"Comments": null,
"CreatedBy": null,
"UpdatedBy": null,
"CreatedOn": "0001-01-01T00:00:00",
"UpdatedOn": "0001-01-01T00:00:00"
}, {
"PodId": 2,
"PodName": "POD FRE-pat",
"DailyAssignmentId": 9072,
"AgentDefaultScheduleId": 12723,
"BlockId": 3,
"IsScheduled": true,
"IsAssigned": true,
"IsDefault": true,
"Date": null,
"IsBlockFullyScheduled": true,
"Comments": null,
"CreatedBy": null,
"UpdatedBy": null,
"CreatedOn": "0001-01-01T00:00:00",
"UpdatedOn": "0001-01-01T00:00:00"
}, {
"PodId": 2,
"PodName": "POD FRE-pat",
"DailyAssignmentId": 9050,
"AgentDefaultScheduleId": 12722,
"BlockId": 4,
"IsScheduled": true,
"IsAssigned": true,
"IsDefault": true,
"Date": null,
"IsBlockFullyScheduled": false,
"Comments": null,
"CreatedBy": null,
"UpdatedBy": null,
"CreatedOn": "0001-01-01T00:00:00",
"UpdatedOn": "0001-01-01T00:00:00"
}
]
}]
Going through and testing the Kendo grid functionality. I created a new Telerik project using the menu and grid template.
.NET Core 3.1
Telerik.UI.for.AspNetCore (2021.1.224)
VS 2019
I can get my test data to load on the grid no problem, however when ever I enter text in the search box, it gives an "Input string was not in a correct format" exception on the server side. I've noticed, that if a defined column is bound to a string typed property, the search filter works fine. But if I have a int (or DateTime for that matter) typed property, that's when I get the exception. For example, in my object I have an ApplicationId property. If I exclude it in the .Columns definition of the grid, everything works fine, however if I include it, that's when the ToDataSourceResultAsync() method seems to choke, and I get the exception. Probably something dumb, but I can't seem to find what I could be doing wrong.
Class:
public
partial
class
Application
{
public
Application()
{
AppItems =
new
HashSet<AppItem>();
AppVersions =
new
HashSet<AppVersion>();
}
[Display(Name =
"Application ID"
)]
public
int
ApplicationId {
get
;
set
; }
[Display(Name =
"Application Name"
)]
[Required]
public
string
AppName {
get
;
set
; }
[Display(Name =
"Description"
)]
public
string
Description {
get
;
set
; }
[Display(Name =
"Added On"
)]
public
DateTime? AddedOn {
get
;
set
; }
[Display(Name =
"Added By"
)]
public
string
AddedBy {
get
;
set
; }
[Display(Name =
"Updated On"
)]
public
DateTime? UpdatedOn {
get
;
set
; }
[Display(Name =
"Updated By"
)]
public
string
UpdatedBy {
get
;
set
; }
public
virtual
ICollection<AppItem> AppItems {
get
;
set
; }
public
virtual
ICollection<AppVersion> AppVersions {
get
;
set
; }
}
Controller Method:
public
async Task<IActionResult> GetApplications([DataSourceRequest]DataSourceRequest request)
{
try
{
var apps = await _repo.GetApplicationsAsync();
var result = await apps.ToDataSourceResultAsync(request);
return
Json(result);
}
catch
(Exception e)
{
return
Json(
""
);
}
}
Designer:
<
div
class
=
"row"
>
<
div
class
=
"col-12"
>
@(Html.Kendo().Grid<
Application
>()
.Name("grdApplications")
.Columns(columns =>
{
columns.Bound(p => p.ApplicationId).Title("ID");
columns.Bound(p => p.AppName);
columns.Bound(p => p.Description);
//columns.Bound(p => p.AddedOn).Format("{0:MM/dd/yyyy}");
columns.Bound(p => p.AddedBy);
//columns.Bound(p => p.UpdatedOn).Format("{0:MM/dd/yyyy}");
columns.Bound(p => p.UpdatedBy);
columns.Command(command => { command.Edit().Text("Details"); command.Destroy(); }).Width(230);
})
.ToolBar(toolbar => { toolbar.Create().Text("Add New Application"); toolbar.Pdf(); toolbar.Excel(); toolbar.Search(); })
.Editable(editable => editable.Mode(GridEditMode.PopUp))
.Reorderable(reorderable => reorderable.Columns(true))
.Pageable()
.Sortable()
.ColumnMenu()
.Filterable()
.Pageable(pageable => pageable.PageSizes(new int[] { 10, 25, 50, 100 }))
.DataSource(dataSource => dataSource
.Ajax()
.Read(read => read.Action("GetApplications", "Applications"))
.Create(create => create.Action("CreateApplication", "Applications"))
.Update(update => update.Action("UpdateApplication", "Applications"))
.Destroy(destroy => destroy.Action("DeleteApplication", "Applications"))
.PageSize(10)
.Model(model => {
model.Id(p => p.ApplicationId);
model.Field(p => p.ApplicationId).Editable(false);
model.Field(p => p.AddedOn).Editable(false);
model.Field(p => p.AddedBy).Editable(false);
model.Field(p => p.UpdatedOn).Editable(false);
model.Field(p => p.UpdatedBy).Editable(false);
})
)
)
</
div
>
</
div
>
We have to used translated menu text from a resource bundle. For the localization we inject the IHtmlLocalizer in our Razor-Pages.
Following code doesn't work.
<kendo-menu name="customermenu">
<items>
<menu-item text='@localizer_Label["Lable_MyTeam"]'></menu-item>
</items>
</kendo-menu>
How can I localize my menu text?
Many thanks for your efforts,
Christian
Is there anyway to stop the inline editor from closing if there are errors? It currently closes the editor after clicking ok on the alert.
Here is my error event handler:
function errorHandler(e) {
if (e.errors) {
var message = "There are some errors:\n";
// Create a message containing all errors.
$.each(e.errors, function (key, value) {
if ('errors' in value) {
$.each(value.errors, function () {
message += this + "\n";
});
}
});
alert(message);
}
Hello,
How to change the Grid row color to be color 1 in even number rows, and color2 in odd number rows.
Thanks!
Hello,
I'm working with a DropDownTree which I create with the following code:
01.
@(Html.Kendo().DropDownTree()
02.
.Name(
"selectJobs"
)
03.
.DataValueField(
"id"
)
04.
.DataTextField(
"text"
)
05.
.HtmlAttributes(
new
06.
{
07.
@
class
=
"form-control"
08.
})
09.
.Filter(FilterType.Contains)
10.
.LoadOnDemand(
false
).MinLength(2)
11.
.BindTo((IEnumerable<DropDownTreeItemModel>)ViewBag.inlineDefault)
12.
.Events(e => e.Change(
"onJobChanged"
).DataBound(
"onJobDataBound"
))
13.
.Template(
"#= autocompleteFormatValue(data.item.text, 'selectJobsFilter') #"
)
14.
)
There is a way to change the content data of this tree, through an ajax call and when it completes, the following code is exeuted:
01.
function
(response) {
02.
var
ds =
new
kendo.data.HierarchicalDataSource({
03.
data: response,
04.
accentFoldingFiltering:
"fr-FR"
05.
});
06.
var
dropdowntree = $(
'#selectJobs'
).data(
'kendoDropDownTree'
);
07.
dropdowntree.setDataSource(ds);
08.
dropdowntree.treeview.expand(
".k-item"
);
09.
}
I believe I am using the 'accentFoldingFiltering' option properly, as per https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/configuration/accentfoldingfiltering
Yet, the diacritics filtering is not working. Any idea what is missing ?
For instance I would have the items you can see on my example1.png picture. And so I would expect that if I pressed e, which I do in example2.png, then I would see all the items that match "matie" including "matiè" but as you can see that's not the case.
Thanks!
If I select the text of a disabled combobox with double click and make copy paste the results text has line feed...
why this?
robert
Last week i migrated one of the projects i work on from .NET MVC to .NET Core.
It surprised me that the .NET Core wrappers lack the security trimming feature that the MVC wrappers support. I voted for this feautre request, but that can take ages before it gets implemented (if ever).
So i'm looking for a work around. Is there anybody out there that could give me some advice?
I used the .Action("actionname", "controllername") method of the menu item to get the securitytrimming going.