I got the dropdownlist example working and was easy.
Just can't figure out how to follow the same method with a Datasource with the grid.
I would like to do something like the following again like with the DropDown list
$(function () {
$.get("GetJsonData", "", function (data) {
for (var i = 0; i < data.length; i++) {
var itemNew = new Item();
itemNew.Id = data[i].Id;
itemNew.Name = data[i].Name;
viewModel.teams.push(itemNew);
}
ko.applyBindings(viewModel);
$("#selectItem").kendoDropDownList();
});
});
thanks.
25 Answers, 1 is accepted
You need to create a datasource using the data and bind the grid to it. Something like this:
$(
function
() {
$.get(
"GetJsonData"
,
""
,
function
(data) {
for
(
var
i = 0; i < data.length; i++) {
var
itemNew =
new
Item();
itemNew.Id = data[i].Id;
itemNew.Name = data[i].Name;
viewModel.teams.push(itemNew);
}
ko.applyBindings(viewModel);
var
dataSource =
new
kendo.data.DataSource( {
data: viewModel.teams
});
$(
"#grid"
).kendoGrid({ dataSource: dataSource });
$(
"#selectItem"
).kendoDropDownList();
});
});
Have in mind though that modifying the observable array won't currently refresh the grid. Regards,
Atanas Korchev
the Telerik team

If the grid won't get refreshed then there is no reason to use Knockoutjs in this scenario.
KnockoutJS integration is supported in one-way binding scenarios.
We are looking for ways to provide deeper integration with KO but we need some assistance from the authors. I have already posted a few questions in KO Google group and I hope to get things clear soon.
Regards,
Atanas Korchev
the Telerik team

This would allow you to do the following:
<table data-bind:"kendoGrid: { dataSource: Items, columns: ['Col1', 'Col2', 'Col3'], pagable: true, sortable: true, groupable: true }">
<thead>
<tr>
<td>Column 1</td>
<td>Column 2</td>
<td>Column 3</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
Where the ViewModel bound to this document has an observable array of Items property. The one thing that needs to work though is that the properties of the objects in the array Items are itself observable and need to work in the grid. Currently in your grid, if the properties you are binding to are an observable, it just prints out the function, and doesnt actually utilize it correctly. So, in essense, the grid is useless for Knockout in all but an extremely limited sense: An observable array of objects that has no observable properties.
Here is an example of what dataTables did using an custom binding: https://github.com/CogShift/Knockout.Extensions/tree/master/Demo
Here is an example of a custom binding from Steve himself with a paged grid:
http://knockoutjs.com/examples/grid.html
I only point this out so you can see how relatively easy it was to create (althouth its not full featured as I would hope Telerik would do) and a correct approach for integrating your controls with Knockout, instead of having to do all the extra things to make these two systems work together in a un-natural way, they would work together in a familiar way with how people actually use knockout.
I am not a fan of DataTables though, as it isnt as easy to use and is doing some funcky things to the array of items internally. I much rather use Telerik's Kendo Grid. It just doesnt work. If you could do something similar for each of your controls, not only would you be highly integrated plugins for Knockout, you wouldnt clutter your existing controls with knockout. It would allow you to make it really easy to use each of your controls with Knockout and use that as a selling point.
Not to mention you would make KendoUI a favorite at many web development offices :)
Thank you for sharing this information. For now this seems to be the only possible way to integrate Kendo UI and KO. Unfortunately it would require quite a bit of coding from our side. I really wish there were an easier way but that's life.
I will post an update to this thread once there is any progress.
Atanas Korchev
the Telerik team

Thank you for your reply.
I did a quick sample with the jQuery UI Autocomplete to help show you how simple it is to create a Knockout Custom Binding. It took me about 2 hours or so. Most of the time was spent trying to make the jQuery UI AUtocomplete act like your ComboBox with both a value / text (obviously it doesnt look nearly as good and probably not as performant).
http://jsfiddle.net/cjgaudin/HfNk9/
This is just an example and what I am doing until there are some knockout custom bindings for kendo UI. If I have time this weekend I will do the same for the kendoUI Autocomplete. Hopefully this helps you out and can show you that it doesnt take that long to create one.

