Initialize multiple selections in select2 - javascript

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} %>

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',
})
}
});

select2 programmatically without knowing results in advance

I am trying to write a test for a Javascript select2 control and I would like to automatically select the first item. Since it's using ajax I do not know what the first item is. All the examples I have seen create <option> however they assume knowledge of the value. How can I select the first item without knowledge? (Note this example only runs the ajax command after 3 items are entered).
var $selector = $("#foo");
$selector.show().select2({
allowClear: true,
placeholder: "--------",
minimumInputLength: 3,
ajax: {
url: "...",
type: 'GET',
dataType: 'json',
delay: 250,
data: function(term, page) {
return {
number__icontains: term
};
},
results: function(data) {
return {
results: $.map(data.objects, function(option) {
return {
'id': option.id,
'text': option.desc
};
})
};
},
cache: false
},
initSelection: function(element, callback) {
...
}
});

Aria attributes not be added to results

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;
}),
};
}

Forcing select2 ajax call

I have 2 select2 and when one of them changes the other one loads it's content using the built in select2 ajax function, the problem is that in the case only one element comes from the server I want it to be loaded by default, but for what I have seen the ajax call is only executed when opening the select2 in question. Here is the code I run when the first selec2 is changed in order to change the second's data:
$select1.on('change', function () {
initializeLocationsSelect2($select2, $select1.val(), $template, omId);
});
function initializeLocationsSelect2(tag, s1Value, template, id) {
tag.val("");
tag.select2({
placeholder: "Please Select One",
minimumInputLength: 0,
multiple: true,
tokenSeparators: [","],
tags: false,
ajax: {
url: tag.data('url'),
dataType: 'json',
quietMillis: 250,
data: function (term, page) {
return {
id: id,
value: s1Value
};
},
results: function (data, page) {
return {
results: data
};
}
},
formatSelection: function (item) {
return $.format(template.html(), item.text);
},
formatResult: function (item) {
return $.format(template.html(), item.text);
},
escapeMarkup: function (m) { return m; }
});
}
just in case it is relevant, the second select2 is attached to a <hidden> tag

Set selected value on select2 without loosing ajax

I have this select2 code in my html (mvc with razor) page:
$('#QuickSearchState').select2({
minimumInputLength: 3,
width: 'resolve',
ajax: {
url: '#Url.Action("QuickSearchState", "DataCenter")',
contentType: 'application/json',
dataType: 'json',
type: 'POST',
traditional: true,
quietMillis: 400,
data: function(term, page) {
var data = {
term: term
};
return data;
},
results: function(data, page) {
return { results: data };
}
},
initSelection: function(element, callback) {
var data = { id: element.val(), text: element.val() };
callback(data);
},
formatResult: function(format) {
return format.label;
},
formatSelection: function(format) {
//this is a knockout view model
vmNewAddress.IdState(format.id);
vmNewAddress.StateName(format.stateName);
return format.label;
},
dropdownCssClass: "bigdrop",
escapeMarkup: function(m) { return m; }
});
But i have another select in my code that can set a state in this select, but i dont know how to set this value to that select.
In my html i have this:
<select class="width-xl" data-bind="options: vm.GivenLocationsForConnection, optionsText: 'DisplayFormat', value: SelectedLocation"></select> -> first select that can fill the second state search select with a state
#Html.Hidden("query", null, new { #id = "QuickSearchState", #class = "width-xl", placeholder = "Ej. Montevideo" }) -> second select, this is a search for states and selects a single state
I am not sure if this is what you want but if you only want to select a value in the select you can just do below
$("#QuickSearchState").select2("val", "<YOUR VALUE>");

Categories

Resources