Select2 ajax: preselected data in edit mode - javascript

I'm making user profile page on Laravel and using select2 component to filter huge list of items.
I have a ajax-based select2. It's good when you are on /create page, but I need to have selected value in it, when I am on page /edit/1.
$('.search-filter-ajax').select2({
width: '100%',
minimumInputLength: 3,
placeholder: "Search...",
ajax: {
url: '/api/listing/search/',
data: function (term) {
return {
data: term.term
};
},
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.name,
search_from: item.name,
model: 'some_model',
id: item.id
}
})
};
},
dataType: 'json',
type: "GET",
delay: 250,
},
});
I tried to use initSelection function, but no luck, because it creates only select2 text elements, when I need real <option value="1"> something </option> component.
initSelection: function (element, callback) {
var id = $(element).data('select-id');
var text = $(element).data('select-text');
callback({ id: id, text: text });
},
How can I have a valid preselected option in select2 on page load, but still having opportunity to fire ajax call by onChange?

well, you could try to use your own logic to generate slect options like
$.ajax().then((res)=>{
$('#select').html('');
res.data.forEach((item)={$('#select').append($('option').text(item.text).value(item.value);)})
})

Related

select2 not displaying selected value text added programatically

I have a dropdown created with select2 (v4.0.13 and I can not change it) using AJAX requests on a form where the user can search for things. The page is built with Thymeleaf and when the view is reloaded the dropdown value is lost.
Following the recommendation of the documentation itself when you deal with AJAX values, I have writed this code:
let selectedOption = $('#select2-id');
$.ajax({
type: 'GET',
dataType: 'json',
url: baseAjaxUrl + '/api_endpoint?q=' + myVar,
}).then(function (data) {
if (data.length !== 0) {
let optionValues = data[0];
let option = new Option(optionValues.name, optionValues.id, true, true);
selectedOption.append(option).trigger('change.select2');
selectedOption.trigger({
type: 'select2:select',
params: {data: optionValues}
});
}
});
Now, when the view is reloaded the dropdown has the value but does not show its text. An x appears to remove it and if you hover the mouse over it in the tooltip the text that should be displayed in the dropdown appears.
In the <span> generated by select2 I can see the title attribute with the value that should be displayed:
<span class="select2-selection__rendered" id="select2-anId-container" role="textbox" aria-readonly="true" title="The text that should be displayed">
<span class="select2-selection__clear" title="Remove all items" data-select2-id="20">×</span>
</span>
The select2 is initialised as follows:
$('#select2-id').select2({
ajax: {
url: baseAjaxUrl + '/api_endpoint',
dataType: 'json',
delay: 180,
data: function (parameters) {
return {
q: parameters.term,
page: parameters.page
};
},
processResults: function (data, page) {
return {
results: data
};
}
},
placeholder: {
id: "-1",
text: "Select an item"
},
allowClear: true,
escapeMarkup: function (markup) {
return markup;
},
minimumInputLength: 5,
templateResult: formatItem,
templateSelection: formatItemSelection,
theme: "bootstrap",
width: myCustomWidth
});
What is the problem or what have I done wrong?
Greetings.
After finding this answer, my problem was that when selecting an option, templateSelection is used. Checking the function I realised that the object I receive has the fields id and name. The object that handles select2 also has the fields id and name but it has another one, text, and this is the one it uses to show the value!
So in the function I use for templateSelection I have to do:
if (data.text === "") {
data.text = data.name;
}
... other stuff ...
return data.text;
Done!

select2 add custom classes using processResults

I used to add custom classes and use it to fill an input according to the selection
since I did it directly in the view
example:
<option value="290044" data-nombre="xxxx" data-select2-id="20">0931105/Diego Suarez</option>
but since I had to bring more than 70000 records I do it now from the server side and I don't know how to add the custom classes that I want to appear
it appears like this automatically
example
<option value="290044" (here i want to add my custom class) data-select2-id="20">09311055/Diego Suarez</option>
I attach the complete code
$(document).ready(function () {
$("#cliente").select2({
language: "es",
minimumInputLength: 2,
ajax: {
url: "/Clientes/jsonclientes",
dataType: "json",
delay: 250,
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.NIF20 + "/" + item.NOMBRECLIENTE,
id: item.CODCLIENTE,
};
}),
};
},
cache: true,
},
});
$("#cliente").change(function () {
let selected = $(this).find("option:selected");
direccion = selected.data("direccion");
$("#direccione").val(direccion);
});
})

