How to select and add a new item in select2 - jquery-select2

I am pulling my hair off trying to do a very simple thing with select 2. When I edit a record of table1, I have a simple select dropdown with a list of items built from a field of table1 (with distinct). Sometimes I need to add a new item. So I thought that the example to create and add a new item would work but it does not. When I type the new item in the open box on top of the dropdown, I got "No result found"... ok but how do I force this new item to be selected and recorded in the database (and obviously available for later use)?
I am not really good in JS, so I presume I am doing something wrong or something is missing... please help.
<select class="selectAdd-who" name="who">
<option value="item1">item1</option>
<option value="item2" selected>item2</option>
<option value="item3">item3</option>
</select>
<script>
$(document).ready(function() {
$('.selectAdd-who').select2();
// Set the value, creating a new option if necessary
if ($('.selectAdd-who').find("option[value='" + data.id + "']").length) {
$('.selectAdd-who').val(data.id).trigger('change');
} else {
// Create a DOM Option and pre-select by default
var newOption = new Option(data.text, data.id, true, true);
// Append it to the select
$('.selectAdd-who').append(newOption).trigger('change');
}
});
</script>

Related

Removing selected option in multiple select2 clears all options

Using Laravel livewire, bootstrap 5 modal and select 2.
Select2 (s2) without multiple works fine. It's populated, selections save to the component, clearing is also fine.
When an s2 has multiple attribute, removing a selected option clears all the options and nothing is displayed in the results drop down. When adding a selection, this doesn't happen.
If I do a dispatchBrowserEvent and re-init the s2 it does work again.
My question is why does removing an s2 option require a re-init but an add doesn't.
Seems to be something to do with the rendering in render().
Some code...
Blade:
<div wire:ignore>
<select id="selectedTrades" wire:model.defer="selectedTrades" class="select-2" multiple="multiple" data-field="selectedTrades" data-allow-clear="false">
#foreach ($contractor_trades as $trade)
<option value="{{ $trade['id'] }}">{{ $trade['name'] }}</option>
#endforeach
</div>
Standard stuff. wire.ignore around the s2. The modal has wire:ignore.self.
JS:
$('.select-2').on('change', function (e)
{
var $this = $(this);
livewire.emit('setSelect2Property', $this.attr('data-field'), $this.val());
});
Component:
public function setSelect2Property($property, $value)
{
$this->$property = $value;
}
Just sets $this->selectedTrades to the array sent.
Adding:
The drop down has the options as expected.
Removing:
The thin light line under it is the container for the results that's now empty. The original select element does still have its options.
If I remove the livewire.emit from the js to test, the s2 behaves correctly.
I think it has to do with the components render method. I can't figure out what is happening different when I add versus remove.
I got this to work. The problem was the dropdownParent element I was using. I had it set to the modal. Setting it to the immediate parent element and it worked as expected.

MVC "Editfor" Element for a "List<string>" with the option to add new elements

I need way to display a "List" property with the option to add new elements to the list.
So Basically
Value 1
Value 2
Button: Add new
I created an editfor template for it, where I display all the values with a foreach loop. However, each item get's an index, so when I add a new input field with javascript, the index is wrong.
Any suggestions how to achieve this.
PS: the adding of new elemens mustbe done on the client, since it is a simple form
var abccounter = 1;
$("#abcbutton").click(function () {
$('#itemlist').append('<p><input class="text-box single-line" id="listofstringname_' + abccounter + '_" name="listofstringname[' + abccounter + ']" type="text" value=""></p>');
abccounter++;
});
<p>#Html.EditorFor(model => model.listofstringname)</p>
that is what I did and it worked. the only problem I'm having (and it may be solved eventually) is I want to wrap each element with a tag but I'm not sure how. this JS just adds a new "text box element" assuming 1 as the start as my model loads 1 example by default.

Select2 doesn't show selected value

