For almost 2 years, we have been running a page that has a Kendo Tab Strip with some Kendo Grids below that will show or hide based on the selected tab. The data source for each is defined with as a property of the grid. It is the same for all grids, with filters that get passed to switch which data comes back.
Starting with SP1 and still an issue in SP2, the last tab's filter is what filters every time, no matter what tab we are on. The grids are still switching correctly, so that doesn't appear to be the issue.
This is where we set the filters:
$(
"#vDrafts"
).data(
"kendoGrid"
).dataSource.transport.options.read.data = { list:
"mine"
, tab:
"NotSubmitted"
};
$(
"#vPending"
).data(
"kendoGrid"
).dataSource.transport.options.read.data = { list:
"mine"
, tab:
"AwaitingApproval"
};
$(
"#vApproved"
).data(
"kendoGrid"
).dataSource.transport.options.read.data = { list:
"mine"
, tab:
"ApprovedVouchers"
};
$(
"#vRejected"
).data(
"kendoGrid"
).dataSource.transport.options.read.data = { list:
"mine"
, tab:
"RejectedVouchers"
};
$(
"#vPosted"
).data(
"kendoGrid"
).dataSource.transport.options.read.data = { list:
"mine"
, tab:
"PostedVouchers"
};
$(
"#vAll"
).data(
"kendoGrid"
).dataSource.transport.options.read.data = { list:
"mine"
, tab:
"AllVouchers"
};
$(
"#vDrafts"
).data(
"kendoGrid"
).dataSource.read();
Do you need more information? A former co-worker created it about 2 years ago, and we haven't changed the code since, so there might be other details that you would need...
Is there something that has to be done differently after SP1?
25 Answers, 1 is accepted
Please accept my apologies for the delayed response.
Also, I'm not quite sure if we ever recommended setting the request data in this manner.
It might work, but a more robust approach is to set up a data function that executes before each request.
Is the data source shared by reference between the Grids? For example:
var myDataSource = new kendo.data.DataSource({ ... });
$("#vDrafts").kendoGrid({
dataSource: myDataSource
...
});
$("#vPending").kendoGrid({
dataSource: myDataSource
...
});
If this is the case then all grids should refresh, but they'll also display the same data. So this is unlikely.
If they share the configuration of the data source then you need to call read on each dataSource instance:
$("#vDrafts").data("kendoGrid").dataSource.read();
I hope this helps.
Regards,
T. Tsonev
Telerik
Well we have one setup for all the grids, so it might effectively be that..
$(
".vGrid"
).kendoGrid({
autoBind:
false
,
pageable: {
pageSizes: [10, 25, 50, 100]
},
dataSource: {
pageSize: 10,
serverFiltering:
true
,
serverPaging:
true
,
serverSorting:
true
,
type:
"json"
,
transport: {
parameterMap:
function
(options) {
return
{
filter: _public.convertFilter(options.filter),
page: options.page,
pageSize: options.pageSize,
sort: _public.convertSort(options.sort),
list: options.list,
tab: options.tab
}
},
read: {
url:
"vouchers.ashx"
,
contentType:
"application/json; charset=utf-8"
,
type:
"GET"
,
dataType:
"json"
}
},
schema: {
data:
"results"
,
total:
"total"
,
model: {
fields: {
DateApproved: { type:
"date"
},
DatePosted: { type:
"date"
},
DateRequested: { type:
"date"
},
InvoiceDate: { type:
"date"
},
TotalAmount: { type:
"number"
}
}
}
}
},
We usually reference the examples though as a base, so that style probably was in some example 2+ years ago when we started using the Grid that way.
Why would that suddenly break in a service pack? I could see a Q release having an issue, but I thought those were mostly just fixes... I didn't see anything about it in the release notes either...
I'm trying to replicate this behavior on a small scale in the dojo, but without success.
Regardless of the chosen version, I can only get one of the grids to bind, presumably due to the autoBind: false setting.
In this scenario the Grid will not listen for changes in the data source and will not rebind on its own.
I hope this sheds some light on the issue.
Regards,
T. Tsonev
Telerik
Ok, I found the exact change from Q1 to Q1 SP1 that broke our code.
if
(!kendo.data.transports[options.type]) {
kendo.logToConsole(
'Unknown DataSource transport type \''
+ options.type +
'\'.\nVerify that registration scripts for this type are included after Kendo UI on the page.'
,
'warn'
);
}
else
if
(!isPlainObject(kendo.data.transports[options.type])) {
//if (kendo.data.transports[options.type] && !isPlainObject(kendo.data.transports[options.type])) {
Thanks for taking the time to investigate. I don't think you should specify type on the dataSource in this case at all.
Let me know if that helps.
Regards,
T. Tsonev
Telerik
Sorry, I didn't get your message either.
Have you tried debugging the code with the type removed? It shouldn't get into that branch at all in this case.
Perhaps the change that lead to this issue is in another spot.
Regards,
T. Tsonev
Telerik
I didn't reply to the post that only came through email. I thought it had been deleted and was waiting for another until the reply that you replied to.
As I stated in that reply, I DID try it without the type, and I had the same exact issue...
I'll try to verify that AGAIN today, but I can't spend too much time debugging Telerik's controls...
If your service is ODATA, then by all means use this type.
We investigated how the history of the code in question and indeed the old version behaved slightly differently.
It doesn't seem to affect the normal use cases and I think this is the first report we've got so far.
We'll see if we can safely revert it without causing any additional breakage. Apologies for the caused inconvenience.
Regards,
T. Tsonev
Telerik
Hello,
The code depends on a side effect that the transport options are cloned in this specific scenario. To resolve the problem:
- Remove the type of the datasource. No need to specify 'json' or a different type.
- Either use the documented approach for passing data to remote end-points via the data function (recommended), or initialize the grids via $.fn.each: instead of $(".vGrid").kendoGrid() use $(".vGrid").each(function() { $(this).kendoGrid() });
I understand that you are frustrated about this seemingly working code breaking between service pack releases, but the approach that is used is not documented, nor supported -- thus was prone to break.
Regards,Alex Gyoshev
Telerik
Alex,
Did you not read through the whole thread? Removing the type does not fix the issue... If I specify "odata" for the type, it works fine. Also, the other support person said it was being switched back. I was just trying to figure out which release that was happening because I don't really have much more time I can spend on checking if a new release fixes it.
I'm sure that our approach was part of an example, at one point (although probably 2+ years ago because that is how old our code is) because we base basically all our use of Telerik controls on some example, so we can reference back to it if there are any issues. I read through every change log to look for potential changes that I would need to address, and the changes from the way we are using it, had not been documented.
Mike
Hello Mike,
Yes, I read through the whole thread. Please read the second point in my post and apply one of the suggested solutions to resolve the problem. This is unsupported functionality, and there has not been any mention of type: "json" in the docs, nor in our tests. It is a hack. Hacks break during upgrades. If you do not want broken code during upgrades, do not use hacks. Use the documented approach.
Regards,Alex Gyoshev
Telerik
Alex,
We did do that..over 2 years ago, when that code was first written...
We've been using Telerik controls for about 10 years, and since you were acquired, the quality has really been dropping. This is about the third time that an undocumented change has broke something, since then. Right now, I'm basically the only developer that handles most of the custom internal web applications that were written be me or a former coworker over about 10 years, for a nonprofit with about 2000 employees. I REALLY need controls that I can rely on being the same between releases because I don't have time to test your code too.
Our code was not a hack, it was in at least one example, from the time we wrote it because that is how we use your controls. We can't help it if you change those examples and don't document breaking changes...
Mike
Hello Mike,
I am sorry that we have frustrated you. I understand that this has been a breaking change for your project, and this is especially annoying when it happens between minor releases.
To shed some light on the introduced change, we have updated the code in order to help users of the framework debug problematic behavior when using custom transports that are not registered. If we don't trigger the warning, this results in cryptic runtime errors, which are very hard to debug.
The change itself prevents the transport objects to be cloned when an erroneous datasource type is specified. We have never supported a type: "json" DataSource -- it does not make sense, as the datasource itself is based on JS objects. None of our tests are testing against this, and we have had no other reports of broken functionality apart from this thread. Since we are not supporting this scenario, we are not bringing the code back.
Please use one of the provided workarounds. Wrapping the grid initialization in an each method call will immediately resolve the problem, as this will provide new objects to the grid configurations:
$(".vGrid").each(function() {
$(this).kendoGrid();
});
For a future refactoring, consider using a data function to provide the request data.
Regards,Alex Gyoshev
Telerik
Alex,
So breaking code was chosen over having people just learn how to set break points and debug code..?
I doubt they had to go through any more than I had to go through to figure out what caused our code to break..
Mike
Alex,
Do you have have an example of what you mean by "using a data function"?
Mike
Hello Mike,
After reviewing the example, the data can be determined upon initialization, so there is even no need to pass it via a function. See this Dojo snippet that illustrates how to make different requests based on the selected tab. This has the added benefit that the grids are initialized on demand, rather than slowing down the initial page load. The alternative is to loop through all grids and set the data statically -- this will initialize them all.
Regards,Alex Gyoshev
Telerik
Alex,
Right now we don't appear to be loading the data until the tab is clicked. When tab is selected this gets run to load the data.
RefreshData:
function
(grid, currentTab) {
if
(currentTab.indexOf(
'va'
) == 0)
_settings.currentTabApprovals = currentTab;
else
_settings.currentTabMine = currentTab;
grid.dataSource.read();
}
We also call that if we need to reload the existing grid. That page opens up new tabs. When one of the generated tabs is closed, the last tab is opened and the data is refreshed if that tab controls a grid.
It seems to work fine with looping through all of them. Thanks!
Mike