Select2 Grouped Static Data With AJAX Search Fallback

GIST =>  Select2 Grouped Static Data With AJAX Fallback

I have a database table named Locations which contains hierarchical data which again grouped by a title. To take the confusion off, here's the sample JSON returned from my API.

{
"results":[
{
"text":"Country",
"children":[
{
"id":11082,
"text":"SRI LANKA (LK)"
},
{
"id":10627,
"text":"MAURITIUS (MU)"
}
]
},
{
"text":"Airport",
"children":[
{
"id":17269,
"text":"Katunayake Airport"
}
]
},
{
"text":"City",
"children":[
{
"id":25845,
"text":"Kandy"
},
{
"id":25829,
"text":"Galle"
}
]
}
]
}

As you can see, I have Cities, Airports, Countries, Provinces etc. In each JSON object, "text" is the group name, children are well, the children of that group.

My Locations table has thousands of rows so I need to auto-fill these grouped data on the fly from my API. I am using the awesome Select2 library, which has everything I need to search, format and display these data.

But, I have another requirement, which is,

I have another table called something like PreferredLocations which contains some of these locations which I would search most of the time. I need to display these data (<20 records) when I open select2 dropdown before searching anything.

Using default options and operations, you can either set static data or use ajax to query the API. I want to do the both. all we have to do is create a custom "QUERY" function in select2 initialization.

This is the code, commented.


var initLocationLookup = function (element, apiUrl, dataItems, opt) {
opt = opt || {};
// retrieve these from initial ajax query or somewhere
var dt = { results: [{
"text":"Country",
"children":[
{
"id":11082,
"text":"SRI LANKA (LK)"
},
{
"id":10627,
"text":"MAURITIUS (MU)"
}
]
}]};
$(element).select2({
minimumInputLength: 0, // important!!! => without setting to 0 the default data will not be shown
ajax: {
// Select2's ajax helper
url: apiUrl,
dataType: 'json',
data: function (term, page) {
return {
q: term, // search term
page_limit: 10
};
},
results: function (data, page) {
// data from server is something like
// {"Locations":[{"text":"Country","children":[{"id":11107,"text":"UNITED KINGDOM (GB)"}]}]}
return { results: data.Locations };
}
},
initSelection: function (element, callback) {
// if there's an initial value set in the input control, use it to query the data
var id = element.val();
if (id) {
$.ajax({
url: apiUrl + "?q=" + id
}).done(function (data) {
// data from server is something like
// {"Locations":[{"text":"Country","children":[{"id":11107,"text":"UNITED KINGDOM (GB)"}]}]}
if (data.Locations && data.Locations.length > 0 && data.Locations[0].children && data.Locations[0].children.length > 0) {
callback(data.Locations[0].children[0]);
}
});
}
},
multiple: false,
query: function (query) {
// here we check whether the user has entered some search term
// and enforce a min term length to 2 chars
if (query.term && query.term.length > 2)
$.ajax({
url: apiUrl + "?q=" + query.term
}).done(function (data) {
// data from server is something like
// {"Locations":[{"text":"Country","children":[{"id":11107,"text":"UNITED KINGDOM (GB)"}]}]}
if (data.Locations && data.Locations.length > 0) {
query.callback({ results: data.Locations });
}
});
else
query.callback(dt); // no search term, display default data
}
});
};

And the output,



Happy coding!


Popular posts from this blog

Print a receipt using a Thermal Printer with C#.NET

Automatic redirect upon session timeout using ASP.NET MVC and Javascript

Complex Master-Detail Form using Knockout.js and ASP.NET MVC