I need to bind a RadClientDataSource to a TelerikSearchBox, where the RadClientDataSource pulls data that I already have on the client-side. All the examples I can find try to pull data from a web service or REST API.
I haven't had luck getting a consistent approach that works for setting data and handling when the item is clicked.
I've been playing with trying to set the data in the OnRequestStart client event using code like:
function
QN_OnClientDataRequestingDS(sender, args) {
if
(args.get_type() ===
"read"
) {
//var searchText = sender.get_filterExpressions().getItem(0).get_value();
// Normally get this from another array already on the client-side, but stubbed this for the example
var
myData = [
{
'ID'
: 1,
'Text'
:
'Item 1'
},
{
'ID'
: 2,
'Text'
:
'Item 2'
},
];
var
dataSource = sender.get_dataSourceObject();
dataSource.transport.data = myData;
}
}
The OnRequestStart appears to be called multiple times however.
Also, then in the RadSearchBox OnClientSearch event, I'm trying to get the selected item when they click the dropdown list item, but it doesnt return anything but text:
function
QN_OnClientSearch(sender, args) {
var
item = args.get_dataItem(),
text = args.get_text(),
value = args.get_value();
if
(item) {
alert(text +
" "
+ value);
}
}
My server controls are defined like:
<
telerik:RadSearchBox
id
=
"SearchBox"
accesskey
=
"S"
runat
=
"server"
visible
=
"true"
EmptyMessage
=
"Search..."
ClientDataSourceID
=
"SearchDS"
DataTextField
=
"Text"
DataValueField
=
"ID"
OnClientSearch
=
"QN_OnClientSearch"
>
</
aec:TelerikSearchBox
>
<
telerik:RadClientDataSource
ID
=
"SearchDS"
runat
=
"server"
>
<
Schema
>
<
Model
ID
=
"ID"
>
<
Fields
>
<
telerik:ClientDataSourceModelField
FieldName
=
"ID"
DataType
=
"Number"
/>
<
telerik:ClientDataSourceModelField
FieldName
=
"Text"
DataType
=
"String"
/>
</
Fields
>
</
Model
>
</
Schema
>
<
ClientEvents
OnRequestStart
=
"QN_OnClientDataRequestingDS"
/>
</
telerik:RadClientDataSource
>
Thanks!
Mike
10 Answers, 1 is accepted
try..
var dataSource = sender.get_dataSourceObject();
dataSource = new Kendo.Data.DataSource({ data: myData});
i'll take that back...its not kendo
just try..
instead of dataSource.transport.data = myData;
dataSource.data = myData;
This causes errors because RadClientDataSource is expecting _kendoDataSource.data to be a function
SCRIPT5002: Function expected
Telerik.Web.UI.WebResource.axd (36477,9)
get_data: function (v) {
var w = this;
return w._kendoDataSource.data();
[Main Thread]
e.RadClientDataSource.prototype.get_data [Line: 36477, Col: 9], Telerik.Web.UI.WebResource.axd
c.RadSearchBox.prototype._doLoadOnDemandFromClientDataSource [Line: 27215, Col: 9], Telerik.Web.UI.WebResource.axd
c.RadSearchBox.prototype._query [Line: 27046, Col: 13], Telerik.Web.UI.WebResource.axd
c.RadSearchBox.prototype.query [Line: 27323, Col: 17], Telerik.Web.UI.WebResource.axd
Anonymous function [Line: 27039, Col: 13], Telerik.Web.UI.WebResource.axd
And if I try to do "dataSource.data = function () { return myData };" it doesn't error, but the dropdown doesn't open.
In order to set the data for the RadClientDataSource control you can use the set_data() method. Please examine the following code snippet that outline the approach:
<
telerik:RadScriptBlock
runat
=
"server"
ID
=
"RadCodeBlock1"
>
<
script
type
=
"text/javascript"
>
$telerik.$(document).ready(function () {
var items = [
{ "ProductID": 1, "ProductName": "Name 1" },
{ "ProductID": 2, "ProductName": "Name 2" },
{ "ProductID": 3, "ProductName": "Name 3" },
{ "ProductID": 4, "ProductName": "Name 4" },
{ "ProductID": 5, "ProductName": "Name 5" },
];
var dataSource = $find("<%= RadClientDataSource1.ClientID%>");
dataSource.set_data(items);
});
</
script
>
</
telerik:RadScriptBlock
>
<
telerik:RadClientDataSource
runat
=
"server"
ID
=
"RadClientDataSource1"
>
</
telerik:RadClientDataSource
>
<
telerik:RadSearchBox
RenderMode
=
"Lightweight"
ID
=
"RadSearchBox1"
runat
=
"server"
DataTextField
=
"ProductName"
DataValueField
=
"ProductID"
ClientDataSourceID
=
"RadClientDataSource1"
>
</
telerik:RadSearchBox
>
Regards,
Viktor Tachev
Telerik by Progress
Thank you for that code sample. My scenario is a little more complex in that I don't have static data.
When the user types in some data to search, I need to perform a dynamic search on the client-side and give the JSON to the client data source. I have tried to do this from RadSearchBox OnClientDataRequesting event (call dataSource.set_data in there) but it doesn't seem to render the dropdown items properly.
Currently I have code in RadClientDataSource.OnRequestStart (see QN_OnClientDataRequestingDS above) that can get the filter text from:
if
(args.get_type() ===
"read"
&& sender.get_filterExpressions().get_count() === 1) {
var
dataSource = sender.get_dataSourceObject(),
searchText = sender.get_filterExpressions().getItem(0).get_value();
However, that event seems to get called multiple times as it processes sort expressions, etc. So its a little clumsy.
I did figure out how to pass an object for the QN_OnClientSearch event and its args.get_dataItem() call by setting a property on the JSON data called DataItem. I had to dig into the source code for this, I never saw a documentation reference to it.
Mike
I would like to ask for the bigger picture of your requirement so I can understand it better. Please elaborate on the scenario you would like to implement in more detail.
What I understand from your posts is that the SearchBox would be bound to a RadClientDataSource control. When the user selects an option in the SearchBox that value should be used to populate another control. Am I correct? Please correct me if I am wrong.
If that is correct you can handle the client-side search event for RadSearchBox. In the event handler you can access the text and value for the item. Then you can use that information to populate the relevant control with data.
I guess that the second control will also be bound on the client via RadClientDataSource. In that case you can use the CustomParameter event of RadClientDataSource to pass the relevant information to the service. Please examine the resources below that describe the approach in more detail.
- http://docs.telerik.com/devtools/aspnet-ajax/controls/clientdatasource/client-side-programming/events/oncustomparameter
- http://demos.telerik.com/aspnet-ajax/grid/examples/data-binding/client-side/client-data-source-binding/defaultcs.aspx
Regards,
Viktor Tachev
Telerik by Progress
I am searching the current page (DOM) for certain elements matching text from the RadSearchBox to display in the dropdown. When they select an item from the list, I wanted to inspect the HTML element found and do more with it, so that's why I needed the DataItem property, not just the value/text.
I had also wanted to use the Search Context feature to give a list of areas on the page to narrow the search.
Mike
I am afraid that the behavior you describe is a custom functionality that would require manual implementation. If you would like to search through the DOM elements on the page you would need to populate the RadClientDataSource manually with data.
You can use the $(document).ready() event to iterate through all elements on the page and add them to the data source. This way you can populate the RadSearchBox control with data.
With that said, note that this is a custom behavior that is not available out of the box. Implementing it would depend on the developer working on the project.
Regards,
Viktor Tachev
Telerik by Progress
I understand the DOM searching and building up an array is custom development. I have all this taken care of.
What I wanted to know is what is the proper way to give the RadClientDataSource that array (it is pre-filtered and pre-sorted) so that when the user is typing into the RadSearchBox, it calls my search method with the search text. If the text changes, my search method needs to be called again. When I was experimenting, the OnRequestStart event would be fired multiple times forcing me to try to cache my results based on the search text, so I could skip searching again, but it is extra complexity when I just want to dynamically give it the array and make it happy.
In order to pass the custom JavaScript array to the ClientDataSource you should use the set_data() method.
<telerik:RadScriptBlock runat=
"server"
ID=
"RadCodeBlock1"
>
<script type=
"text/javascript"
>
$telerik.$(document).ready(
function
() {
var
dataSource = $find(
"<%= RadClientDataSource1.ClientID%>"
);
dataSource.set_data(myArrayWithData);
});
</script>
</telerik:RadScriptBlock>
If you would like more information on the client-side method available for RadClientDataSource please examine the article below.
If you would like to perform a specific action when the user searches something in the SearchBox you should use the OnClientSearch event.
Regards,
Viktor Tachev
Telerik by Progress