I'm not sure if i'm going about this the correct way, but if you have any constructive ment that can help lead me in the right direction please share. I've been stuck on this for quite some time.
I have the following select2 control that is loading the entire table for a field of that table. There is a function with select2 called minimumInputLength, which still seems to load the table in it's entirety instead of querying on the first three characters. The pagination works correctly as shown in this fiddle.js: /
$.fn.select2.amd.require(
['select2/data/array', 'select2/utils'],
function (ArrayData, Utils) {
function CustomData($element, options) {
CustomData.__super__.constructor.call(this, $element, options);
}
function contains(str1, str2) {
return new RegExp(str2, "i").test(str1);
}
Utils.Extend(CustomData, ArrayData);
CustomData.prototype.query = function (params, callback) {
if (!("page" in params)) {
params.page = 1;
}
var pageSize = 50;
var results = this.$element.children().map(function (i, elem) {
if (contains(elem.innerText, params.term)) {
return {
id: [elem.innerText, i].join(""),
text: elem.innerText
};
}
});
callback({
results: results.slice((params.page - 1) * pageSize, params.page * pageSize),
pagination: {
more: results.length >= params.page * pageSize
}
});
};
$(".js-example-basic-multiple").select2({
ajax: {},
minimumInputLength: 3,
allowClear: true,
width: "element",
dataAdapter: CustomData
});
});
The problem is my view is loading the entire table for active students on the rendering of the html.
def multisearch(request):
userid = ADMirror.objects.filter(student_status_id = 1).values('studentntname').values_list('studentntname', flat=True)
args = {'userid':userid}
return render(request, 'multisearch.html',args)
I render the html and select2 control with:
{% block extra_js %}
{{ block.super }}
{{ form.media }}
<script src=".2.1/jquery.js" type="text/javascript"></script>
<script src=".0.6-rc.0/js/select2.min.js"></script>
<link href=".0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src= "{% static '/search/user_select2.js' %}" type="text/javascript"></script>
<div class="col"><h4 style="margin-top: 0"><strong>Student ID Search</strong></h4><select class="js-example-basic-multiple" value = "{{ userid }}" style="width: 1110px" required>
{% for user in userid %}
<option value="{{ user }}"> {{ user }}</option>
{% endfor %}
</select>
Now I know how to prevent the loading of the data in my filter, which I do with the following, but how can I get this to work with my view and select2's minimum input length:
# doesn't load data on the initial load of the search.html page
def __init__(self, *args, **kwargs):
super(StudentFilter, self).__init__(*args, **kwargs)
# at startup user doen't push Submit button, and QueryDict (in data) is empty
if self.data == {}:
self.queryset = self.queryset.none()
I've also tried the following options with select2 and javascript unsuccessfully, because the data doesn't seem searchable :
$(document).ready(function () {
$('.js-example-basic-multiple').select2({
minimumInputLength: 3,
allowClear: true,
placeholder: {
id: -1,
text: 'Enter the Student id.',
},
ajax: {
type: 'POST',
url: '',
contentType: 'application/json; charset=utf-8',
async: false,
dataType: 'json',
data: function (params) {
return "{'searchFilter':'" + (params.term || '') + "','searchPage':'" + (params.page || 1) + "'}";
},
processResults: function (res, params) {
var jsonData = JSON.parse(res.d);
params.page = params.page || 1;
var data = { more: (jsonData[0] != undefined ? jsonData[0].MoreStatus : false), results: [] }, i;
for (i = 0; i < jsonData.length; i++) {
data.results.push({ id: jsonData[i].ID, text: jsonData[i].Value });
}
return {
results: data.results,
pagination: { more: data.more,
},
};
},
},
});
});
How can I get my data to not load until the minimum inputlength of select2 is met and still be searchable? I'm having to wait for the entire table to load before I can search and return results.
I'm not sure if i'm going about this the correct way, but if you have any constructive ment that can help lead me in the right direction please share. I've been stuck on this for quite some time.
I have the following select2 control that is loading the entire table for a field of that table. There is a function with select2 called minimumInputLength, which still seems to load the table in it's entirety instead of querying on the first three characters. The pagination works correctly as shown in this fiddle.js: http://jsfiddle/jgf5fkfL/66/
$.fn.select2.amd.require(
['select2/data/array', 'select2/utils'],
function (ArrayData, Utils) {
function CustomData($element, options) {
CustomData.__super__.constructor.call(this, $element, options);
}
function contains(str1, str2) {
return new RegExp(str2, "i").test(str1);
}
Utils.Extend(CustomData, ArrayData);
CustomData.prototype.query = function (params, callback) {
if (!("page" in params)) {
params.page = 1;
}
var pageSize = 50;
var results = this.$element.children().map(function (i, elem) {
if (contains(elem.innerText, params.term)) {
return {
id: [elem.innerText, i].join(""),
text: elem.innerText
};
}
});
callback({
results: results.slice((params.page - 1) * pageSize, params.page * pageSize),
pagination: {
more: results.length >= params.page * pageSize
}
});
};
$(".js-example-basic-multiple").select2({
ajax: {},
minimumInputLength: 3,
allowClear: true,
width: "element",
dataAdapter: CustomData
});
});
The problem is my view is loading the entire table for active students on the rendering of the html.
def multisearch(request):
userid = ADMirror.objects.filter(student_status_id = 1).values('studentntname').values_list('studentntname', flat=True)
args = {'userid':userid}
return render(request, 'multisearch.html',args)
I render the html and select2 control with:
{% block extra_js %}
{{ block.super }}
{{ form.media }}
<script src="https://ajax.googleapis./ajax/libs/jquery/3.2.1/jquery.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare./ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
<script src= "{% static '/search/user_select2.js' %}" type="text/javascript"></script>
<div class="col"><h4 style="margin-top: 0"><strong>Student ID Search</strong></h4><select class="js-example-basic-multiple" value = "{{ userid }}" style="width: 1110px" required>
{% for user in userid %}
<option value="{{ user }}"> {{ user }}</option>
{% endfor %}
</select>
Now I know how to prevent the loading of the data in my filter, which I do with the following, but how can I get this to work with my view and select2's minimum input length:
# doesn't load data on the initial load of the search.html page
def __init__(self, *args, **kwargs):
super(StudentFilter, self).__init__(*args, **kwargs)
# at startup user doen't push Submit button, and QueryDict (in data) is empty
if self.data == {}:
self.queryset = self.queryset.none()
I've also tried the following options with select2 and javascript unsuccessfully, because the data doesn't seem searchable :
$(document).ready(function () {
$('.js-example-basic-multiple').select2({
minimumInputLength: 3,
allowClear: true,
placeholder: {
id: -1,
text: 'Enter the Student id.',
},
ajax: {
type: 'POST',
url: '',
contentType: 'application/json; charset=utf-8',
async: false,
dataType: 'json',
data: function (params) {
return "{'searchFilter':'" + (params.term || '') + "','searchPage':'" + (params.page || 1) + "'}";
},
processResults: function (res, params) {
var jsonData = JSON.parse(res.d);
params.page = params.page || 1;
var data = { more: (jsonData[0] != undefined ? jsonData[0].MoreStatus : false), results: [] }, i;
for (i = 0; i < jsonData.length; i++) {
data.results.push({ id: jsonData[i].ID, text: jsonData[i].Value });
}
return {
results: data.results,
pagination: { more: data.more,
},
};
},
},
});
});
How can I get my data to not load until the minimum inputlength of select2 is met and still be searchable? I'm having to wait for the entire table to load before I can search and return results.
Share Improve this question edited Mar 28, 2018 at 14:39 user1470034 asked Mar 27, 2018 at 20:18 user1470034user1470034 7013 gold badges9 silver badges23 bronze badges3 Answers
Reset to default 4Certainly too late for a response. but in case it helps someone else. I got mine to work this way:
$("#select-pany").select2({
ajax: {
url: "/en/entreprises.json", //URL for searching panies
dataType: "json",
delay: 200,
data: function (params) {
return {
search: params.term, //params send to panies controller
};
},
processResults: function (data) {
return {
results: data
};
},
cache: true
},
placeholder: "Start typing",
minimumInputLength: 3,
});
$("#selctor").select2({
placeholder: ".................. choos ....................",
//dropdownCssClass: 'smalldrop',
width: '100%',
ajax: {
url: "/search RUL",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params,
// page: params.page
};
},
results: function (data, search) {
return {
results: data.items
};
},
cache: true
},
templateResult: function (item) {
if (item.loading) return item.text;
return item.text;
},
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 3,
});
I think that the minimumInputLength it only works if you haven't loaded your options (ajax load). In your code the select has the options loaded at the beginning so minimumInputLength will not work.
So if you populate all the options at the page load the minimumInputLength will no affect.
Hope the solution goes this way.