Aria attributes not be added to results - javascript

I am using select 2 version 4.0.2 and have created a select to look up remote data via ajax.
I am getting the data ok but when the results are rendered, the aria-selected attribute is not being added and therefore I can not select any of the options.
I believe it may be to do with the templateResult and templateSelection but I don't know what needs to be changed.
Jquery:
$("#select2").select2({
theme: "bootstrap",
ajax: {
url: "/search/games",
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term, // search term
type: "suggest"
};
},
processResults: function (data, params) {
return {
results: data.games,
};
},
cache: true
},
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 3,
templateResult: formatResult,
templateSelection: formatSelection
});
function formatResult(game) {
markup = "<p>" + game.name + "</p>";
return markup;
};
function formatSelection(game) {
markup = "<p>" + game.name + "</p>";
return markup;
}
Form:
= form_for [:member,#event], :html => {:class => "formtastic form-horizontal"} do |f|
%fieldset
%div{:class => "control-group"}
= f.label :game_id, :class => "control-label"
%div{:class => "controls"}
= f.select :game_id, "", {}, :class => "form-control"

Turns out when processing the results, the data has to be mapped to an id and text attribute for it to be recognised:
processResults: function (data, params) {
return {
results: jQuery.map( data.games, function( game ) {
var arr = {id:game.name,text:game.name};
return arr;
}),
};
}

Related

select2 won't show me results after transforming data into the required format

I use ajax call to fetch data from server and display the results via select2. The problem is that the fetched data is structured in a way that needs to be transformed for select2 to process it correctly.
When I transform data following their documentation, it won't show me the results.
The structure of the response:
{
type1: [{result1}, {result2}, {result3}...],
type2: [{result1}, {result2}, {result3}...],
type3: [{result1}, {result2}, {result3}...]
}
Select2 expects data to be: {"results": [{result1}, {result2}, {result3}...]}
My code:
function formatParent(parent) {
return parent.title || parent.text
}
Ember.$('#parent-select').select2({
ajax: {
url: '/api/parents/' + type,
headers: headers,
dataType: 'json',
data: function (params) {
let query = {
q: params.term,
}
return query;
},
processResults: function (data) {
const res = []
for (let property in data) {
if (data.hasOwnProperty(property)) {
res.push({
"text": property,
"children": data[property]
})
}
}
return res
}
},
width: 'resolve',
theme: 'bootstrap',
escapeMarkup: function (markup) {
return markup;
},
minimumInputLength: 1,
templateResult: formatParent,
templateSelection: formatParent
})
<select
data-tags="true"
data-placeholder={{placeholder}}
id="parent-select"
style="width: 100%;">
</select>
When I transform the data as presented below the results appear in the dropdown without any problems:
function formatParent(parent) {
return parent.title || parent.text
}
Ember.$('#parent-select').select2({
ajax: {
url: '/api/parents/' + type,
headers: headers,
dataType: 'json',
data: function (params) {
let query = {
q: params.term,
}
return query;
},
processResults: function (data) {
return {"results": data.type1}
}
},
width: 'resolve',
theme: 'bootstrap',
escapeMarkup: function (markup) {
return markup;
},
minimumInputLength: 1,
templateResult: formatParent,
templateSelection: formatParent
})

Prevent loading of data with select2 until minlength is met

I'm not sure if i'm going about this the correct way, but if you have any constructive comment 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.net/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.com/ajax/libs/jquery/3.2.1/jquery.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<link href="https://cdnjs.cloudflare.com/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.
Certainly too late for a response. but in case it helps someone else. I got mine to work this way:
$("#select-company").select2({
ajax: {
url: "/en/entreprises.json", //URL for searching companies
dataType: "json",
delay: 200,
data: function (params) {
return {
search: params.term, //params send to companies 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.

.Val() set value, but not show into TextBox

So, i have a problem with a function un JS, how call a Ajax request :
function editDataAddress(idPartnerAddress) {
// simplified
var url = "#Url.Action("SelectAddressToEdit", "Partners", idPartnerAddress)"
$.ajax({
url: url,
dataType: 'json',
success: function (data) {
var adresse = data.Address;
var zip = data.Zip;
var locality = data.Locality;
var idLocalite = data.IdLocality;
//alert("locality : "+locality);
$("#ZipSwiss").empty()
$("#ZipSwiss").append($('<option></option>').val(idLocalite).html(zip));
$('#PartnerAdresse_Locality').val(locality)
// This line confirm i don't have another PartnerAdresse_Locality in my page
console.log('ID Test:', $('[id=PartnerAdresse_Locality]').length, $('[id=PartnerAdresse_Locality]').get())
}
});
}
<div class="col-md-4" id="divZipSwiss">
#Html.DropDownListFor(model => model.ZipSwiss, ViewBag.localiteList as IEnumerable<SelectListItem>, "Recherche...", new {#class = "form-control", style = "width : 100%;"})
</div>
<div class="col-md-5">
#Html.TextBoxFor(model => model.PartnerAdresse.Locality, new { #class = "form-control" })
</div>
The problem is, when i call the function, the ajax return all value, and put in the 4 first var (adresse, zip, locality, idlocalite) correctly
When i do the $('#PartnerAdresse_Locality').val(locality), the value is set in the HTML, but not show :
and the HTML :
<input class="form-control" id="PartnerAdresse_Locality" name="PartnerAdresse.Locality" type="text" value="Geneva">
The NPA (Zip) is okay, and the locality value is filled, but not showing
if now I comment $("#ZipSwiss").append($('<option</option>').val(idLocalite).html(zip));
the locality appears, but of course, no more the NPA (zip) because of the comment.
i'm really lost, somebody can help me?
Following my explanation, i founded the solution by comment some code line :
for my ZipSwiss, I Have a select2 DDL :
$('#ZipSwiss')
.select2({
language: lang,
minimumInputLength: 2,
minimumResultsForSearch: Infinity,
closeOnSelect: true,
ajax: {
url: '#Url.Action("SearchLocalite", "Partners")',
dataType: 'json',
delay: 200,
data: function(params) {
return {
searchTerm: params.term
};
},
processResults: function(data) {
return {
results: $.map(data, function(item) {
return {
id: item.IdLocalite,
text: item.ZipCode,
name: item.Name
}
})
}
},
cache: true
},
templateResult: function(item) {
if (item.loading)
return item.text;
return item.text + " | " + item.name;
},
templateSelection: function (item) {
$("#PartnerAdresse_Locality").val(item.name);
return item.text;
},
escapeMarkup: function(markup) {
return markup;
}
});
The line : $("#PartnerAdresse_Locality").val(item.name); is called ALWAYS when you update the selection. it's mean, the value is null.
Thanks ^^

Initialize multiple selections in select2

I'm developing a multiple selection in Select2 4.0 and Rails 4.2.7.1. The code saves the right value in the database, but I've noticed a problem: it loses all value selection after a failed validation.
How could i initialize all the value previously selected after a page reload? Thanks.
This is the current select2 declaration:
$(select_report).select2({
ajax: {
url: '/vaccination_plans/index_json',
dataType: 'json',
data: function (params) {
return {
q: params.term
};
},
processResults: function (data, params) {
return {
results: data
};
},
cache: true
},
templateResult: function (data) {
return data.vaccine_name;
},
templateSelection: function (data) {
return data.vaccine_name;
},
minimumInputLength: 3
});
Actually all that was necessary was set the values (selection_array) server-side, then call the select2 initialization
Es.
<%= f.collection_select :attribute, selection_array, :id, :value, {}, {:class => 'form-control', :multiple => true} %>

JQuery UI Autocomplete Multiple Textbox on ASP MVC Razor

I return a class object but only XRCFOR textbox is populate correctly. Select events seems no work.
Through a WebServe I return object items. Select event on a row however is only populated the XRCFOR textbox. Here is the Html/razor/Jquery code. Thanks.
<td>
#Html.EditorFor(model => model.XRUDBF, Functions.GetAdditionalViewData(ViewData["PageStatus"].ToString(), ViewData["PageReadonly"].ToString(), "form-control"))
#Html.EditorFor(model => model.XRCFOR, Functions.GetAdditionalViewData(ViewData["PageStatus"].ToString(), ViewData["PageReadonly"].ToString(), "form-control"))
#Html.EditorFor(model => model.XRCFORDescription, new {htmlAttributes= new { #class = "form-control", #readonly = "readonly" }})
<script type="text/javascript">
$("#XRCFOR").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Zoom/GetFOR/",
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return {
label: item.B5CFOR + " - " + item.B5RGS1, value: item.B5CFOR
};
}))
}
})
},
select: function (event, ui) {
$("#XRUDBF").val(ui.item.B5CUDB);
$("#XRCFOR").val(ui.item.B5CFOR);
$("#XRCFORDescription").val(ui.item.B5RGS1);
},
//messages: {
// noResults: '',
// results: function () { }
//},
minLength: 1
});
</script>
</td>
I've found this solution
success: function (data) {
response($.map(data, function (item) {
return {
label: item.B5CFOR + " - " + item.B5RGS1, value: item.B5CFOR, extravalue: item
};
}))
}
and then
select: function (event, ui) {
$("#XRUDBF").val(ui.item.extravalue.B5CUDB);
$("#XRCFORDescription").val(ui.item.extravalue.B5RGS1);
},
works fine!

Categories

Resources