Select2 multiple-select - programmatically deselect/unselect item - javascript

I have a select2 list and a set of external buttons. I wanted to click the external buttons and unselect corresponding items in the select2 list. I know I can do item selection from external value using the command
$("#external_btn").click(function() {
$("#select2").val("CA").trigger("change");
});
So when I click on the "external_btn" button, the "ca" item will be selected on the select2.
But how I can do item unselection? Thanks.

There does not appear to be a built-in function to programmatically deselect/unselect an option from a multiple-select Select2 control. (See this discussion.)
But you can get the array of selected values, remove the value from the array, and then give the array back to the control.
Select2 v4:
The following code works for Select2 v4. It also works for Select2 v3 as long as the control is backed by a <select> element, rather than a hidden input element. (Note: When using Select2 v4, the control must be backed by a <select> element.)
var $select = $('#select');
var idToRemove = 'c4';
var values = $select.val();
if (values) {
var i = values.indexOf(idToRemove);
if (i >= 0) {
values.splice(i, 1);
$select.val(values).change();
}
}
JSFiddle for Select2 v4
JSFiddle for Select2 v3
Select2 v3:
The following code works for Select2 v3, regardless of whether you back the control with a <select> element or a hidden input element.
var $select = $('#select');
var idToRemove = 'c4';
var values = $select.select2('val'),
i = values.indexOf(idToRemove);
if (i >= 0) {
values.splice(i, 1);
$select.select2('val', values);
}
JSFiddle for Select2 v3, using <select> element
JSFiddle for Select2 v3, using hidden input element

As you've indicated in your question, you can modify the state of the underlying select element and then trigger a change. So then you can simply deselect an option in the same way you might with a regular select.
Assuming an option of value "val", the following code would deselect it:
$("#select option[value=val]").prop("selected", false) // deselect the option
.parent().trigger("change"); // trigger change on the select
http://jsfiddle.net/9fD2N/3/

I don't see anything to "deselect" an element. But, you can get the list of currently selected elements, remove your element and then set the value.
http://jsfiddle.net/wLNxA/
$("#e8_2").select2({
placeholder: "Select a state"
});
$('#removeBtn').click(function () {
// get the list of selected states
var selectedStates = $("#e8_2").select2("val"),
index = selectedStates.indexOf('NV'); // we're removing NV, try to find it in the selected states
if (index > -1) {
// if NV is found, remove it from the array
selectedStates.splice(index, 1);
// and set the value of the select to the rest of the selections
$("#e8_2").select2("val", selectedStates);
};
});

It's works.
$('{SELECTOR}').val('').trigger('change')

If you do not have any other event listener action on select option better :
$("#select2").val("CA").attr('checked', 'checked'); // to check
$("#select2").val("CA").removeAttr('checked'); // to un-check

Related

update select dropdown values using angularjs/javascript

I have a drop down(dropddown2) which is displayed using a json object:
listData:[{id:"1",label:"lbl1"},{id:"2",label:"lbl2"}]
When I select a value in dropddown1, I need to add a value to the dropdown2 list and display it. I think I am able to push the data, but I cannot see it on UI.
On dropdown1, you'll need to add an event listener for the onchange event that triggers a function where you can capture the selected value and add a new value to the other dropdown.
You can do something like this:
<select id="carsSelector" onchange="addToSelector();">...</select>
function addToSelector() {
var val = document.getElementById('carsSelector').value;
var selector = document.getElementById('addSelector');
var option = document.createElement("option");
option.text = val;
selector.add(option);
}
Here's a fiddle showing this.

Preselecting options of multiple selectbox, using Materialize css FW doesn't work

I'm using materialize css framework. When I'm printing multiple selectbox (<select multiple>...), preselected options (<option selected...>) won't render.
Browser however understand that some options are preselected, so they are send again, when the form is submited. Also because of the rendering issue i'm unable to manipulate with preselected options or select new ones.
Normal Selectbox works just fine.
You can add onchange event to field and reset the values by accessing all the (li) children. If you see carefully. Multi select uses UL and a text field for value storing and keeps class "Active" for li. And append this code after .material select since check boxes are initialized after that
you can try following in
function change_materialize_multiple_Select(id_of_select)
{
var newValuesArr = [],
select = $(id_of_select),
ul = select.prev();
ul.children('li').toArray().forEach(function (li, i) {
if ($(li).hasClass('active')) {
newValuesArr.push(select.children('option').toArray()[i].value);
}
});
select.val(newValuesArr);
}

Removing an option from all other chosen multiple dropdowns, when selected on a particular dropdown

