Multiselect dropdown search is very slow with large data - javascript

Hi i am using multiselect dropdown, using select2 jquery 4.0.3
i am getting data using Viewbag and loading around 9000 data in viewbag below is the dropdown
#Html.DropDownListFor(m => m.Tags, ViewBag.tags1 as IEnumerable<SelectListItem> , "----Select tags----", new { #class = "Tags form-control", multiple = "multiple", #id = "Tags" })
<script>
$(document).ready(function () {
$("#Tags").select2({
placeholder: "Select Tags",
minimumInputLength: 3,
tags: true
})
});
</script>
ViewBag.tags1 contains my data , now my page load perfectly but while searching (type required data in dropdown search box) dropdown reacts very very slow.
It feels like system has got hanged, any action in that search box is very slow.
Any solution for this?
Need help.

Loading 9000 items and inserting it to DOM is a bad idea.
Please see the code below, it will be easy to implement. This will allow you to load the data by page.
You need to create an endpoint that returns JSON.
$(".js-data-example-ajax").select2({
ajax: {
url: "https://api.github.com/search/repositories",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
// parse the results into the format expected by Select2
// since we are using custom formatting functions we do not need to
// alter the remote JSON data, except to indicate that infinite
// scrolling can be used
params.page = params.page || 1;
return {
results: data.items,
pagination: {
more: (params.page * 30) < data.total_count
}
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; }, // let our custom formatter work
minimumInputLength: 1,
templateResult: formatRepo, // omitted for brevity, see the source of this page
templateSelection: formatRepoSelection // omitted for brevity, see the source of this page
});

Related

Select2 - Multi Select Autocompletion - Programmatically population of field

I am using the bundled AUI Select2 Lib in a JIRA 8.13 instance.
What I would like to try is to code an autocompletion field with multiple values. My main components are running so far, but I have some problems while populating the field programmatically via JavaScript.
This my basic setup:
field.auiSelect2(
{
multiple: true,
closeOnSelect: true,
tokenSeparators: [","],
placeholder: PLACEHOLDER,
minimumInputLength: 2,
formatResult: format,
initSelection: function (element, callback) {
callback({id: $(element).val(), text: $(element).val()});
},
ajax: {
url: <...>,
dataType: 'json',
data: function (term) {
return {term: term,};
},
results: function (results) {
return results;
},
quietMillis: 250,
cache: false
},
});
The field population code is the following:
field.val(["A","B","C"]).trigger('change');
But this results in a single entry in the input field value "A,B,C" which is wrapped within a single gray box instead of multiple boxes - one for each passed value.
Any ideas on how to solve this issue? I guess it might be related to the initSelection parameter.
https://codepen.io/aschuma/pen/rNLRLWL
$(field).auiSelect2("data", [{id: "A", text: "A"},{id:"B", text: "B"},{id:"C", text: "C"}]);
https://codepen.io/aschuma/pen/ExyMNJP
This error is because you are using an <input> element instead of a <select> element. When you call this:
field.val(["A","B","C"]).trigger('change');
what you are really doing is setting the value of the <input> field which operates completely separately from select2. An <input> field can only have a single value, so it is likely that jQuery simply calls a standard .join() on the array and then sets the value to that. You can verify this is correct by simply opening a console and running:
console.log(["A","B","C"].join())
which will result in the string "A,B,C". What you might need is a <select> element which can support multiple values. Also note that the latest version of AUI Select2 (9.1.4) uses select2 version 3.4.5 instead of the latest version (4.0.13 as of the time of this post).
You could also set the data on the select2 instance itself like so:
$(field).auiSelect2('data', [
{id: 'A', text: 'A'},
{id: 'B', text: 'B'},
{id: 'C', text: 'C'},
]);
Found this thread because we had the same problem. I can confirm that it's also posible using elements if you use the following code.
AJS.$('#customfield_14882').auiSelect2(
{
multiple: true,
closeOnSelect: true,
tokenSeparators: [","],
placeholder: PlaceHolder,
minimumInputLength: 1,
allowClear:true,
initSelection: function (element, callback) {
var arr = $(element).val().split(',');
var res=[];
for(var i=0;i<arr.length;i++){
res[i]={id:arr[i],text:arr[i]};
}
callback(res);
},
ajax: {
url: "<url>",
dataType: 'json',
data: function (term) {
return {term: term};
},
results: function (results) {
return {results:results};
},
quietMillis: 250,
cache: false
},
});

Js Grid Pager does not load

Js Grid External Pager is not working.
I have tried working with Aspo.net Mvc, Back end is sql server
This is my Pager configuration
pageLoading: true,
paging: true,
pageSize: 15,
pageButtonCount: 5,
pagerContainer: "#externalPager",
//pagerFormat: "current page: {pageIndex} {first} {prev} {pages} {next} {last} total pages: {pageCount}",
pagePrevText: "<",
pageNextText: ">",
pageFirstText: "<<",
pageLastText: ">>",
pageNavigatorNextText: "…",
pageNavigatorPrevText: "…",
My controller returns
controller: {
loadData: function (filter) {
var d = $j.Deferred();
$j.ajax({
type: "POST",
url: '#Url.Action("LoadData", "User")',
data:filter,
dataType: "json",
success: function (response) {
var da = {
data: response.response,
itemsCount: response.response.length
}
d.resolve(da);
}
})
//.done(function (response) {
//console.log("response", response.response.length)
//var da = {
// data: response.response,
// itemsCount: response.response.length
//}
//console.log("da", da)
//d.resolve(da);
//});
return d.promise();
}
My Dom
<div id="grid"></div>
<div id="externalPager" class="external-pager"></div>
My Css
<style>
.external-pager {
margin: 10px 0;
}
.external-pager .jsgrid-pager-current-page {
background: #c4e2ff;
color: #fff;
}
</style>
The pager does not load. I am using the external pager. I have used exactly as same as the sample given. But the pager does not seem to load. Am I missing out on something. Any help is appreciated
Are you trying to lead at least one "full" page? If there isn't more than one page, you won't get a page. Also, if you don't return the total quantity of results, it also won't know to add a pager.
You have to return the data in the following format for the pager to work correctly with the data loading correctly.
{
data: [{your list here}],
itemsCount: {int}
}
It's barely in the documentation, as it's inline and not very obvious. (Bolding mine.)
loadData is a function returning an array of data or jQuery promise that will be resolved with an array of data (when pageLoading is true instead of object the structure { data: [items], itemsCount: [total items count] } should be returned). Accepts filter parameter including current filter options and paging parameters when
http://js-grid.com/docs/#controller
add new div with ID in my case I had used nbrdeclar it's will work
success: function (response) {
$("#nbrdeclar").text("Nombre de déclarations :"+response.length);
}

select2 - submit form with android search button

My site uses a select2 3.5.3 multiple select field with a search box. On mobile devices, the keyboard that pops ups when the search box is focused includes a search button. Currently, the search button does nothing (I assume it's behaving like the 'enter' key, which select2 uses to confirm a selection, but not submit).
I would like the mobile keyboard's search button to submit the users query if, and only if they have already made a selection. Is there a way to do this?
Here's the relevant select2 code:
function formatPerson(person) {
// select2: template for people results display
if (person.loading) return person.text;
if (person.known_for[0]) {
var known = person.known_for[0].title
} else {
var known = ""
}
var markup = '<div><object type="image/jpg" data="https://image.tmdb.org/t/p/w45' +
person.profile_path +
'"><img id="placeholder" src="/static/images/logo_placeholder.png"></object> <strong>' +
person.name +
"</strong> ( <em>" +
known +
"</em> )</div>";
return markup;
}
function formatPersonSelection(person) {
// select2: how the people results appear once selected
return person.name;
}
$('.people_query').select2({
// select2: ajax code for people search
ajax: {
url: "https://api.themoviedb.org/3/search/person?api_key=3b6e9eed30447d42a82fa925134de4ff&language=en-US",
dataType: 'json',
delay: 250,
data: function(params) {
return {
query: params.term, // search term
};
},
processResults: function(data, params) {
return {
// "data" is the object returned, "results" is the name of the array in the object
results: data.results,
};
},
cache: true
}, // ajax
escapeMarkup: function(markup) {
return markup;
}, // custom formatter from Select2
minimumInputLength: 3,
language: {
inputTooShort: function() {
return 'Search for a person...';
}
},
maximumSelectionLength: 2,
templateResult: formatPerson,
templateSelection: formatPersonSelection,
}); //select2 params

Select2 - Can't select a value?

Release version (Select 4.0.1)
HTML
<select id="search_customers" style="width: 300px;"></select>
Javascript:
$("#search_customers").select2({
multiple: false,
allowClear: true,
ajax: {
url: "#Url.Action("
SearchCustomers ", "
Home ")",
dataType: 'json',
delay: 250,
data: function(params) {
return {
id: params.term, // search term
};
},
processResults: function(data, params) {
return {
results: data
} // Data is a List<T> of id an text
},
}
});
The dropdown works, and I can see my records, however, when I click on one of the options the box closes, and the selected record isn't shown. My box looks like this
I've tried everything I can think of. The issue appears in all browsers. The data being return is a list of id/text pairs.
Controller code
var customers = this.service.SearchCustomers(id).Select(x => new { id = x.CustomerID, text = x.CustomerName }).ToList();
return Json(customers, JsonRequestBehavior.AllowGet);
My customer ID's had leading spaces for some reason. (Old ERP system), so adding a .Trim() call to the select statement on the customer ID fixed it. Apparently select2 doesn't like " 56", but "56" is fine!

Creating new tags in a Select2 tag textarea

I have an input (textarea) that has Select2's tags applied to it. So when a user types in the name of an item that exists in my data base, it shows a list of matching items and the user can select one and a tag is created.
Here is my code so far for basic tag functionality:
$('#usualSuppliers').select2({
placeholder: "Usual suppliers...",
minimumInputLength: 1,
multiple: true,
id: function(e) {
return e.id + ":" + e.name;
},
ajax: {
url: ROOT + 'Ajax',
dataType: 'json',
type: 'POST',
data: function(term, page) {
return {
call: 'Record->supplierHelper',
q: term,
page_limit: 10
};
},
results: function(data, page) {
return {
results: data.suppliers
};
}
},
formatResult: formatResult,
formatSelection: formatSelection,
initSelection: function(element, callback) {
var data = [];
$(element.val().split(",")).each(function(i) {
var item = this.split(':');
data.push({
id: item[0],
title: item[1]
});
});
//$(element).val('');
callback(data);
}
});
Is there a way for a new tag to be created if the text typed does not exist? Initially I thought this could some how be done by delimiting with spaces, but some items (supplier names) will have spaces in them, so that won't work.
I think when no matches are found the user needs to somehow "create" the tag by pressing a button that could appear in the drop down box, but I have no idea how to do this.
How can I allow users to create new tags that may have spaces in them and still be able to carry on adding more tags, existing or otherwise?
Yes you can do it. There is a example in the documentation. Look at http://ivaynberg.github.io/select2/#events
$("#e11_2").select2({
createSearchChoice: function(term, data) {
if ($(data).filter( function() { return this.text.localeCompare(term)===0;
}).length===0) {
return {id:term, text:term};
}
},
multiple: true,
data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});
You have to create a function like createSearchChoice, that returns a object with 'id' and 'text'. In other case, if you return undefined the option not will be created.

Categories