Unable to select result from select2 dropdown - javascript

I have the following javascript/jQuery that pulls in data from via AJAX. That works fine however I can cannot seem to be able to select an option from the dropdown? Can anyone explain what I have done wrong..
This is something to do with the id..
$(".js-data-example-ajax").select2({
ajax: {
url: "/admin/generator/teams",
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,
id: function(data){ return data._id; },
});

First you should make sure processResults function returns an array of objects with id and text properties like this:
{ id: '1', text: 'Option 1' }
Then once the options are loaded, you can set the value by calling:
$(".js-data-example-ajax").val('1').trigger('change');

Related

Select2: Creating tags with ajax

I am using the select2 library.
My select2 element can search the database for each tag via the ajax and that works fine.
My issue is, I want the user to also be able to create a new tag. Looking at their documentation I should use the createTag option; however, this fires as soon as I click into the element and on each key press.
Can anyone offer any guidance on how I can achieve my goal?
here is my code thus far
I am using ajax top search for tags but I would also like to create new tags to the database. I have tried doing this via createTag but this seems to be firing as soon as I click in the HTML element and on each key press.
Here is my code:
$('.tags').select2({
tags: true,
placeholder: "These tags will apply to all lines",
tokenSeparators: [','],
ajax: {
url: '/api/tags/find',
dataType: 'json',
data: function (params) {
return {
q: $.trim(params.term)
};
},
processResults: function (data) {
return {
results: data
}
},
cache: true,
},
createTag: function(params) {
alert('tag created') // This is were I would put my ajax POST.
}
});
After reading the documentation again, I can see I should have been using the events https://select2.org/programmatic-control/events
I used the createTag option to assign newTag: true to newly created tags and used the select2:selected event which checked if a new tag had been selected and, if it was, sent an ajax request to the server to create that tag.
$('.tags').select2({
tags: true,
placeholder: "These tags will apply to all lines",
minimumInputLength: 3,
tokenSeparators: [','],
ajax: {
url: '/api/tags/find',
dataType: 'json',
data: function (params) {
return {
q: $.trim(params.term)
};
},
processResults: function (data) {
return {
results: data
}
},
// cache: true,
},
createTag: function(params) {
let term = $.trim(params.term);
if (term.length < 3)
{
return null
}
return {
id: term,
text: term,
newTag: true,
}
},
});
$('.tags').on('select2:select', function (e) {
let tag = e.params.data;
if (tag.newTag === true)
{
axios.post('/api/newtag', {
name: tag.text,
type: 'default',
})
}
});

how to pass $(this) of select2 inside ajax parameters

I need to pass $(this) of select2 inside ajax to get data-url like like code below it, $(this).data("url") not working.
$(".select-ajax").select2({
allowClear: $(this).data('allowclear') ? $(this).data('allowclear') : false,
ajax: {
url: $(this).data("url"),
dataType: 'json',
delay: 250,
data: function(params) {
return {
q: params.term, // search term
page: params.page
};
},
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: data
};
},
cache: true
},
escapeMarkup: function(markup) {
return markup;
}, // let our custom formatter work
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
The easiest way to deal with this and similar situations is to set a constant to refer to.
const selectAjax = $(".select-ajax");
selectAjax.select2({
allowClear: selectAjax.data('allowclear') ? selectAjax.data('allowclear') : false,
ajax: {
url: selectAjax.data("url"),
dataType: 'json',
delay: 250,
data: function(params) {
return {
q: params.term, // search term
page: params.page
};
},
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: data
};
},
cache: true
},
escapeMarkup: function(markup) {
return markup;
}, // let our custom formatter work
templateResult: formatRepo,
templateSelection: formatRepoSelection
});
You need to set this as a variable.
var that = $(this);
that.select2({
...
//other code
url: $(that).attr("data-url")
//other code
});

jQuery.map() to Parse results from select2 ajax call

