- Home
- Forum
- ASP.NET MVC
- How to prevent loading of datasource before filter
How to prevent loading of datasource before filter
Hello
I have a DropDownList with a lots of items (> 10000). I'd like to use server filtering, but when I click on the drop down button, the list is populated with the full set of items.
My DropDownList is as follows:
@(Html.EJ().DropDownList("Product_Id")
.WatermarkText("Search for product")
.DropDownListFields(df => df.Value("Id").Text("Name"))
.Datasource(Model.GetProductsDataSource())
.EnableFilterSearch(true)
.EnableIncrementalSearch(false)
.EnableServerFiltering(true)
.LoadOnDemand(true)
)
I tried to prevent loading of a list in my controller action, like this:
public ActionResult ProductsDataSource(DataManager dataManager)
{
if (dataManager.Where == null || dataManager.Where.Count == 0)
{
return new JsonResult
{
Data = new object[0], // new[] { new { Id = "", Name= "" } },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
// perform database query
}
}
which works, but if I don't select any item in the drop down list, it stops working. Think works if I use the commented code, but in this case I have an empty item in the list.
So, is it possible to prevent calling the datasource if there's no search/filter string?
Thanks, Tom
I have a DropDownList with a lots of items (> 10000). I'd like to use server filtering, but when I click on the drop down button, the list is populated with the full set of items.
My DropDownList is as follows:
@(Html.EJ().DropDownList("Product_Id")
.WatermarkText("Search for product")
.DropDownListFields(df => df.Value("Id").Text("Name"))
.Datasource(Model.GetProductsDataSource())
.EnableFilterSearch(true)
.EnableIncrementalSearch(false)
.EnableServerFiltering(true)
.LoadOnDemand(true)
)
I tried to prevent loading of a list in my controller action, like this:
public ActionResult ProductsDataSource(DataManager dataManager)
{
if (dataManager.Where == null || dataManager.Where.Count == 0)
{
return new JsonResult
{
Data = new object[0], // new[] { new { Id = "", Name= "" } },
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
else
{
// perform database query
}
}
which works, but if I don't select any item in the drop down list, it stops working. Think works if I use the commented code, but in this case I have an empty item in the list.
So, is it possible to prevent calling the datasource if there's no search/filter string?
Thanks, Tom
SIGN IN To post a reply.
9 Replies
KR
Keerthana Rajendran
Syncfusion Team
April 12, 2018 04:04 PM UTC
Hi Tomislav,
We checked your query and prepared a sample based on our understanding. We suggest you to use itemsCount property of DropDownList along with allowVirtualScrolling set to true so that items will be loaded based on items count and the remaining items will be loaded only on scrolling. You can set itemsCount which has to be loaded during initial DropDownList click and server filtering will be done with the entire dataSource on search. Please refer to the below given code and UG
|
@Html.EJ().DropDownList("Products_id").Datasource(ds => ds.URL("http://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/")).Query("ej.Query().from('Customers').take(50)").DropDownListFields(f => f.Value("CustomerID").Text("CustomerID")).EnableServerFiltering(true).EnableFilterSearch(true).EnableIncrementalSearch(true).LoadOnDemand(true).AllowVirtualScrolling(true).ItemsCount(10) |
If we have misunderstand , kindly revert with clear details on your requirement so that we can proceed further.
Regards,
Keerthana.
TT
Tomislav Tustonic
April 12, 2018 07:20 PM UTC
Hello
I tried your suggestion, but it doesn't work. My DropDownList looks like:
@(Html.EJ().DropDownList("Product_Id")
.WatermarkText("Search for product")
.DropDownListFields(df => df.Value("Id").Text("Name"))
.EnableServerFiltering(true)
.EnableFilterSearch(true)
.EnableIncrementalSearch(false) // tried both true and false
.LoadOnDemand(true)
.AllowVirtualScrolling(true)
.ItemsCount(2)
)
@(Html.EJ().DropDownList("Product_Id")
.WatermarkText("Search for product")
.DropDownListFields(df => df.Value("Id").Text("Name"))
.EnableServerFiltering(true)
.EnableFilterSearch(true)
.EnableIncrementalSearch(false) // tried both true and false
.LoadOnDemand(true)
.AllowVirtualScrolling(true)
.ItemsCount(2)
)
When I click on the dropdown button, I receive first two items, but when I search, dropdownlist remains empty.
My initial request and response are:
Req:
{"select":["Name","Id"],"requiresCounts":true,"take":2}
{"select":["Name","Id"],"requiresCounts":true,"take":2}
Resp:
{"result":[{"Id":"00000000-0000-0000-0000-000000000020","Name":"EXCALIBUR"}, {"Id":"00000000-0000-0000-0000-000000000001","Name":"Product 01"}],"count":20}
{"result":[{"Id":"00000000-0000-0000-0000-000000000020","Name":"EXCALIBUR"}, {"Id":"00000000-0000-0000-0000-000000000001","Name":"Product 01"}],"count":20}
When I start typing the filter string, I receive multiple responses, like this:
Req:
{"take":2,"where":[{"isComplex":false,"field":"Name","operator":"contains","value":"Prod","ignoreCase":true,"anyCondition":""}]}
Resp:
{"result":[{"Id":"00000000-0000-0000-0000-000000000001","Naziv":"Product 01"},{"Id":"00000000-0000-0000-0000-000000000002","Naziv":"Product 02"}],"count":14}
{"take":2,"where":[{"isComplex":false,"field":"Name","operator":"contains","value":"Prod","ignoreCase":true,"anyCondition":""}]}
Resp:
{"result":[{"Id":"00000000-0000-0000-0000-000000000001","Naziv":"Product 01"},{"Id":"00000000-0000-0000-0000-000000000002","Naziv":"Product 02"}],"count":14}
which means that the server side works ok and the results are being returned to the client.
I also tried your exact code, calling Northwind demo service. Your query string returns 50 items to the dropdownlist, and then takes 10 from the returned set. When I remove take(50) from the query, then it correctly returns top 10.
However, after I receive initial set of 10 and start typing the filter string, I receive this error response:
However, after I receive initial set of 10 and start typing the filter string, I receive this error response:
{"error":{"code":"","message":{"lang":"en-US","value":"Query options $select, $expand, $filter, $orderby, $inlinecount, $skip, $skiptoken and $top are not supported by this request method or cannot be applied to the requested resource."}}}
It seems that the virtual scrolling is broken and only works if I don't filter anything.
Perhaps the problem is in the JSON response or something...
KR
Keerthana Rajendran
Syncfusion Team
April 13, 2018 11:29 AM UTC
Hi Tomislav,
Sorry for the inconvenience.
We couldn’t predict how data is bound to DropDownList since the dataSource property and controller code is missing in the provided code snippet. We have prepared a sample for your reference by modifying the previously given code. As your requirement, to load only two items, you can remove the query property and directly provide the exact Url and ItemsCount as shown below.
| @Html.EJ().DropDownList("Product").Datasource(ds => ds.URL("https://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/Customers")).DropDownListFields(f => f.Value("CustomerID").Text("CustomerID")).EnableServerFiltering(true).EnableFilterSearch(true).EnableIncrementalSearch(true).LoadOnDemand(true).AllowVirtualScrolling(true).ItemsCount(2) |
Two items will be loaded as shown below on initial click
During filter the matched items will be added to the list as shown below
Please download the sample from the following link.
Please add the Url for binding dataSource as done in the above sample and if issue persists, kindly modify the above sample else share us code snippet of both View and Controller page, so that we can proceed further.
Regards,
Keerthana.
TT
Tomislav Tustonic
April 14, 2018 05:37 PM UTC
Hello
Thanks for the response. I have tried your example, but it doesn't work. I have installed the following packages from the Syncfusion nuget source:
Attachment: ItemsCount1262146408__Copy_ae3fdc11.zip
Thanks for the response. I have tried your example, but it doesn't work. I have installed the following packages from the Syncfusion nuget source:
- Syncfusion.AspNet.Mvc5 - 16.1.0.32
- Syncfusion.JavaScript - 16.1.0.32
- Syncfusion.Web.Base45 - 16.1.0.32
- Syncfusion.Web.FileFormatsBase45- 16.1.0.32
Here are the screenshots:
Initially the list is empty:
After typing the filter string I get the error:
I have created a sample similar to what I'm using in my application. I tried with two different JSON outputs. Here are the screenshots:
The first output has the same result as your example, empty list and error:
The second JSON output initially gives the list with some results:
But filtering doesn't give any result:
Attachment: ItemsCount1262146408__Copy_ae3fdc11.zip
KR
Keerthana Rajendran
Syncfusion Team
April 16, 2018 01:04 PM UTC
Hi Tomislav,
Query: After typing the filter string I get the error:
You receive this error because search is done on empty DropDownList. Please bind the dataSource before performing search.
Query: But filtering doesn't give any result:
We have checked the provided sample and the issue occurs because of the list type result and count returned as shown below
Whereas in the previous sample, list is returned as shown in the below image.
So we suggest you to pass the JsonResult which returns the data as shown in the above format so that filtering will work fine in the sample.
Regards,
Keerthana.
TT
Tomislav Tustonic
April 16, 2018 03:02 PM UTC
Hello
I still can't make it work.
I think that the view for my second example needs a following modification:
.Datasource(ds => ds.URL("/DropDownList/CustomersDataSource2").Adaptor(AdaptorType.UrlAdaptor))
otherwise the DataManager parameter in the CustomersDataSource2 has no values the properties like search, take etc.
Would you, please, modify my example in a way that satisfies following requirements:
I still can't make it work.
I think that the view for my second example needs a following modification:
.Datasource(ds => ds.URL("/DropDownList/CustomersDataSource2").Adaptor(AdaptorType.UrlAdaptor))
otherwise the DataManager parameter in the CustomersDataSource2 has no values the properties like search, take etc.
Would you, please, modify my example in a way that satisfies following requirements:
- Initial loading of a datasource SHOULD NOT load all the data for the drop down list. Preferably, click on a dropdown arrow should not load any data, but from the examples it seems that it can't be done.
- Typing a filter string should load ONLY items that satisfy the filter.
- It SHOULD NOT raise an error in a case when there is no data which satisfy the filter.
Thanks,
Tom
KR
Keerthana Rajendran
Syncfusion Team
April 19, 2018 04:51 PM UTC
Hi Tomislav,
We have prepared a sample based on your requirement.
Query 1: Initial loading of a datasource SHOULD NOT load all the data for the drop down list. Preferably, click on a dropdown arrow should not load any data, but from the examples it seems that it can't be done.
Response: As we have processed the popupListItems in source during search , preventing data load and rendering empty popup on click will result in error during filter search. So, we request you to set a minimum itemsCount 1 or 2 to prevent loading of large data and remaining items will be filtered based on search in input box.
Query 2:Typing a filter string should load ONLY items that satisfy the filter
Response: We have overridden filter search method of DropDownList to filter items based on your return statement in controller. Please refer to the below given code
| <td> @(Html.EJ().DropDownList("Customers2") .Datasource(ds => ds.URL("/DropDownList/CustomersDataSource2").Adaptor("UrlAdaptor")) .DropDownListFields(f => f.Value("CustomerID").Text("CustomerID")) .EnableServerFiltering(true) .EnableFilterSearch(true) .EnableIncrementalSearch(true) .LoadOnDemand(true) .AllowVirtualScrolling(true).ItemsCount(3) ) </td> <script> ej.DropDownList.prototype._filterSearch = function (searchQuery, args) { var flag = false; this.resultList = args.result.result ? args.result.result : ej.DataManager(this._rawList).executeLocal(searchQuery); if (this.resultList.length == 0) { flag = true; this.resultList.push(this._getLocalizedLabels("emptyResultText")); } this.popupListItems = this.resultList; this.ultag.empty(); this._isPlainType(this.popupListItems) ? this._plainArrayTypeBinding(this.resultList) : this._objectArrayTypeBinding(this.resultList, "search"); if (flag && this.ultag.find("li").length == 1) { this.ultag.find("li").eq(0).addClass("e-nosuggestion"); } if (this.model.showCheckbox && !flag) { this._appendCheckbox(this._getLi()); } this._onSearch = true; var value = this.value(), visibleText = this._visibleInput[0].value; this._setValue(this.value()); var checkVal = typeof this.model.value === "function" ? this.model.value() : this.model.value; if (checkVal != value) { this.element[0].value = value; this._visibleInput[0].value = visibleText; this.model.text = visibleText == "" ? null : visibleText; if (this.value() != value && !(this.value() == null && value == "")) { this._updateValue(value); } } this._onSearch = false; this._updateSelectedIndexByValue(this.value()); this._refreshScroller(); this._setListPosition(); } </script> |
Query 3: It SHOULD NOT raise an error in a case when there is no data which satisfy the filter.
Response: In this case when no data matches , no suggestions text will be shown in popup. Please refer to the below image
We have attached the modified sample in the below link
Regards,
Keerthana.
TT
Tomislav Tustonic
April 19, 2018 09:14 PM UTC
Hello
Thanks for the sample. It almost works, but not completely.
When I set ItemsCount(1) for the dropdownlist, and start typing filter, I only get one result. Is it possible to get ALL the results satisfying filter?\
In the image below, it should return all customers which start or contains letter 'W'. Typing more letters should reduce the number of items in the dropdown list.

Thanks, Tom
Thanks for the sample. It almost works, but not completely.
When I set ItemsCount(1) for the dropdownlist, and start typing filter, I only get one result. Is it possible to get ALL the results satisfying filter?\
In the image below, it should return all customers which start or contains letter 'W'. Typing more letters should reduce the number of items in the dropdown list.
Thanks, Tom
KR
Keerthana Rajendran
Syncfusion Team
April 20, 2018 06:44 AM UTC
Hi Tomislav,
Query: When I set ItemsCount(1) for the dropdownlist, and start typing filter, I only get one result. Is it possible to get ALL the results satisfying filter?
Response: By default, itemsCount will considered during filtering data and data will be fetched based on this count. If you wish to load all the results satisfying the filter, you can modify the itemsCount to 0 in search event of DropDownList as shown below.
| <table> <tr> <td> @(Html.EJ().DropDownList("Customers2") .Datasource(ds => ds.URL("/DropDownList/CustomersDataSource2").Adaptor("UrlAdaptor")) .DropDownListFields(f => f.Value("CustomerID").Text("CustomerID")) .EnableServerFiltering(true) .EnableFilterSearch(true) .EnableIncrementalSearch(true) .LoadOnDemand(true) .AllowVirtualScrolling(true).ItemsCount(3).ClientSideEvents(e => e.Search("onSearch")) ) </td> </tr> </table> <script> function onSearch(args) { this.model.itemsCount = 0 } ej.DropDownList.prototype._filterSearch = function (searchQuery, args) { var flag = false; this.resultList = args.result.result ? args.result.result : ej.DataManager(this._rawList).executeLocal(searchQuery); if (this.resultList.length == 0) { flag = true; this.resultList.push(this._getLocalizedLabels("emptyResultText")); } ……………………………. } </script> |
Query: In the image below, it should return all customers which start or contains letter 'W'. Typing more letters should reduce the number of items in the dropdown list.
Response: Now on typing “w” all items will be loaded as shown below.
Typing more letters will reduce the number of items as shown below
Regards,
Keerthana.
SIGN IN To post a reply.
- 9 Replies
- 2 Participants
-
TT Tomislav Tustonic
- Apr 11, 2018 11:25 PM UTC
- Apr 20, 2018 06:44 AM UTC