I have attached a JS Fiddle link here:
http://jsfiddle.net/p0b4j5o8/18/
If you check the fiddle link, you will see that I have written JavaScript/jQuery code (a function named add_mitigator()) in the HTML section.
When I used to write the code in the JavaScript section, Firebug used to trigger an error stating function add_mitigator() isn't defined.
But when I wrote the same in the HTML section instead, it runs with no problem. I am not much accustomed with JS Fiddle. How can I write a function in function_name() format in the fiddle?
In my JS Fiddle, there is a dropdown (chosen multiple) with options 1 to 10. When I click on the add_mitigator link, it creates/appends a new chosen dropdown.
Suppose I have three dropdowns, then if I select 2 from dropdown 1, then the other dropdowns will have 2 removed from their options. When I will unselect the 2 from the first dropdown, then 2 will again be available in the other two dropdowns. This should act vice-versa. When 2 is selected from any dropdown, then it is unavailable for all other dropdowns.
How can I achieve this?
By calling the function below on the select box change event the options will be disabled/enabled as per your requirements.
function disableSelectedValues() {
var cssOptions = [];
$(".input_field.criteria_countries option").removeAttr("disabled");
$.each($(".input_field.criteria_countries"), function(index, select) {
cssOptions = [];
var values = $(select).val();
if (values) {
for (var i = 0; i < values.length; i++) {
cssOptions.push("option[value=" + values[i] + "]");
}
}
console.log("test");
if (cssOptions.length) {
// disable all options with the selected values
$(".input_field.criteria_countries "
+ cssOptions.join(",.input_field.criteria_countries ")).attr("disabled", true);
// enable all options with the selected values for the current select
$(select).find(cssOptions.join()).removeAttr("disabled");
}
});
}
With .chosen you can listen to onchange events with .chosen().change();.
In the .chosen().change() event you then need to tell all of the select boxes to update once a value has changed. By using .trigger("chosen:updated"); on the select box selectors whenever a change event is fired, the select boxes will update.
NOTE that you will need to call the disableSelectedValues() function whenever you add a select box to have its options disabled on creation.
http://jsfiddle.net/p0b4j5o8/22/

Using Jquery, load select options on focus

I am trying to load options into a select element when the user focuses.
Here is the jquery code I'm using:
$('select').focus(function() {
var $this = $(this);
if (!$this.data('hasitems')) {
var selectedValue = $this.val();
$this.empty()
.append($('<option></option')
.attr('value','')
.text('Loading...'));
// This would usually be the result of an AJAX call
$this.empty()
.data('hasitems','true');
$.each(['a','b','c','d'], function(index,item) {
$this.append($('<option></option>')
.attr('value',item)
.text(item)
.prop('selected', selectedValue == item));
});
}
});
Here is the fiddle:
http://jsfiddle.net/agnnC/
The solution almost works... except in Firefox (and sometimes not in Chrome either, although the fiddle I put together does appear to work).
The problem in Firefox is that when the user clicks on the select element, the currently selected value is not remembered and is changed to one of the new values in the drop down.
Can anyone think of a workaround?
I think the issue is that the selected attribute is not really a property the way you are using it. Per the MDN doc:
selected
If present, this Boolean attribute indicates that the option is
initially selected. If the element is the descendant of
a element whose multiple attribute is not set, only one single
of this element may have the selected attribute.
Note, it talks about "initially selected" only, not real time changes. It also refers to selected only as an attribute, not a property.
The W3C spec for the option element also talks only about pre-selecting an option, not about making live changes using the selected attribute.
Once the select and options are live, the .selectedIndex property on the <select> object controls which option is selected in real time for single selection select elements.
In support of this theory, if you change to setting the saved item with .selectedIndex as shown below, the problem goes away:
$('select').focus(function() {
var $this = $(this);
if (!$this.data('hasitems')) {
var selectedValue = $this.val();
$this.empty()
.append($('<option></option')
.attr('value','')
.text('Loading...'));
// This would usually be the result of an AJAX call
$this.empty()
.data('hasitems','true');
$.each(['a','b','c','d'], function(index,item) {
$this.append($('<option></option>')
.val(item)
.text(item));
if (selectedValue == item) {
$this.prop("selectedIndex", index);
}
});
}
});
Working demo: http://jsfiddle.net/jfriend00/4333d/
Firefox can't change the focus option when select is opening, but you can change before it open, change the event to mousedown it working Fiddle
$('select').mousedown(function() {
// ...
});

How to trigger an event ONLY if both dropdowns are selected?

I have a dropdown select list on my page of class="TypeFilter".
I have a jQuery event that fires when a value in that list is selected.
$(".TypeFilter").change(function()
{
// Extract value from TypeFilter and update page accordingly
));
I now have to add another list to the page, and I want to implement functionality which will prevent the .change(function() from running unless both are selected.
In both lists the first option in the list is some text instructing the user to select one of the items, so I was thinking of just writing some logic to test that both lists have a selected index greater than 0.
I think this is a touch unclean though, especially considering that other pages that have a TypeFilter use the same logic.
Is there any nifty functionality in jQuery that can do this?
edit I should specify that the user needs to be able to update the page by selecting either dropdown, so I can't put the onchange on the second element and test that the first element has a selected value, as suggested in one of the answers
If you bind the same event to all dropdowns, you can get a collection of all the dropdowns and check that all of them are selected. Example:
$('.Dropdown').change(function(){
var elements = $('.Dropdown');
if (
elements.filter(function(){
return this.selectedIndex > 0;
}).length == elements.length
) {
// all dropdowns are selected
}
});
As you partly mention, put the onchange on the second element and test that the first element has a selected value before you fire off any logic.
Use bind instead, and as the eventdata, send a function that checks that either that both are selected or that the other is selected. Untested code:
function checker() {
// test your conditions
}
$(".TypeFilter").bind('change', {test: checker}, function(event)
{
if (event.data.test && event.data.test()) {
// Extract value from TypeFilter and update page accordingly
}
));
This way the other pages that use the same function will not notice any changes.

Categories