I have the following select2 ajax call. How do I use the jquery $.map() to parse the returned json results. From the users array i need to get the Text and Value results. From the pager array I need to get the TotalItemCount. What I have below doesnt seem to work i.e the search results don't seem to display in the select list. No console errors are shown either so I'm not sure what Im doing wrong.
var url = '#Url.Action("GetEmployees", "Employees")';
var pageSize = 20;
$(".js-data-example-ajax").select2({
ajax: {
url: url,
dataType: 'json',
delay: 250,
data: function (params) {
return {
term: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
params.page = params.page || 1;
return {
results: $.map(data, function (users) {
return {
text: users.Text,
id: users.Value
}
}),
pagination: {
more: (params.page * pageSize) < data.pager.TotalItemCount
}
};
},
cache: true
},
minimumInputLength: 2,
placeholder: "-- Select --",
allowClear: true
});
The json returned is as follows:
{
"pager":{
"PageCount":1,
"TotalItemCount":1,
"PageNumber":1,
"PageSize":20,
"HasPreviousPage":false,
"HasNextPage":false,
"IsFirstPage":true,
"IsLastPage":true,
"FirstItemOnPage":1,
"LastItemOnPage":1
},
"users":[
{
"Disabled":false,
"Group":null,
"Selected":false,
"Text":"Joe Blogs",
"Value":"97306aa4-d423-4770-9b45-87a701146b10"
}
]
}
I was correct. I wasn't using the jQuery.map() correctly. It should be as follows:
results: $.map(data.users, function (users) {
return {
text: users.Text,
id: users.Value
}
}),

Select2 - start ajax search on enter

I have a Select2 input which I use to search (remote data).
Currently, it works like this:
when user types 1 one more characters we trigger search automatically
Now, the fun part:
I need to add following behaviour:
when user focus on in this input and just hits Enter button, I need to trigger search with one character '*' BUT without actually writing that character in the input.
It should just send search request with character * but input should stay empty.
Is that even possible without messing Select2 code?
My code:
$("#account").select2({
language: "en",
ajax: {
url: window.urls.ajax_account_search,
dataType: 'json',
delay: 500,
data: function(params){
console.log(params);
return {
query: params.term,
page: params.page
}
},
processResults: function(data, params){
return {
results: data.items
}
},
cache: true
},
escapeMarkup: function(m) { return m; },
templateResult: formatSearchResult,
templateSelection: formatSearchSelection,
minimumInputLength: 1
});
Instead of triggering the search on enter (with * being sent), you can just send * when there is no search term present. This also means dropping the minimumInputLength requirement, but that seems to line up with what you are looking for.
$("#account").select2({
language: "en",
ajax: {
url: window.urls.ajax_account_search,
dataType: 'json',
delay: 500,
data: function(params){
return {
query: params.term || '*', // send * if there is no term
page: params.page
}
},
processResults: function(data, params){
return {
results: data.items
}
},
cache: true
},
escapeMarkup: function(m) { return m; },
templateResult: formatSearchResult,
templateSelection: formatSearchSelection
});

select2JS Ajax Option Value

I'm developing a form with select2JS.
In my first step I use a simple Select2
$(this).select2();
But I want to change it for an Ajax version.
$(this).select2({
multiple:multival,
ajax:
{
url: '/api/v2/vocabulary/'+vocabulary+'/words/list',
headers: {'X-AUTHORIZATION-TOKEN': token},
dataType: 'json',
type: "POST",
quietMillis: 100,
data: function (params) { // Lors d'une recherche
return {
pattern: 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.words,
pagination: {
more: (params.page * 15) < data.total
}
};
},
initSelection : function (element, callback) {
var data = [];
$(element.val()).each(function () {
data.push({id: this, text: this});
});
callback(data);
},
cache: true
},
escapeMarkup: function (markup) {return markup; }, // let our custom formatter work
minimumInputLength: 0,
templateResult: function formatRepo (repo)
{
return repo.name;
},
templateSelection: function formatRepoSelection (repo)
{
return repo.name;
}
});
In the first version, my Ajax return the name of the Option ( When I send the form). In the Ajax version, the script create a new Option inside the select ( But not visible ) and when I send the form its an Id who is sent. Because in the Value of the new Option, its the Id and not the name.
I use Select2 4.0.1 and I find in the 3162' Line :
if (data.id) {
option.value = data.id;
}
I tried to change data.id by data.name, but it was not effective.
Do you have an idea?

Categories

Resources