Multiple select get Selected options in order selected - javascript

i have a multiple select like the following
<select name="cars" id="cars" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>
that i have implemented chosen plugin on i have an onchange listener that adds selected elements to an array like so
$("#cars").change(function () {
var selected = [];
for (var option of document.getElementById('cars').options) {
if (option.selected) {
selected.push(option.value);
}
}
console.log(selected);
});
however in which ever option i select the items they always end up arranging themselves in the order they are in the multiple select
for example by selecting the values Volvo , Audi, Saab in that order results in the following array
Array [ "Volvo" ]
Array [ "Volvo", "Audi" ]
Array(3) [ "Volvo", "Saab", "Audi" ]
Is there a way that i can add elements in a multiple select to an array in the order which they were selected?

You always get the same order of the selected array because you create it each time you run your onChange function. So the solution would be to make it a global variable. When you do that, your array won't be empty at the second choice tho, so you have to take care of removing items from it.
Here's some code
var selected = [];
$("#cars").change(function () {
for (var option of document.getElementById('cars').options) {
var value = option.value;
if (option.selected) {
if(selected.indexOf(value) < 0){//we only add element if it's not present in the array
selected.push(value);
}
}else{
if(selected.indexOf(value) >= 0){ //we only remove item if it is present
selected.splice(selected.indexOf(value),1)
}
}
}
console.log(selected);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select name="cars" id="cars" multiple>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="opel">Opel</option>
<option value="audi">Audi</option>
</select>

Related

Filter Drop down list by another drop down list Id ASP.Net

HI I have a issue with filtering one drop down list with another drop down list,
in my search.cshtml file I have added
#{
List<FormCategory> formCategories = ViewBag.formCategories;
List<Form> forms = ViewBag.forms;
List<UsersVM> users = ViewBag.Users;
List<FormSearchResultsVM> results = ViewBag.Results;
}
<select id="selFormCategories" class="sc-select sc-input" onchange="onFormCategoriesChanged(this)">
<option id="0"></option>
#foreach (var formCat in formCategories)
{
<option value="#formCat.ID">#formCat.Name</option>
}
</select>
<select id="selForms" class="sc-select sc-input" onchange="onFormsChanged(this)">
<option id="0"></option>
#foreach (var form in forms)
{
<option value="#form.ID">#form.Name</option>
}
</select>
I need to filter selForms dropdown when selFormCategories onchnage event...
function onFormCategoriesChanged(sel) {
selectedFormCategory = $(sel).find(':selected').attr('value');
}
Thanks
Here's one way I could think of. First, we should store the option elements to a jquery object array then filter that array for display whenever a select is changed.
Data attributes (data-property, data-name, etc) is used for filtering.
In my example below, whenever the vehicle select is changed, it will clear and refill the brands select with corresponding brands from that vehicle type.
$(document).ready(function(){
var vehicleList = [];
var brandsList = [];
// store brands options to variable on document ready
$("#brands option").each(function(){
brandsList.push($(this));
});
// clear brands select to hide option fields
$("#brands").html("");
// vehicle select on change, refill brands with matching data-vehicle value
$("#vehicle").change(function(){
var brandsSelect = $("#brands");
var vehicleValue = $(this).val();
brandsSelect.html("");
brandsSelect.show();
$(brandsList).each(function(){
if($(this).data("vehicle") == vehicleValue){
$(brandsSelect).append($(this));
}
});
});
});
<html>
<body>
<h5>Select a Vehicle Type</h5>
<select id="vehicle">
<option>Motorcycle</option>
<option>Car</option>
</select>
<h5>Choose Brand</h5>
<select id="brands" hidden>
<option data-vehicle="Motorcycle">Yamaha</option>
<option data-vehicle="Motorcycle">Kawasaki</option>
<option data-vehicle="Car">Mercedes Benz</option>
<option data-vehicle="Car">BMW</option>
<option data-vehicle="Car">Audi</option>
</select>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</body>
</html>

variables seem to be coupled

I've got this weird problem with my JavaScript code.
I'm trying to create dynamically loading select boxes without the luxury of something like React.
It compares values of other select boxes so that a value can only be selected in once. So if a value is already set in one select box, it cannot be selected again.
For this I use a list of original values, clone those values into a new variable and remove the ones already selected and then create new lists.
Works fine albeit the numerous loops. The only problem is that if I remove an item from the cloned variable, the original also changes.
Even if I push the original variable in a prototype object or use const.
window.initial_abstract_list = ["Option one", "Option two", "Option three", "Option four", "Option five"];
// Set the option values
function reset_abstract_list() {
var in_list = [];
var new_list = window.initial_abstract_list;
console.log(window.initial_abstract_list); /// window.initial_abstract_list changes!!!
// Get selected value of all select boxes
$.each($('select.values-list'), function(index, value) {
in_list.push($(value).val().toString())
});
// Remove already set values from list
$.each($('select.values-list'), function(index, value) {
$.each(in_list, function(index2, value2) {
delete new_list[value2.toString()];
});
});
// Generate new options for select boxes
$.each($('select.values-list'), function(index, value) {
var current_selected_key = $(value).val().toString();
var current_selected_val = $('option:selected', value).text();
$(value).empty();
$(value).append($('<option></option>')
.attr('value', current_selected_key)
.text(current_selected_val));
for (var index2 in new_list) {
"use strict";
$(value).append($('<option></option>')
.attr('value', index2)
.text(new_list[index2]));
};
});
}
// Alter content on change select boxes
jQuery(document).ready(function($) {
$(document).on('click', 'button', function(e) {
reset_abstract_list();
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="values-list">
<option value="0">Option one</option>
<option value="1">Option two</option>
<option value="2">Option three</option>
<option value="3">Option four</option>
</select>
<select class="values-list">
<option value="0">Option one</option>
<option value="1">Option two</option>
<option value="2">Option three</option>
<option value="3">Option four</option>
</select>
<select class="values-list">
<option value="0">Option one</option>
<option value="1">Option two</option>
<option value="2">Option three</option>
<option value="3">Option four</option>
</select>
<button>Ye olde button</button>
When you set your new_list to the default list, it's basically creating a reference to the original. You need to instead copy the values of the original list so they aren't coupled.
var new_list = window.initial_abstract_list.slice();
By doing var new_list = window.initial_abstract_list; you are only creating a reference to the original array. Any changes made to new_list will reflect in the initial array.
What you want to do is create a deep copy of the initial array, so as to get a different variable but with the same values. You can do this like so:
var new_list = jQuery.extend(true, {}, window.initial_abstract_list);

How to call onchange event when dropdown values are same

I am using Jquery chosen plugin and it's working fine. I have used this plugin in my one of the module. My dropdown values are something like that:
<select id="itemcode" onchange="get_data()">
<option value="1">ITEM001</option>
<option value="2">ITEM002</option>
<option value="1">ITEM001</option>
<option value="3">ITEM003</option>
</select>
It's working fine. But problem is that when user select first option and then try to change third option onchange event does not fire because both options values are same. Is there any way to call onchange event every time if values are same or differ ?
Options values is a unique key of item so it's repeated in dropdown. Dropdown value is duplicate we have allowed to use same item in others module
I saw your implementation and it is working fine in code pen here is the link no need to change anything
<select id="itemcode" onchange="get_data()">
<option value="1">ITEM001</option>
<option value="2">ITEM002</option>
<option value="1">ITEM001</option>
<option value="3">ITEM003</option>
</select>
var get_data =function(){
alert("saas")
}
http://codepen.io/vkvicky-vasudev/pen/dXXVzN
Try this
$('#itemcode').click(function() {
console.log($(this).val());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="itemcode">
<option value="1">ITEM001-A</option>
<option value="2">ITEM002</option>
<option value="1">ITEM001-B</option>
<option value="3">ITEM003</option>
</select>
Edit: This doesn't work. Sorry!
You could add a data attribute that differs for each element, for example:
<select id="itemcode" onchange="get_data()">
<option value="1" data-id="1">ITEM001</option>
<option value="2" data-id="2">ITEM002</option>
<option value="1" data-id="3">ITEM001</option>
<option value="3" data-id="4">ITEM003</option>
</select>
If you're using Rails or another framework to generate the <option> tags, it should be easy to add an incremental id to each element.
There is no way to fire get_data() with your current data.
The solution below is more of a hack. When you populate the options, prepend the value with something unique.
Eg.
<select id="itemcode" onchange="get_data()">
<option value="1_1">ITEM001</option>
<option value="2_2">ITEM002</option>
<option value="3_1">ITEM001</option>
<option value="4_3">ITEM003</option>
</select>
Thus your get_data() method will be called everytime. And in your get_data() method, split the value using underscore _ and you can get the actual value there.
function get_data(){
var actualValue=$(this).val().split("_")[1];
//do other processing
...
}
You can use other characters like $, or anything you like, instead of _
Ideally you want to change the data coming from the backend so that you don't get duplicate data. However if this is not possible, another approach would be to sanitise the data before putting it in the select. E.g
https://jsfiddle.net/vuks2bpt/
var dataFromBackend = [
{key:1,
value: "ITEM0001"
},
{key:2,
value: "ITEM0002"
},
{key:1,
value: "ITEM0001"
},
{key:3,
value: "ITEM0003"
}
];
function removeDuplicates(array){
var o = {};
array.forEach(function(item){
o[item.key] = item.value;
});
return o;
}
function get_data(){
console.log('get_data');
}
var sanitised = removeDuplicates(dataFromBackend);
var select = document.createElement('select');
select.id = "itemcode";
select.addEventListener('change', get_data);
Object.keys(sanitised).forEach(function(key){
var option = document.createElement('option');
option.value = key;
option.textContent = sanitised[key];
select.appendChild(option);
})
document.getElementById('container').appendChild(select);
i am using jquery instead of java script
<select id="itemcode">
<option value="1">ITEM001</option>
<option value="2">ITEM002</option>
<option value="1">ITEM001</option>
<option value="3">ITEM003</option>
</select>
jquery
$('#itemcode:option').on("click",function(){
alert(saaas);
})

Dynamically add options to option group at particular location

I have a small query. I would like to have a HTML select in my page having structure:
<select id="selectedFormulae">
<option value="0" disabled="" selected="">select</option>
<optgroup label="Box1">
<option value="1">Formula1</option>
<option value="2">Formula2</option>
</optgroup>
<optgroup label="Box2?">
<option value="1">Formula1</option>
<option value="2">Formula2</option>
<option value="3">Formula3</option>
</optgroup>
<optgroup label="Marital status?">
<option value="1">Formula1</option>
</optgroup>
</select>
The options of the select will be added as per what user adds in his computations. My question here is how do I add particular option under particular option group? ie. if user adds another value under box1 then new option should be added under <optgroup label="Box1"> like this:
<optgroup label="Box1">
<option value="1">Formula1</option>
<option value="2">Formula2</option>
<option value="3">Formula3</option>
</optgroup>
Same way if user deleted some value say Formula2 of Box1 then it will have only this:
<optgroup label="Box1">
<option value="1">Formula1</option>
<option value="3">Formula2</option>
</optgroup>
I was planning to save all the options in JSON object and then modifying the select html as per what user adds in. Any help with this?
I tried adding it to jsonobject like this:
var opt = {
Box1:[
{name:"Formula1"},
{name:"Formula2"}
],
Box2:[
{name:"Formula1"},
{name:"Formula2"}
],
Box3:[
{name:"Formula1"},
{name:"Formula2"}
]
};
Try this: you can use jQuery attribute selector to find a particular option group and append new option to it
$("#selectedFormulae").find('optgroup[label="Box1"]').append('<option>New option</option>');
Here option group with label="Box1" get selected and user can append new option to it, similarly, user can delete option using below code
$("#selectedFormulae").find('optgroup[label="Box1"]').find('option').filter(function(){
var text = $(this).text();
return text=='New option';
}).remove();
EDIT - to know if an option exists already, use below code
var $optionGroup = $("#selectedFormulae").find('optgroup[label="Box1"]');
var optionLength = $optionGroup.find('option').filter(function(){
return $(this).text() == "New option";
);
if(optionLength.length < 1) //option does not exist
{
$optionGroup.append('<option>New option</option>');
}
it can be achieve by your jsonobject :
var opt = {
Box1:[
{name:"Formula1"},
{name:"Formula2"}
],
Box2:[
{name:"Formula1"},
{name:"Formula2"}
],
Box3:[
{name:"Formula1"},
{name:"Formula2"}
]
};
$(function(){
var $select = $('#mySelect');
$.each(opt, function(key, value){
var group = $('<optgroup label="' + key + '" />');
$.each(value, function(){
$('<option />').html(this.name).appendTo(group);
});
group.appendTo($select);
});
});
here the fiddle http://jsfiddle.net/ZP4E9/29/

Fill second dropdown with the same value as the first dropdown

I have a dynamic number of dropdowns. When a value is selected in the first dropdown, the value of the second and so on dropdowns will be the same with the first dropdown. But the user has the option to change the value of the second and so on dropdowns, but not changing the first and other dropdown's value.
<select name="dropdown[]">
<option value="1">Sony</option>
<option value="2">Nintendo</option>
<option value="3">Microsoft</option>
</select>
<select name="dropdown[]">
<option value="1">Sony</option>
<option value="2">Nintendo</option>
<option value="3">Microsoft</option>
</select>
<select name="dropdown[]">
<option value="1">Sony</option>
<option value="2">Nintendo</option>
<option value="3">Microsoft</option>
</select>
How can I achieve this using javascript or jquery libraries?
You can attach a listener to the first select element:
var selects = document.querySelectorAll('select[name="dropdown[]"]');
selects[0].addEventListener('change', function () {
for (var i = 0; i < selects.length; i++) {
selects[i].value = selects[0].value;
}
});
When the value of only the first select changes, it updates the values of the other selects. This way does not rely on any 3rd-party libraries.
Demo: http://jsfiddle.net/cuefb9ag/
Use a change event and then alter the other dropdowns:
$("select[name=dropdown\\[\\]]").change(function() {
var value = this.value;
$("select[name=dropdown\\[\\]]").not(this).val(value);
});
Demo: http://jsfiddle.net/awv14f6r/1/
If you want to change them in order (first alters the second, etc) - use next along with this
$(this).next("select").val(value);
var id = $('#DropDownID1 option:selected').val();
var textValue = $('#DropDownID1 option:selected').text();
$('#DropDownID2').prop('selectedIndex', 0);
$('#DropDownID2').select2('data', {
val: id,
text: textValue
});
$('#DropDownID2 option:selected').val(id);
}

Categories