Select2 loads all items from my list successful, the issue I found when try to select a specific value when page loads. Example:
:: put select2 in a specific html element, no value is selected even all items are loaded.
$('#my_id').select2();
:: When the page is loaded I'm trying to show a specific item selected, but doesn't work as expected, because even selected, the select2 doesn't show it.
$('#my_id').val('3'); //select the right option, but doesn't render it on page loads.
How to make a selected option to pop up when pages loads?
Thanks in advance.
#UPDATED
:: How I load all select2 items (sorry, its jade, not pure HTML):
label(for='category') Category
span.required *
select(id='category', style='width:230px', name='category')
option(value='') - Select -
each cat in categories
option(value='#{cat.id}') #{cat.description}
P.S.: All items from my list are loaded.
:: How I initialize the select2:
Just put the following line code on my javascript and it does successful:
$('#category').select2();
:: How I'm trying to select a specific value:
First attempt:
$('#category').select2(
{
initSelection: function(element, callback) {
callback($('#field-category').val());
}
}
);
Second attempt:
$('#category').val($('#field-category').val());
P.S.: #field-category has a value its a hidden input field and works OK.
You need to use the initSelection option to set the initial value.
If you are using a pre-defined select element to create the select2, you can use the following method
$('select').select2().select2('val','3')
Demo: Fiddle
add a trigger change after setting val:
$('#my_id').val('3').trigger('change');
A very simple way to tackle this problem is :
//Step1: Here assuming id of your selectbox is my_id, so this will add selected attribute to 1st option
$('#my_id option').eq(0).prop('selected',true);
//Step2: Now reinitialize your select box
//This will work, if you haven't initialized selectbox
$('#my_id').select2();
or
//This will work, if you have initialized selectbox earlier, so destroy it first and initialise it
$('#my_id').select2('destroy').select2();
This may help:
$('#mySelect2').val('1'); // Select the option with a value of '1'
$('#mySelect2').trigger('change'); // Notify any JS components that the value changed
You can find more on details here:
Thanks
Per here initSelection is deprecated in Select2 4.0 and later.
Using Select2 4.0.0 this worked for me:
$('#my_id').select2({val:3});
HT: #Kokizzu
Here is how to make val in select2 just select the corresponding element.
For some reason, select2 doesn't provide the function to look up selections by id.
init:
$("#thing").select2({data:sources, initSelection: function(item, callback) {
// despite select2 having already read the whole sources list when you
// do .val(n) you have to explicitly tell it how to find that item again.
var to_be_selected = null;
$.each(sources, function(index, thing) {
if (thing.id == item.val()) {
to_be_selected = thing;
return;
}
})
callback(to_be_selected);
}})
normal code
// to load the thing with id==3 from the initial sources list.
$("#thing").select2({'val': 3})
For me I was sending selected in the data set still default option was not getting selected. I had to do something like below to make it work -
$(".select").select2({
data: data_names
});
data_names.forEach(function(name) {
if (name.selected) {
$(".select").select2('val', name.id);
}
});
I had a multiple select2 box with multiple selections.
Step 1 was to put my string of school_ids into an array of integers corresponding to the id of each school, and remove a leading zero. I had to do this in a separate script tag.
<script>
var school_ids = <%= raw JSON.parse(#search.school_ids).map{|x| x.to_i} - [0]%>
</script>
Step two was to create the select box, then set the values, then trigger like so:
<script>
$(document).ready(function() {
$('.select2-multiple').select2({
placeholder: "Hit Enter After Selection",
width: 'resolve'
});
$('.select2-multiple').val(school_ids);
$('.select2-multiple').trigger('change');
</script>
trigger just select2 to set the value
$('#my_id').val('3').trigger("change.select2");
and this will trigger select2 with dropdown
$('#my_id').val('3').trigger("change");
I meet with the same problem, this works for me:
Using Select2 > 4.0.0
$('#select_id').val('3').trigger('change');
var option=$(this);
if(option.val()==data.StudentCourses.CourseId)
{
option.setAttribute('Selected');
}
});
i have initilized select2 because i just want few options selected from them.
If you are using select2 v4.0.0 or above, you can check select2 documentation
// Initialize select2 for all select tags
$('select').select2();
// Initialize select2 for a specific id
$('#my-id').select2();
// Initialize select2 for a class
$('.my-class').select2();
// Update the displayed value after changing the selected option.
$('#my-id').trigger('change');
$('.classname').each(function() {
$(this).siblings().find('.select2selection__rendered').text($(this).text())
})
in my case I were dealing with a class then I used this way to set showing content at select2
<option selected value="your_value">your_text</option>
u need to put this at each select box's first option

Manually triggering the styling on a jQuery mobile select list

I'm building a select list with an Ajax call that is triggered when another select list is changed.
The page loads correctly with the jQuery styling, but when I replace my ajax container with the new div I can't get jQuery mobile to format it. This means that it reverts to the native select list format.
I have tried what is suggested in the JQM documentation:
var myselect = $("select#foo");
myselect[0].selectedIndex = 3;
myselect.selectmenu("refresh");
but that does not work. My page initially loads with this:
<div id="ajax-destination">
<select id="destinationAirport" data-native-menu="false">
<option value="-- Please Select --" data-placeholder="true">-- Please Select --</option>
</select>
and this is my jQuery code wrapped in the change function of the other select list.
$('#ajax-destination').empty();
$.post(url, { departureAirport : departureAirport }, function(data) {
$('#ajax-destination').append(data);
var myselect = $("#destinationAirport");
myselect[0].selectedIndex = 1;
myselect.selectmenu("refresh");
});
The only other way I can think to do this is to return a JSON array via Ajax and use that to add the options to the select list, but I would prefer to just send formatted HTML because it's simpler to follow.
If myselect.selectmenu("refresh"); or myselect.selectmenu("refresh",true); doesn't work you can always refresh the page using
you could try myselect.trigger('create');
#Andy :
myselect.selectmenu("refresh"); will refresh the select box and where as
myselect.selectmenu('refresh', true); will rebuild the select menu.It may helps you out. Check this link once http://forum.jquery.com/topic/how-to-add-items-and-refresh-the-select-menu-in-jquery-mobile

Jquery Mobile Select does not reset

I am writing a web shop with Jquery Mobile where I want to use a select menu to browse the categories available. When the user selects a category I want to navigate to the same page but with a couple of parameters added to the url. This is my markup for the select:
<asp:Repeater id="productCatSelect" runat="server">
<HeaderTemplate>
<select id="productCatSelectMenu" data-native-menu="false" onchange="categoryClick();" class="button" data-theme="a">
<option data-placeholder="true">All Categories</option>
</HeaderTemplate>
<ItemTemplate>
<option value="<%# Eval("NodeID") %>" ><%# Eval("Description")%></option>
</ItemTemplate>
<FooterTemplate>
</select>
</FooterTemplate>
</asp:Repeater>
And here is the javascript:
function categoryClick() {
var mySelect = $("#productCatSelectMenu");
if (mySelect.val() != '') {
if (mySelect.val() == 0) {
$.mobile.changePage("shop.aspx", {reloadPage: true, transition:"slide"});
} else {
$.mobile.changePage("shop.aspx?c=" + $("#productCatSelectMenu").val() + "&n=" + $('#productCatSelectMenu :selected').text(), {reloadPage: true, transition:"slide"});
}
}
}
My problem occurs when I have navigated once and try to choose another option from the select, my javascript still retreives the previous value; the select does not seem to reset! However, when I press F5 and reload the page manually the menu works again, until I have used it once of course.
Anyone have any ideas on how I can fix this? As you can see in the javascript the "reloadPage: true" attribute does not fix the problem.
If you're using jQuery Mobile's custom select field, try
$("#select_id").selectmenu('refresh', true)
This will successfully reset the select options rendered by jQuery mobile.
You're going to need to reset this yourself, maybe try:
$('select#productCatSelectMenu option').attr('selected', false);
or
$('select#productCatSelectMenu option').removeAttr('selected');
or
$('select#productCatSelectMenu').children('option').removeAttr('selected').filter(':nth-child(1)').attr('selected', true);
or
$('select#productCatSelectMenu').attr('selectedIndex', -1);
I had a similar problem the other day
Reset/Un-select Select Option
I have no clue why Jquery mobile select is working the way it is. None of the above worked for me except for what is mentioned here. I am using the current versions
jquery-1.10.2.min.js
jquery.mobile-1.4.2.min.js
https://forum.jquery.com/topic/resetting-select-menu
var myselect = $("select#useOfColor");
myselect[0].selectedIndex = 0;
myselect.selectmenu("refresh");
Have you tried $('#productCatSelectMenu').selectmenu('refresh');?
You can check information about the refresh method in the documentation

Resources