- Home
- Forum
- JavaScript - EJ 2
- Set delay search when typing and minimum character count?
Set delay search when typing and minimum character count?
Using a data manager with UrlAdaptor for searching a huge list of data that we have - but every time you type, no matter how fast it hits the server, this causes a significant amount of unneeded network traffic and queries on my database. I cannot seem to find a setting to have a delay, ie 200-300ms from when you stop typing for it to run the search, that way if I search for "something" - so long as I type it continuously - it will do one search with the full word vs right now it hits the server 9 times...
I was trying to override this with a custom adapter, since I have a "delay callback" pattern for this already in other keyword searching through my system - but was hoping to not have to tweak that...
SIGN IN To post a reply.
3 Replies
SP
Sureshkumar P
Syncfusion Team
November 1, 2019 09:39 AM UTC
Hi Nayt,
Greetings from Syncfusion support.
We have validated your requirement. we can able to restrict the search based on the given text length and timeout. Kindly refer the below code block.
|
[search string length]
// initialize the MultiSelect component
let listObj: MultiSelect = new MultiSelect({
// set placeholder to MultiSelect input element
placeholder: 'Select countries',
// set the countries data to dataSource property
dataSource: (data as any).countries,
// bind the Query instance to query property
query: new Query(),
// map the appropriate columns to fields property
fields: { text: 'Name', value: 'Code' },
// set true for enable the filtering support.
allowFiltering: true,
// bind the filtering event
filtering: (e: FilteringEventArgs) => {
e.preventDefaultAction = true;
let query: Query = new Query();
// frame the query based on search string length with filter type.
query = (e.text.length > 3) ? query.where('Name', 'startswith', e.text, true) : query;
// pass the filter data source, filter query to updateData method.
e.updateData((data as any).countries, query);
}
});
listObj.appendTo('#list');
[timeout]
// initialize the MultiSelect component
let listObj: MultiSelect = new MultiSelect({
// set placeholder to MultiSelect input element
placeholder: 'Select countries',
// set the countries data to dataSource property
dataSource: (data as any).countries,
// bind the Query instance to query property
query: new Query(),
// map the appropriate columns to fields property
fields: { text: 'Name', value: 'Code' },
// set true for enable the filtering support.
allowFiltering: true,
// bind the filtering event
filtering: (e: FilteringEventArgs) => {
e.preventDefaultAction = true;
let query: Query = new Query();
// frame the query based on search string with setTimeOut filter type.
query = (e.text !== "") ? query.where('Name', 'startswith', e.text, true) : query;
// pass the filter data source, filter query to updateData method.
setTimeout(function () {
e.updateData((data as any).countries, query);
}, 1000)
}
});
listObj.appendTo('#list');
|
We created a sample based on your requirement. please refer the sample here: https://stackblitz.com/edit/ro1bde-3s5app?file=index.ts
Regards,
Sureshkumar P
NG
Nayt Grochowski
November 1, 2019 05:23 PM UTC
One more question - since it does the search as soon as you click on the box and doesn't call "filtering" callback when the search field is empty - any way to have it not do a search at all until you start typing?
The "filtering" attribute is what I was missing though and this really helped - Just a quick note if anyone else asks about this - the way you set this up right now for delayed search, will still trigger the run for every keystroke, since set time, just delays the call.
Here is a tweak to the code that I put in place to wipe out the current "setTimeout" so that only the last one runs (FYI - I code everything in ES6...)
const dataManager = new ej.data.DataManager({
adaptor: new ej.data.UrlAdaptor(),
crossDomain: true,
headers: headers,
url: site_settings.api + `v1/poc/advanceSearch/filterSource/${_which}`,
});
let timeoutPointer = null;
const lookupSelector = new ej.dropdowns.MultiSelect({
dataSource: dataManager,
query: new ej.data.Query().addParams('filterSource', filterData.filterSource),
allowFiltering: true,
filtering: function (e) {
e.preventDefaultAction = true;
if (timeoutPointer) { clearTimeout(timeoutPointer); }
timeoutPointer = setTimeout(() => {
const query = new ej.data.Query()
.addParams('filterSource', filterData.filterSource)
.addParams('keyword', e.text)
;
e.updateData(dataManager, query);
}, 400);
},
fields: {
text: 'name',
value: 'code'
},
filterBarPlaceholder: 'Search',
filterType: 'Contains',
mode: 'CheckBox',
showClearButton: true,
showDropDownIcon: true,
showSelectAll: false,
});
lookupSelector.appendTo(`#filter-value-${groupIndex}-${rowIndex}`);
SP
Sureshkumar P
Syncfusion Team
November 4, 2019 10:09 AM UTC
Hi Nayt,
We have checked the reported requirement. We would like to inform you that, filtering event will be triggered when you start searching on the character. When you click on the input element, focus event will trigger. From the focus event we can get the multiselect value by using below code,
|
focus: function(args) {
console.log(this.value)
}
|
Also, in multi-select when you click on the input element then request will be sent to the server. If you want to send requests only when filtering, then we suggest disabling the openOnClick property.
|
openOnClick: false, |
Regards,
Sureshkumar P
SIGN IN To post a reply.
- 3 Replies
- 2 Participants
-
NG Nayt Grochowski
- Oct 31, 2019 08:17 PM UTC
- Nov 4, 2019 10:09 AM UTC