This is a migrated thread and some comments may be shown as answers.

Dynamic ListViews/Datasources

3 Answers 371 Views
ListView
This is a migrated thread and some comments may be shown as answers.
Brian
Top achievements
Rank 1
Brian asked on 03 Jun 2016, 07:52 PM

I am using Kendo UI 2016.1.226, Windows 7 Enterprise SP 1, Google Chrome 51.0.2704.79 m, SQL Server 2012

I created a ListView for available report filters (Filter List), which loads from a stored procedure and uses the HTML ListView wrapper.  On Filter List databound, I am dynamically creating 2 more listviews (Available items and Selected items) for each item in the primary ListView.  When an item is selected from the primary, if no items are currently in the available list, the datasource is read from a stored procedure, passing the report filter ID, and returns a list of KeyIndex (int) and Value (string) items from various DB tables.  These are supposed to be loaded in the Available ListView's databound event.  However, there are no items in the datasource after return from the stored procedure call.

 

I suspect the issue is a JSON vs. OData format issue (see 12/5/2011 post here: http://www.telerik.com/forums/connect-grid-to-mvc-controller-method).  I don't care about grouping, filtering, and sorting of the items, but it seems like I may need to send a request object to the controller in order to call ToDataSourceResult, which I'm guessing converts JSON to OData format.  The Available datasource has AutoBind set to false, so that I can load only the report filters as needed.  When I try to pass information in the request, I get the following error because there is no data to group, filter, or sort yet:

    jquery.min.js:3 Uncaught TypeError: Cannot read property 'length' of undefined

 

                var availableDataSource = listViewAvailable.dataSource;
                var parameterMap = availableDataSource.transport.parameterMap;
                var request = parameterMap({ filter: availableDataSource.filter(), group: availableDataSource.group(), sort: availableDataSource.sort() });
                availableDataSource.transport.options.read.url = 
                    "/ReportCategory/GetFilterValues?FilterID=" + dataItem.ReportFilterID + "&TplNum=" + @ViewBag.TplNum + "&request=" + request;
                availableDataSource.read();

If I leave the parameterMap empty, my controller routine is called, the JSON data is populated and returned to the client, but the number of items in the datasource is 0:

               var request = parameterMap({  });

 

        public async Task<ActionResult> GetFilterValues([DataSourceRequest]DataSourceRequest request, int FilterID = 0, int TplNum = 0)
        {
            var url = string.Format("{0}{1}/{2}", GlobalVariables.ApiBaseUrl.Replace("api", "GetFilterValues"), FilterID, TplNum);

            var jsonResult = await Request.GetSerializedJsonResult<FilterValues>(url);
            IList listFilterValues = (IList)jsonResult;

            return Json(listFilterValues.ToDataSourceResult(request),JsonRequestBehavior.AllowGet);
        }

Datasource definition:

                    filterDataSource = new kendo.data.DataSource({
                        type: "odata",
                        transport: {
                            read: {
                                url: "/api/GetFilterValues/" + filterRecord.ReportFilterID + '/' + @ViewBag.TplNum,
                                type: "GET",
                                dataType: "json"
                            },
                        },
                        schema: {
                            model: {
                                fields: {
                                    KeyIndex: { type: "number" },
                                    Value: { type: "string" }
                                }
                            },
                            data: function(data) { return data.value; },
                            total: function(data) { return data["odata.count"]; }
                        },
                        serverFiltering: true,
                        serverGrouping: true,
                        serverSorting: true
                    });

Available ListView:

            idString = "Filters_1_" + filterIndex;
            divString = '<div id="' + idString + '" class="filterlist1" style="display: none;"><h2>Available Values</h2></div>';
            divStringInner = '<div class="filterlist1_inner"></div>';
            $(divString).insertAfter('#ReportFilters');
            $(divStringInner).insertAfter('#' + idString + ' h2').kendoListView({
                dataSource: filterDataSource,
                dataBound: onAvailableDataBound,
                autoBind: false,
                pageable: false,
                selectable: selectableType,
                template: kendo.template($('#' + templateName).html())
            });

ListView item template (TBD being eventually replaced by the Value string in the datasource):

<script type="text/x-kendo-tmpl" id="options">
<div class="filter2">
    <h3 value='0'>TBD</h3>
</div>
</script>

 

I saw something for SQL Server called FOR JSON AUTO that may help make the stored procedure OData compliant (https://msdn.microsoft.com/en-us/library/dn921897.aspx), but that is for SQL Server 2016 on.  Any ideas?

3 Answers, 1 is accepted

Sort by
0
Accepted
Boyan Dimitrov
Telerik team
answered on 07 Jun 2016, 04:58 PM

Hello Brian,

The ToDataSourceResult method stores the data items in "Data" field of the response (it is one of the things which ToDataSourceResult actually does) . It does not convert the JSON to OData format. This is why the setting type: "odata" will not work as expected in your case. When type is set to "odata" the DataSource will try to read the data items from specific field (since it expects the response to be in OData format). 

My suggestion is to remove the type: "odata" from the DataSource configuration settings and use the following: 

   - schema.data - the field of the server response which contains the data items. 

    - schema.errors - the field from the server response which contains the errors (if any). 

    - schema.total - the field from the server response which contains the total number of data items. 

 

Please refer to the attached project that shows how to configure the Kendo UI DataSource to read the data from the response when ToDataSourceResult method is used in the action method on the server.

Regards,
Boyan Dimitrov
Telerik
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Brian
Top achievements
Rank 1
answered on 08 Jun 2016, 12:43 PM

The combination of using type: 'aspnetmvc-ajax' in my datasource and using the empty parameter map to send a DataSourceRequest worked.  I'm not sure why I have to send a request object rather than just invoke a URL that returns JSON, but that's the only way I could get it to work.

Also, I was able to use the following syntax in my template to auto populate the results:

<script type="text/x-kendo-tmpl" id="options">
<div class="filter2">
    <h3 value=#:KeyIndex#>#:Value#</h3>
</div>
</script>

I thought maybe this was Razor code and had to be rendered before the HTML was downloaded to the client.

0
Brian
Top achievements
Rank 1
answered on 09 Jun 2016, 06:08 PM

It turns out that ToDataSourceResult does not have to be used and a request object does not have to be passed to the controller.  I modified my data and total in the schema section and it's working.

 

                    filterDataSource = new kendo.data.DataSource({
                        type: 'aspnetmvc-ajax',
                        transport: {
                            read: {
                                url: function(filterID, tplNum){
                                    var url = "/api/GetFilterValues/" + filterID + '/' + tplNum;
                                    return url;
                                },
                                type: "GET",
                                dataType: "json"
                            },
                        },
                        schema: {
                            data: function (data) { return data; },
                            total: function (data) { return data.length; },
                            model: {
                                fields: {
                                    KeyIndex: { type: "number" },
                                    Value: { type: "string" }
                                }
                            },
                        },
                        serverFiltering: true,
                        serverGrouping: true,
                        serverSorting: true
                    });

Tags
ListView
Asked by
Brian
Top achievements
Rank 1
Answers by
Boyan Dimitrov
Telerik team
Brian
Top achievements
Rank 1
Share this question
or