Why Select2 from Jquery shows me a disabled options when I paste in the search input?

I'm using Select2 4.0.6-rc.0 from Jquery, the thing is that when I copy and paste a value to be searched and there is only one option, that option is disabled and I can select it nor click it.
In this image I'm expecting only one results cause SF190 belongs to only one user.
But if the search brings more than one result everything is ok, like in this image:
This is the piece of code I'm using to initialize the Select2:
$('.js-data-example-ajax').select2({
width: '100%',
minimumInputLength: 1,
tags: [],
ajax: {
url: '<URL of my action>',
type: "POST",
dataType: "json",
delay: 1000,
data: function (term) {
return {
query: term.term
};
},
processResults: function (data) {
var res = data.map(function (item) {
return { id: item.Id, text: item.Id + ' ' + item.Name };
});
return {
results: res
};
}
}
});
I really don't know whats going on and I can't find any related solutions.
Here's a working codepen based on your example (and another codepen):
$( ".select2" ).select2({
ajax: {
url: "<url>",
dataType: 'json',
delay: 1000,
//type: "POST",
tags: [],
data: function (params) {
return {
q: params.term // search term
};
},
processResults: function (data) {
var res = data.map(function (item) {
return { id: item.id, text: item.text };
});
return {
results: res
};
},
},
minimumInputLength: 1
});
The only difference is that I removed the request type - I'm pretty sure that you are getting the data here, not posting it :) And if you try to put it back, the filter stops working, albeit in a different way (it returns the full list no matter what you put in the filter), so it might be the source of your problem here.
There is one more thing to consider - are you sure that there is no other code affecting your selectbox? Like something that applies to the .js-data-example-ajax, or any <span> with a single child (that's what a Select2 dropdown part is) etc.

Select2 go to href link

I'm using Select2 js library but I can't not put the links into the select options.
Here is my json structure
[{id: 1, title: "Foo", slug: "foo"}]
And my select2 script
$(".search-box").select2({
placeholder: "Enter...",
ajax: {
url: window.location.href + '/search',
dataType: 'json',
delay: 250,
data: function (params) {
return {
q: params.term // search term
};
},
processResults: function (data) {
// 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
return {
results: $.map(data, function (item) {
return {
text: item.title,
id: item.id
}
})
};
},
cache: true
},
minimumInputLength: 2,
maximumSelectionLength: 6
});
What I expect is when i type and click the title of SELECT OPTION i want the browser go to the post's address (link)
So any help plzzz
You cannot put window.location.href in the URL. Instead, use proper page URL path.
window.location.href is mainly use for page redirection.

set data attributes with ajax and select2

I'm trying setup data attributes into select2 options but without success, at this moment i have the following JS code
_properties.$localElement.select2({
ajax: {
url: "url",
type: "POST",
dataType: 'json',
delay: 250,
data: function (params) {
return {
name: params.term, // search term
type: 1
};
},
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.name,
source: item.source,
id: item.id
}
})
};
},
cache: true
},
//define min input length
minimumInputLength: 3,
});
And i want setup a data-source for the selected option value.
I find the solution, looks that resultTemplate dont format the "visual" selected option , need to use templateSelection option:
templateSelection: function(container) {
$(container.element).attr("data-source", container.source);
return container.text;
}
I solved this problem.
$('select').on('select2:select', function (e) {
var data = e.params.data;
$("select option[value=" + data.id + "]").data('source', data.source);
$("select").trigger('change');
});
You can actually use the exact syntax, that you already used. The "source-attribute" just needs to be accessed via data().data.source of the specific select2-option.
So keep your processResults function like you did:
processResults: function (data) {
return {
results: $.map(data, function (item) {
return {
text: item.name,
source: item.source,
id: item.id
}
})
};
},
and if you want to retrieve the source of the selected option, you can do it like this:
var selectedSelect2OptionSource = $("#idOfTheSelect2 :selected").data().data.source;
In fact you can set any variable you want in your processResults function and then select it via data().data.variableName!

Categories