jsFiddle: Autocomplete Custom Databind example
Thank you for sharing your efforts. I see that quite a lot of code is required to wire things up with KO and I can imagine even more code would be needed to wire a more complex widget such as the grid. I am also not sure how passing grid complex options should happen. The following looks too hairy and error-prone to me:
<div data-bind="kendoGridOptions: {
dataSource: tickets,
columns: [ {
field: 'foo',
template: '<strong>${foo}</strong>'
],
pageable: true,
sortable: true,
groupable:true
}"></div>
The ideal solution would be to somehow determine the observable to which a certain UI element is bound to and get notifications when something changes. Something like this:
Initialization:
kendoGrid({
dataSource: viewModel.products
});
Implementation:
if (data is KO observable) { // this seems impossible right now
data.subscribe(function() {
refresh();
});
}
Then the need to write KO extension for every single Kendo widget would no longer be needed - the integration will happen at datasource level.
Regards,
Atanas Korchev
the Telerik team

You could do the binding the following way, although not terribly different, you are not passing one all knowing object, you can pass in additional bindings that deal with your custom-bindings in:
<div data-bind="kendoGridOptions: source, pageable: true, sortable: true, columns : [{ field: 'foo' }]"></div>
I just think it would be cleaner than integrating knockout code in your main js code branch. Also did you take a look at the jquery plugin for datatables doing a custom knockout binding? They have less lines of code than I have. Please take a look at it here. They are essentially doing the exact thing below you say you need. Checking if the datasource is an observable, and subscribing to it to refresh the table. Also you can see there isnt much to the custom binding, it more checking and unwrapping the values from knockout.
if (ko && ko.isObservable(dataSource)) {
dataSource.subscribe(function() {
var grid = $(element).data("grid");
grid.refresh();
};
}
Unfortunately this seems to be the only option to properly integrate KO with a third-party UI widget. I wish there was an option to do this only one time at DataSource level but that's life - we need to create a custom binding for every single Kendo UI widget.
I cannot commit yet with a deadline because we have quite a lot on our plate now. Custom knockout binders were really not in our plans.
All the best,
the Telerik team

I am not meaning to beat a dead horse, and I understand your priority lists might not involve doing knockout custom bindings, but I would like to re-iterate how easy it is to create one.
Here is one I created in about 1.5 hours (took longer because I had no idea how your datasources worked) that utilize your Kendo ComboBox: (updated) Custom Kendo ComboBox Binding (jsFiddle)
As you can see it works well, binds the datasource to the kendo combobox, respects the observable array changes, ignores invalid changes, and sets the observable selected item back and forth.
I basically took my autocomplete version and changed it to work with ComboBox. Here is the dropdown knockout custom binding version.
Here is the Date Picker Custom Knockout Binding, this allows you to bind to a Date object in your viewModel without having to worry about converting to and from a string and respects the observable property from the ViewModel.
Thanks again for your continuous involvement. I see that it is relatively easy to implement simple binding to an observable array (once you know the KO internals such as _ko_property_writers). However how should ajax binding be handled? Or we should just ignore it completely.
There are other unclear things such as implementing grid editing with KO.The latter currently works with Kendo models only which means that a KO enabled version of the model needs to be created as well. Don't get me wrong - binding simple widgets is doable however supporting all Kendo UI features with KO is not as trivial.
Atanas Korchev
the Telerik team

Thank you for responding. You never get this kind of service from other places, so it is much appreciated. As you have pointed out the Grid is somewhat troublesome to make a custom binding. My problem currently is that the datasource does not have the necessary events I need to hook into changes and such. Also the datasource is constantly throwing errors because its internal '_set' is null when it shouldnt be.
I am adding a binding attribute called 'key' to be able to map when a model changes, I can map those changes back to the viewModel. Since the grid doesn't know how to show a observable object from knockout or a regular function (see next paragraph), I have to re-map the data array to a simple javascript array using a dependent observable. Because of this, I will have to manually change the viewmodel's array bound to the grid. However, I dont have the necessary events to accomplish this from what I can tell. If I had the necessary edited events from the datasource, I could remap that to the viewmodels array using the key property (to find that model in the array).
Side Note: If the kendo grid would treat column values that are simple functions i.e. if it sees a value of function type then it just executes it with no params, and it sets the value passing in the value to the function, then you could accomplish handling knockout observables, and other libraries without having to clutter your widget library with dependencies. This is just a suggestion.
Here is my start and far from finished, but at this point I need help to get the grid to respond as the internal datasource doest work right when trying to edit/delete, the paging does refresh correctly when you add items, and the grid looks off: Grid Custom Binding - Alpha 0
As for the ajax binding, I think it would be safe to ignore that feature. Since you are using knockout, you can get the datasource through your viewmodel and add to your observable array. Since the goal is to get the Kendo Grid to respect changes 2-way from the observable array, it would automatically respond to the changes or load of data. The goal of a viewModel is to do all of the work and contain all of the logic in pulling that data, the Grid itself should not concern itself with the details of where it is getting its data. Again, this is from a MVVM pattern perspective, so from that respect, I dont think worrying about incorporating in the need for the grid to get the data is necessary in this case.
In any case, I dont know what I am doing wrong with the kendo datasource. Any advice or suggestions?
DataSource editing requires a valid model to be defined. The errors about _set being undefined are most probably caused by this. I think a KO aware Kendo model should be invented in order to support properly the editing.
As for raising events during CRUD - the datasource does not do that at the time being. We are going to implement that in a future release for sure (probably even in the next release). Perhaps those events would eliminate the need for a KO - aware model.
I think that the best we can achieve now is to make the grid listen to observable array changes and rebind itself (what you have implemented right now). In order for the grid to update observable arrays we need to expose more DataSource events.
Atanas Korchev
the Telerik team

I'm afraid that we do not have such prototype currently available.
Greetings,Rosen
the Telerik team


We are currently working on our own Kendo MVVM. It would ship with the next major release of Kendo UI (March 2012). The key benefit is that we will provide built-in integration with the Kendo UI widgets and the datasource - a thing which is not that easy with a third party library such as KnockoutJS.
This means that deeper integration with KnockoutJS (and demos) will be provided after the Q1 2012 release. We will probably introduce a new type of datasource (pretty much as OData support is implemented) which knows about KnockoutJS observables and knows how to update them.
Atanas Korchev
the Telerik team

Yes, I confirm that the Kendo MVVM implementation would update only affected areas of the UI. Stay tuned for the beta version!
Atanas Korchev
the Telerik team


Enabling integration with Knockoutjs would be to implement significant UI design pattern, i.e. clear separation of the visualization of the data from it's source and two way data binding to enable changes in the source to be automatically reflected in the UI and changes in the UI reflected in the source with change tracking. Controls that just perform a one off or re-refresh style render are of no use for modern apps. Is Kendo going to write the same base library? If I was a component vendor in this space I would look into a framework of composition and templating out of your neat highly functional fundamental components and the use of your lib much much more powerful and this UI pattern may then be implemented in a provider agnostic way.

BTW it doesn't look like the kendoui mvvm framework is as complete as knockoutjs.
Kendo UI doesn't provide official support for KnockoutJS. There is however the knockout-kendo open source library which you can check. The following blog post might be helpful: http://www.kendoui.com/blogs/teamblog/posts/12-12-20/knockout_js_and_kendo_ui_-_a_potent_duo.aspx
Regards,
Atanas Korchev
Telerik