How do I know the last unselected option from a multiselect dropdown? - javascript

I have a multi select Listbox
<div id="multiselectList">
<select>
<option value="option1">Val 1</option>
<option value="option2">Val 2</option>
<option value="option3">Val 3</option>
<option value="option4">Val 2</option>
<option value="option5">Val 3</option>
</select>
Suppose all the options are selected initially. Now I unselect option2 from multi select list. How can I know which option is currently unselected by the user. I used below code but it was giving me all the unselected values.
var unselectedValue = $("#multiselectList").find('option:not(:selected)');
Can anyone help me in finding the solution?
Thanks in advance

You can use jquery last() for it
https://api.jquery.com/last/
document.querySelector('select').addEventListener('change', () => {
var unselectedValue = $("#multiselectList").find('option:not(:selected)').last();
console.log(unselectedValue.val())
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="multiselectList">
<select multiple>
<option value="option1" selected>Val 1</option>
<option value="option2" selected>Val 2</option>
<option value="option3">Val 3</option>
<option value="option4">Val 4</option>
<option value="option5" selected>Val 5</option>
</select>

Try Using
$(document).ready(function() {
$("#sel").on("click", function(event) {
if(!event.originalEvent.srcElement.selected) {
console.log($(event.originalEvent.srcElement).val());
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="multiselectList">
<select id="sel" multiple>
<option value="option1" selected>Val 1</option>
<option value="option2" selected>Val 2</option>
<option value="option3" selected>Val 3</option>
<option value="option4" selected>Val 4</option>
<option value="option5">Val 5</option>
</select>

Try using
// save array to compare in function check
let lastSelected = [];
// set last selected value on document ready
$(document).ready(() => {
lastSelected = $('select option:not(:selected)')
.map((i, el) => el.value)
.get();
});
$('select').on('change', () => {
const currentSelected = $('select option:not(:selected)')
.map((i, el) => el.value)
.get();
// compare to get recently selected
const selected = lastSelected.filter(
(val) => !currentSelected.includes(val)
);
// compare to get recently unselected
const unselected = currentSelected.filter(
(val) => !lastSelected.includes(val)
);
recentChanges(selected, unselected);
// update last selected
lastSelected = currentSelected;
});
// recentChanges event
function recentChanges(selected, unselected) {
console.log(
(selected.length > 0 ? selected : 'nothing') + ' is selected'
);
console.log(
(unselected.length > 0 ? unselected : 'nothing') + ' is unselected'
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select multiple>
<option value="option1" selected>Val 1</option>
<option value="option2" selected>Val 2</option>
<option value="option3">Val 3</option>
<option value="option4">Val 4</option>
<option value="option5" selected>Val 5</option>
</select>

How can I know which option is currently unselected by the user.
// This is the selected value on page load
let selected = $("#multiselectList option:selected").text()
// On change event
$("#multiselectList select").on("change", function(){
// Keep the previous selection
let prevSelection = selected
// Get the new one
selected = $(this).find('option:selected').text();
// Results
console.log(`${prevSelection} was deselected and ${selected} was selected.`)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="multiselectList">
<select>
<option value="option1">Val 1</option>
<option value="option2">Val 2</option>
<option value="option3" selected>Val 3</option>
<option value="option4">Val 4</option>
<option value="option5">Val 5</option>
</select>
</div>

Related

How do I create a list of the selected options from a dropdwon

I am trying to loop through a multiple select dropdown list and add all of the selected options to a comma separated list.
My dropdown code is:
<select name="testnameID" id="testnameID" multiple>
<option value="1">Test number 1</option>
<option value="2">Test number 2</option>
<option value="3">Test number 3</option>
<option value="4">Test number 4</option>
<option value="5">Test number 5</option>
<select>
In my tag I am using the following, but think it can be simplified or improved:
var testnameID = $('#testnameID').val();
var testnameText;
Array.from(document.querySelector("#testnameID").options).forEach(function(option_element) {
let option_text = option_element.text;
let is_option_selected = option_element.selected;
if (is_option_selected===true){
testnameText = testnameText + option_text +", ";
console.log("TestnameText: "+testnameText);
console.log("\n\r");
}
});
I need to generate a variable, testnameText, which if the first three items were selected, would return a value of "Test number 1, Test number 2, Test number 3"
I'm getting myself in a muddle!
You can try using Document.querySelectorAll() to target all the selected options like the following way:
Array.from(document.querySelectorAll("#testnameID option:checked")).forEach(function(option_element) {
let option_text = option_element.text;
var testnameText = option_text +", ";
console.log("TestnameText: "+testnameText);
console.log("\n\r");
});
<select name="testnameID" id="testnameID" multiple>
<option value="1" selected>Test number 1</option>
<option value="2" selected>Test number 2</option>
<option value="3" selected>Test number 3</option>
<option value="4">Test number 4</option>
<option value="5">Test number 5</option>
<select>
You can also try using Array.prototype.map() and Arrow function expressions which is more shorter.
The following example creates an array of the selected options:
var checkedOptions = Array.from(document.querySelectorAll("#testnameID option:checked"));
var res = checkedOptions.map(option_element => ("TestnameText: "+option_element.text));
console.log(res);
<select name="testnameID" id="testnameID" multiple>
<option value="1" selected>Test number 1</option>
<option value="2" selected>Test number 2</option>
<option value="3" selected>Test number 3</option>
<option value="4">Test number 4</option>
<option value="5">Test number 5</option>
<select>
In this case, jquery's each() can help. So getting selected options is pretty simple:
$('#testnameID :selected').each(function (index, el) {
console.log("TestnameText: " + $(el).text());
});
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<select name="testnameID" id="testnameID" multiple>
<option value="1" selected>Test number 1</option>
<option value="2" selected>Test number 2</option>
<option value="3" selected>Test number 3</option>
<option value="4">Test number 4</option>
<option value="5">Test number 5</option>
</select>
selectedOptions contains all the selected options of a select element. You can use it like this:
const select = document.querySelector('select');
select.addEventListener('change', e => {
// Option texts as an array
const texts = Array.from(e.target.selectedOptions).map(({text}) => text);
// Option texts as a comma-separated string
const textsStr = texts.join(', ');
console.log(texts);
console.log(textsStr);
});
<select multiple>
<option value="1">Test number 1</option>
<option value="2">Test number 2</option>
<option value="3">Test number 3</option>
<option value="4">Test number 4</option>
<option value="5">Test number 5</option>
</select>
This works outside of the event too, just refer the select element directly instead of e.target.

Js dropdown depends of an other dropdown

Hey guys simple question how can I display in the second dropdown information that depends of the first one.
Example. I have this:
var option = document.getElementById("second_dropdown").getElementsByTagName("option");
for (var j = 0; j < option.lenght; j++) {
option[j].disabled = true;
}
<!-- DROPDOWN 1 -->
<select id="first_dropdown" name="first_d">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<!-- DROPDOWN 2 -->
<select id="second_dropdown" name="second_d">
<optgroup label="1">
<option value="100">blabla</option>
<option value="101">blabla</option>
<option value="102">blabla</option>
</option>
<optgroup label="2">
<option value="103">blabla</option>
<option value="104">blabla</option>
<option value="105">blabla</option>
</option>
<optgroup label="3">
<option value="106">blabla</option>
<option value="107">blabla</option>
<option value="108">blabla</option>
</option>
<select>
And I would like to display in dropdown 2 only the optgroup that has been selected in dropdown 1 ...
I really don't know about js so I hope that i explained it well and thanks in advance :)
But here I only disable all (and I want to disable only what's not selected in dropdown one) and I don't want to disable but I want to undisplay.
Loop through optgroup of second <select> and in loop check if value of first select is equal to label of optgroup remove disabled of it.
document.querySelector("#first_dropdown").onchange = function(){
var val = this.value;
document.querySelectorAll("#second_dropdown optgroup").forEach(function(ele){
ele.disabled = ele.label != val
});
};
<select id="first_dropdown" name="first_d">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<select id="second_dropdown" name="second_d">
<optgroup label="1">
<option value="100">blabla</option>
<option value="101">blabla</option>
<option value="102">blabla</option>
</optgroup>
<optgroup label="2">
<option value="103">blabla</option>
<option value="104">blabla</option>
<option value="105">blabla</option>
</optgroup>
<optgroup label="3">
<option value="106">blabla</option>
<option value="107">blabla</option>
<option value="108">blabla</option>
</optgroup>
<select>
Also you should change display property of element if you want to show/hide optgroup
document.querySelector("#first_dropdown").onchange = function(){
var val = this.value;
document.querySelectorAll("#second_dropdown optgroup").forEach(function(ele){
ele.style.display = ele.label==val ? "block" : "none";
});
};
Also you can do this work simplify using jquery
$("#first_dropdown").change(function(e){
$("#second_dropdown optgroup").css("display", function(){
return this.label==e.target.value ? "block" : "none";
});
});
You can try the following way:
var firstDD = document.getElementById('first_dropdown');
firstDD.addEventListener('change',changeDD);
function changeDD(){
var fValue = firstDD.value;
document.querySelectorAll('#second_dropdown > optgroup').forEach(function(el){
if(el.label != fValue )
el.style.display='none';
else
el.style.display='block';
});
document.querySelector('#second_dropdown').value = "";
}
changeDD(firstDD);
<select id="first_dropdown" name="first_d">
<option value="1">Option 1</option>
<option value="2">Option 2</option>
<option value="3">Option 3</option>
</select>
<select id="second_dropdown" name="second_d">
<optgroup label="1">
<option value="100">blabla</option>
<option value="101">blabla</option>
<option value="102">blabla</option>
</optgroup>
<optgroup label="2">
<option value="103">blabla 21</option>
<option value="104">blabla</option>
<option value="105">blabla</option>
</optgroup>
<optgroup label="3">
<option value="106">blabla</option>
<option value="107">blabla</option>
<option value="108">blabla</option>
</optgroup>
<select>

update list of <select> from another <select multiple> using jquery

I am trying to update a <select> element when I select one or multiple values from another <select multiple> using jQuery. Here's my multiple select:
<select class="form-control" multiple>
<option value="1">company 1</option>
<option value="2">company 2</option>
<option value="3">company 3</option>
<option value="4">company 4</option>
</select>
I hope this is what you are looking for,
$('select#first').change(function() {
$("select#second option:not(:first-child)").remove();
$(this).find("option:selected").each(function() {
$("select#second").append($(this).clone());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="first" class="form-control" multiple>
<option value="1">company 1</option>
<option value="2">company 2</option>
<option value="3">company 3</option>
<option value="4">company 4</option>
</select>
<select name="second" id="second">
<option value=''>Select 2</select>
</select>
Check this script https://jsfiddle.net/gpb5wx8h/5/
Jquery:
function chooseItems(item, placeholder){
$(item).change(function() {
var item = $(this);
console.log(typeof(item.val()));
if(typeof item.val() == 'object'){
$.each(item.val(), function(i,v){
var selectedItem = item.find('option[value="'+ v +'"]'),
selectedText = selectedItem.text();
selectedItem.detach();
$(placeholder).append('<option value="' + v +'">' + selectedText + '</option>')
})
}
})
}
$(document).ready(function() {
chooseItems('.choose-role','.placeholder-role');
chooseItems('.placeholder-role','.choose-role');
})
HTML:
<select class="form-control choose-role" multiple>
<option value="1">company 1</option>
<option value="2">company 2</option>
<option value="3">company 3</option>
<option value="4">company 4</option>
</select>
<select class="form-control placeholder-role" multiple>
</select>
If you want to update select options by fetching data from the server end regarding the selected values in multiple select box then you can perform ajax operation and insert the result to the another select box which is to be updated.

Jquery disallow same value from multiple select lists

I need to make sure that when a value is selected in one of the lists, it cannot be selected in any of the others. Can this be done with jQuery, or do I need to create a validator that does not allow selection of the same value?
I have multiple select lists which are basically numbers only, i.e.
<select id="101_1">
<option value="0">0</option>
<option value="1"> 1</option>
<option value="2"> 2</option>
<option value="3"> 3</option>
<option value="4"> 4</option>
<option value="5"> 5</option>
<option value="6"> 6</option>
<option value="7"> 7</option>
....
<option value="50"> 50</option>
</select>
<select id="101_2">
<option value="0">0</option>
<option value="1"> 1</option>
<option value="2"> 2</option>
<option value="3"> 3</option>
<option value="4"> 4</option>
<option value="5"> 5</option>
<option value="6"> 6</option>
<option value="7"> 7</option>
....
<option value="50"> 50</option>
</select>
<select id="101_1">
<option value="0">0</option>
<option value="1"> 1</option>
<option value="2"> 2</option>
<option value="3"> 3</option>
<option value="4"> 4</option>
<option value="5"> 5</option>
<option value="6"> 6</option>
<option value="7"> 7</option>
....
<option value="50"> 50</option>
</select>
I have gotten the following code to work for one of my colleagues :
HTML :
<h3>List 1</h3>
<select id="select1">
<option value="null">-- select --</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
<h3>List 2</h3>
<select id="select2">
<option value="null">-- select --</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
<h3>List 3</h3>
<select id="select3">
<option value="null">-- select --</option>
<option value="A">A</option>
<option value="B">B</option>
<option value="C">C</option>
<option value="D">D</option>
<option value="E">E</option>
</select>
JS with jQuery :
$(document).ready(function() {
var selectState = {
'select1': 'null',
'select2': 'null',
'select3': 'null'
};
$('select').change(function() {
var selectId = $(this).attr('id');
var selectedOptionValue = $(this).val();
// for each other select element
$('select[id!="' + selectId + '"]').each(function(index) {
// enable the old option
$(this).find('option[value="' + selectState[selectId] + '"]').removeAttr('disabled');
if (selectedOptionValue !== 'null') { // if selected a real option
// disable the new option
$(this).find('option[value="' + selectedOptionValue + '"]').attr('disabled', 'disabled');
}
});
selectState[selectId] = selectedOptionValue; // update the new state at the end
});
});
And here is a CodePen
I opted to hide the option tag instead of remove as I suggested. Here is a complete working html file. I was going to post it on jsfiddle, but for some reason it wouldn't work. Be very aware of copy/paste errors in the .change handlers. Spent some time myself wondering why it wasn't working, but it was a copy/paste error.
Note that this code only works if every select tag has the same options. But, it works dynamically if you add or remove options later, while keeping them in sync as noted.
If you need it to work with lists with only some of the same options, you will be stuck dealing with having IDs on the options and then working the hiding/unhiding based on that instead of indexing into the children, but the basic mechanics are the same.
<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.12.0.min.js"></script>
<style type="text/css">
.gone {display: none;}
</style>
<script type="text/javascript">
$(document).ready(function() {
// hides the option selected in the others
var hideValue = function(oldval, val, options, others) {
var unhideChild = -1;
var hideChild = -1;
// find which child to hide in the others
// also find the value we change from and unhide it
for (var i=1; i<options.length; i++) {
var optval = $(options[i]).val();
console.log(optval);
if (optval == val) {
hideChild = i;
}
if (optval == oldval) {
unhideChild = i;
}
}
if (unhideChild == -1 && oldval != "None") {
console.log("uh oh");
return;
}
if (hideChild == -1 && val != "None") {
console.log("uh oh");
return;
}
// hide them using the passed in selectors
for (var j=0; j<others.length; j++) {
if (oldval != "None") {
console.log("unhiding: " + others[j] + " v: " + unhideChild);
$($(others[j]).children()[unhideChild]).removeClass("gone");
}
if (val != "None") {
console.log("hiding: " + others[j] + " v: " + hideChild);
$($(others[j]).children()[hideChild]).addClass("gone");
}
}
}
// we need to keep track of the old values so we can unhide them if deselected
var val1 = "None";
var val2 = "None";
var val3 = "None"
$('#101_1').change(function() {
var opts = $('#101_1').children();
var v = $('#101_1').val();
hideValue(val1, v, opts, ["#101_2", "#101_3"]);
val1 = v;
});
$('#101_2').change(function() {
var opts = $('#101_2').children();
var v = $('#101_2').val();
hideValue(val2, v, opts, ["#101_1", "#101_3"]);
val2 = v;
});
$('#101_3').change(function() {
var opts = $('#101_3').children();
var v = $('#101_3').val();
hideValue(val3, v, opts, ["#101_2", "#101_1"]);
val3 = v;
});
});
</script>
</head>
<body>
<select value="None" id="101_1">
<option value="None">None</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select value="None" id="101_2">
<option value="None">None</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select value="None" id="101_3">
<option value="None">None</option>
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</body>
</html>
Also, if you need the "None" value to not be there, remove it. Then just start the select ta 101_1 having 0 selected, 101_2 with 1 selected etc. Then make sure to trigger the change handler. Also, without the None option, the for loop needs to start with i=0.
So basically add this to the end of the script and make sure var i starts at 0 instead of 1.
$('#101_1').val('0');
$('#101_2').val('1');
$('#101_3').val('2');
$('#101_1').trigger('change');
$('#101_2').trigger('change');
$('#101_3').trigger('change');

Show/hide options from dropdown using jQuery

I have 3 dropdowns which contains more than 4 questions as options in each dropdowns. What I want to achieve is when a user selects one option from any dropdown, that particular option/question has to be hidden from other 2 dropdowns and when he changes his selection that option/question has to be shown again in the other 2 dropdowns. He can select questions from any dropdowns. Here is what I have tried till now. This particular piece of code will hide the options on select but I am not getting how exactly I can show it up back.
Javascript
var removeSelection = function (select) {
$('select').filter(':not(#' + select.attr('id') + ')').each(function () {
var index = select.find(':selected').index();
$(this).find('option:eq(' + index + ')').hide();
});
};
$(function () {
$('select').change(function () {
removeSelection($(this));
});
});
HTML
<form id="form1">
<select id="select1">
<option id="selectOpt1">Question 1</option>
<option id="selectOpt2">Question 2</option>
<option id="selectOpt3">Question 3</option>
<option id="selectOpt4">Question 4</option>
</select>
<select id="select2">
<option id="selectOpt1">Question 1</option>
<option id="selectOpt2">Question 2</option>
<option id="selectOpt3">Question 3</option>
<option id="selectOpt4">Question 4</option>
</select>
<select id="select3">
<option id="selectOpt1">Question 1</option>
<option id="selectOpt2">Question 2</option>
<option id="selectOpt3">Question 3</option>
<option id="selectOpt4">Question 4</option>
</select>
</form>
JSFIDDLE-
CLick Here
Updated Fiddle
Updated
Scenario 1 - Select one option from any dropdown.It should be disabled from other dropdowns.
Scenario 2 - Change option from same dropdown. Previous option should be enabled in other dropdowns.
Once you change the duplicate id's to common classes, You can try something like this
$('select').change(function () {
$("option:disabled").prop("disabled",false); // reset the previously disabled options
var $selectedQ = $(this).find("option:selected"); // selected option
var commonClass= $selectedQ.attr("class"); // common class shared by the matching options
$("."+commonClass).not($selectedQ).prop("disabled","disabled"); // disable the matching options other than the selected one
});
Updated Fiddle
(This won't work if there are more than one, different classes for the options, i'd use a common value or data attribute instead like)
$('select').change(function () {
$("option:disabled").prop("disabled", false);
var $selectedQ = $(this).find("option:selected")
var value = $selectedQ.val();
$("option[value='" + value + "']").not($selectedQ).prop("disabled", "disabled");
});
Demo
Update (as per comments)
$('select').change(function () {
var prevMatches = $(this).data("prevMatches");
if (prevMatches) prevMatches.prop("disabled", false)
var $selectedQ = $(this).find("option:selected")
var value = $selectedQ.val();
var $matches = $("option[value='" + value + "']").not($selectedQ);
$matches.prop("disabled", "disabled");
$(this).data("prevMatches", $matches);
});
Demo
You could do something like this:
var removeSelection = function (select) {
var id=select.attr("id");
$(".hide-"+id).show();
$('select').filter(':not(#' + select.attr('id') + ')').each(function () {
var index = select.find(':selected').index();
$(this).find("option").removeClass("hide-"+id);
$(this).find('option:eq(' + index + ')').each(function(){
if($(this).attr("id")!="selectOpt1"){
$(this).addClass("hide-"+id);
}
});
});
$(".hide-"+id).hide();
};
$(function () {
$('select').change(function () {
removeSelection($(this));
});
});
JSFiddle
Take a look
<form id="form1">
<select id="select1">
<option value="Question1">Question 1</option>
<option value="Question2" >Question 2</option>
<option value="Question3" >Question 3</option>
<option value="Question4" >Question 4</option>
</select>
<select id="select2">
<option value="Question1">Question 1</option>
<option value="Question2" >Question 2</option>
<option value="Question3" >Question 3</option>
<option value="Question4" >Question 4</option>
</select>
<select id="select3">
<option value="Question1">Question 1</option>
<option value="Question2" >Question 2</option>
<option value="Question3" >Question 3</option>
<option value="Question4" >Question 4</option>
</select>
</form>
$(document).on('change','select',function(e){
var elm = $(this);
elm.find('option').show();
$('select').not(elm).find('option',each(function(){
if($(this).attr('value')==$(elm).val()){
$(this).hide();
}else{
$(this).show();
}
}));
});

Categories