Hi,
I am trying to explore the below mentioned demo of multiselect with virtualization on my local machine, as per the demo i have created all the required html, script and web service.
It is showing me the result from the web service but when i try to select an item it is throwing the error. I have attached the error screenshot.
Can you please help me understand the issue.
Error Screenshot -
Hi Himanshu,
The error message you shared is thrown by our online demo or by the Web app you are working on?
If it is the online demo, can share the steps to replicate the issue?
Otherwise, I would need to see the implementation you have. Markup, Backend, related scripts. That will give me a better understanding of how the component is configured and I will be able to detect any conflicts.
I look forward to your reply.
The error is thrown by your online demo.
Steps: Scroll through the items in the multiselect and select any item. Nothing will happen. And if you check the console in your browser, you will see the same error messages posted by Himanshu.
Demo URL - https://demos.telerik.com/aspnet-ajax/multiselect/virtualization/defaultcs.aspx?_ga=2.211857303.2029322217.1647423137-1941866349.1635312360
Hi Hudson,
I hope you are doing well!
We are actively working on a fix for this issue and so far I have found a viable workaround that you can use until an official fix will be implemented in the next release. The fix is the following:
Sys.Application.add_init(function () { let kendo = window.$telerik._kendo; let VirtualList = kendo.ui.VirtualList; // keep a reference in case you need to call the original implementation let originalGetElementIndex = VirtualList.fn.getElementIndex; VirtualList.fn.getElementIndex = function (element) { if (!(element instanceof kendo.jQuery)) { return undefined; } return parseInt(element.attr('data-offset-index'), 10); }; });The full MultiSelect sample is as follows:
<telerik:RadMultiSelect runat="server" Filter="Contains" EnforceMinLength="false" AutoClose="false" DataTextField="ShipName" DataValueField="OrderID" Width="400px" ID="RadMultiSelect1" Placeholder="Shipping names..."> <VirtualSettings ItemHeight="26" ValueMapper="valueMapper" /> <ItemTemplate> <span class='order-id'>#= OrderID #</span> #= ShipName #, #= ShipCity # </ItemTemplate> <WebServiceClientDataSource EnableServerFiltering="true" AllowPaging="true" PageSize="80" EnableServerPaging="true"> <ClientEvents OnCustomParameter="OnCustomParameter" /> <WebServiceSettings ServiceType="Default"> <Select Url="WebService/VirtualizationWebService.asmx/GetOrders" RequestType="Post" DataType="JSON" ContentType="application/json; charset=utf-8" /> </WebServiceSettings> <Schema DataName="d.Data" TotalName="d.Count" ResponseType="JSON"> <Model> <telerik:ClientDataSourceModelField DataType="Number" FieldName="OrderID" /> <telerik:ClientDataSourceModelField DataType="Number" FieldName="Freight" /> <telerik:ClientDataSourceModelField DataType="String" FieldName="ShipName" /> <telerik:ClientDataSourceModelField DataType="Date" FieldName="OrderDate" /> <telerik:ClientDataSourceModelField DataType="String" FieldName="ShipCity" /> </Model> </Schema> </WebServiceClientDataSource> </telerik:RadMultiSelect>Sys.Application.add_init(function () { let kendo = window.$telerik._kendo; let VirtualList = kendo.ui.VirtualList; // keep a reference in case you need to call the original implementation let originalGetElementIndex = VirtualList.fn.getElementIndex; VirtualList.fn.getElementIndex = function (element) { if (!(element instanceof kendo.jQuery)) { return undefined; } return parseInt(element.attr('data-offset-index'), 10); }; }); function OnCustomParameter(sender, args) { args.set_parameterFormat(JSON.stringify({ customfilterstring: JSON.stringify(args.get_data()) })); } function valueMapper(options) { $.ajax({ url: '/WebService/VirtualizationWebService.asmx/ValueMapper', type: 'POST', dataType: 'json', contentType: 'application/json', data: JSON.stringify({ values: convertValues(options.value) }), success: function (data) { options.success(data.d); } }); } function convertValues(value) { let data = new Array(); value = $telerik.$.isArray(value) ? value : [value]; for (let idx = 0; idx < value.length; idx++) { data.push(value[idx]); } return data; }/// <summary> /// Summary description for VirtualizationWebService /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] [ScriptService] public class VirtualizationWebService : WebService { [WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public List<int> ValueMapper(List<int> values) { var indices = new List<int>(); if (values != null && values.Any()) { var listData = GetListData(GetData()); var index = 0; foreach (var order in listData) { if (values.Contains(order.OrderID)) { indices.Add(index); } index += 1; } } return indices; } [WebMethod] [ScriptMethod(ResponseFormat = ResponseFormat.Json)] public ResponseModel GetOrders(string customfilterstring) { var filterString = customfilterstring; var myFilter = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<ODataFilterObject>(filterString); var filteredData = GetListData(GetData()); if (myFilter.filter != null && myFilter.filter.filters.Any()) { var filter = myFilter.filter.filters[0]; var value = filter.value; var predicate = GetPredicate(filter.field, filter.value, filter.@operator, filter.ignoreCase); filteredData = filteredData.Where(predicate).ToList(); } var results = filteredData.OrderBy(x => x.OrderID).Skip(myFilter.skip).Take(myFilter.take).ToList(); return new ResponseModel(results, filteredData.Count); } #region Data Helper Methods private static DataTable GetData() { SqlDataAdapter adapter = new SqlDataAdapter("SELECT OrderID, OrderDate, Freight, ShipCity, ShipName from Orders Order by OrderID", ConfigurationManager.ConnectionStrings["NorthwindConnectionString"].ConnectionString); DataTable data = new DataTable(); adapter.Fill(data); return data; } private List<OrderModel> GetListData(DataTable data) { var result = new List<OrderModel>(); for (int i = 0; i < data.Rows.Count; i++) { var row = data.Rows[i]; result.Add(new OrderModel() { Freight = Convert.ToDouble(row["Freight"]), OrderDate = Convert.ToDateTime(row["OrderDate"]), OrderID = Convert.ToInt32(row["OrderID"]), ShipCity = row["ShipCity"].ToString(), ShipName = row["ShipName"].ToString() }); } return result; } #endregion #region Filtering Helper Methods public bool IsFilterSatisfied(string fieldValue, string filterValue, string operatorValue) { switch (operatorValue.ToLower()) { case "contains": return fieldValue.Contains(filterValue); case "startswith": return fieldValue.StartsWith(filterValue); case "endswith": return fieldValue.EndsWith(filterValue); case "eq": return fieldValue.Equals(filterValue); default: return false; } } private Func<OrderModel, bool> GetPredicate(string field, string filterValue, string operatorValue, bool caseSensitive) { filterValue = caseSensitive ? filterValue : filterValue.ToLower(); switch (field) { case "ShipName": return x => IsFilterSatisfied( caseSensitive ? x.ShipName : x.ShipName.ToLower(), filterValue, operatorValue); case "ShipCity": return x => IsFilterSatisfied( caseSensitive ? x.ShipCity : x.ShipCity.ToLower(), filterValue, operatorValue); default: return null; } } #endregion #region OData Filter Object public class ODataFilterObject { public int skip { get; set; } public int take { get; set; } public int page { get; set; } public int pageSize { get; set; } public FilterExpression filter { get; set; } } public class FilterExpression { public string logic { get; set; } public List<FilterData> filters { get; set; } } public class FilterData { public string value { get; set; } public string field { get; set; } public string @operator { get; set; } public bool ignoreCase { get; set; } } #endregion } #region Data Models public class OrderModel { public int OrderID { get; set; } public double Freight { get; set; } public string ShipName { get; set; } public DateTime OrderDate { get; set; } public string ShipCity { get; set; } } #endregion #region Response Models public class Result { public IQueryable<OrderModel> results { get; set; } public int __count { get; set; } } public class ResponseModel { public List<OrderModel> Data { get; set; } public int Count { get; set; } public string Errors { get; set; } public ResponseModel(List<OrderModel> data, int count) { this.Data = data; this.Count = count; } public ResponseModel(string errors) { this.Errors = errors; this.Data = new List<OrderModel>(); } public ResponseModel() { this.Data = new List<OrderModel>(); } } #endregionPlease test with this workaround in your project and let me know if it fixed the issue on your end.
Regards,
Vasko
Progress Telerik