How to manage order of select options on event change - javascript

I am trying to get items when selected by user to an array with onchange action, The problem is when user select lower option according to the arrangement it does not record the higher options when selected, but rather it retain the value of the lower option untill you select an lower option if it exists.
<select name="tasks[]" id="activities" multiple="multiple" onchange="getSeleted()">
<option value="1">lifting</option>
<option value="2">jogging</option>
<option value="3">sleeping</option>
<option value="4">working</option>
<option value="5">praying</option>
</select>
</script>
var myarr = [];
function getSeleted(){
var activityValue =document.getElementById('activities').value;
myarr.push(activityValue);
console.log(myarr);
}
</script>
Whenever I select lower option it stuck with that option untill you select another lower.
e.g if you select option 1, and then 2, and then 3 the console prints.
//1,2 and 3
console ['1',]
console ['1','1']
console ['1','1','1']
//3,2 and 1
console ['3',]
console ['3','2']
console ['3','2','1']
//3,4 and 4
console ['3']
console ['3','3']
console ['3','3','3']
//5,2 and 4
console ['5']
console ['5','2']
console ['5','2','2']
It acts the same even with string, Why does it behave like this, and how can I handle it.

Why not make things little bit easier with filter and map.
Example:
function getSeleted() {
var select = document.getElementById('activities');
var selected = [...select.options]
.filter(option => option.selected)
.map(option => option.value);
console.log(selected);
}
<select name="tasks[]" id="activities" multiple="multiple" onchange="getSeleted()">
<option value="1">lifting</option>
<option value="2">jogging</option>
<option value="3">sleeping</option>
<option value="4">working</option>
<option value="5">praying</option>
</select>

Related

Javascript Div onchange Grab Values from Two Select Boxes

I'm trying to make it so when a select box within a div changes, it will grab values from both that select box and one other one that I've yet to add, but I don't know how to go about it.
I currently have this code
<select id='selMag' onchange='getSelMag(this)'>
<option value='0.0>Select Minimum Magnitude</option>
<option value='1.0'>1.0</option>
<option value='2.0'>2.0</option>
<option value='3.0'>3.0</option>
<option value='4.0'>4.0</option>
<option value='5.0'>5.0</option>
<option value='6.0'>6.0</option>
<option value='7.0'>7.0</option>
<option value='8.0'>8.0</option>
<option value='9.0'>9.0</option>
<option value='10.0'>10.0</option>
</select>
function getSelMag(sel) {
value = Number(sel.value);
console.log(window.value);
}
This, as it is right now, works fine from grabbing it from the , but I would like to add another one and put them inside a container div, and make it so when either one changes it will grab the values from both of them, add both strings together, and convert them into a number. I plan to make it so the select box above will not have the decimal values and just be 1, 2, etc. and have the second box be .1, .2, etc. so when they are added together, it will show 1.1, 1.2, etc.
Presumably, the select is in a form. To be successful, form controls must have a name, so:
<select id='selMag' name='selMag' onchange='getSelMag(this)'>
Adding a name nearly always obviates the requirement for an ID. If the other select also has a name:
<select name='selMag2'>
and it belongs to the same form as the first, you can reference it from the getSelMag function via the form:
function getSelMag(sel) {
// Always declare variables
var value = Number(sel.value);
// Access them from the appropriate scope
console.log(value);
// Reference the other select using named properties of the form
var otherSelect = sel.form.selMag2;
// Do stuff with it
var otherValue = otherSelect.value;
}
Note that all form controls have a form property that references their parent form, and that the controls belonging to a form can be accessed via the form's elements collection.
Those with names (and in some browsers those with IDs) can be accessed as named properties of the form and of the elements collection, and also by index in the collection.
It seems that you want to concatenate the values with a period between, so the function might look like:
function getSelMag(sel) {
var value0 = sel.form.selMag.value;
var value1 = sel.form.selMag2.value;
console.log(value0 + '.' + value1);
}
and the HTML:
<form>
<select name="selMag" onchange="getSelMag(this);">
<option value="0" selected>0
<option value="1">1
<option value="2">2
</select>
<select name="selMag2" onchange="getSelMag(this);">
<option value="0" selected>0
<option value="1">1
<option value="2">2
</select>
</form>
Use the answer from this link to get the value of other select box in getSelMag() function
Get selected value in dropdown list using JavaScript?
as follows:
function getSelMag(sel) {
value = Number(sel.value);
console.log(window.value);
var e = document.getElementById("selMag2");
var option2 = e.options[e.selectedIndex].text;
//do whatever u want
}
You can make another function say x() that will be called for other select box you make and access the value of first select box from that
<select id='selMag2' onchange='x(this)'>
as
function getSelMag2(sel) {
value = Number(sel.value);
console.log(window.value);
var e = document.getElementById("selMag");
var option1 = e.options[e.selectedIndex].text;
//do whatever u want
}
Hope this helps

jQuery option appendTo select moves to next option instead of select one

http://jsfiddle.net/j3oh6s3a/
For some reason appending options to a select tag doesn't select the selected='selected' attribute option, instead selects the next option in the list.
Please see the above jfiddle.
<select id="category">
<option value='1'>Categroy 1</option>
<option value='2'>Categroy 2</option>
<option value='3'>Categroy 3</option>
</select>
<select id="sub-category">
<option value='1' data-parentid='1'>Car1</option>
<option value='2' data-parentid='1'>Car2</option>
<option selected='selected' value='3' data-parentid='1'>Car3</option>
<option value='4' data-parentid='1'>Car4</option>
<option value='5' data-parentid='1'>Car5</option>
<option value='6' data-parentid='2'>Car6</option>
<option value='7' data-parentid='2'>Car7</option>
<option value='8' data-parentid='2'>Car8</option>
<option value='9' data-parentid='3'>Car9</option>
<option value='10' data-parentid='3'>Car10</option>
<option value='11' data-parentid='3'>Car11</option>
<option value='12' data-parentid='3'>Car12</option>
</select>
$(document).ready(function(){
var allsuboptions = $('#sub-category option').remove();
var selectedOptions = allsuboptions.filter(function () {
return $(this).data('parentid').toString() === $('#category').val().toString();
});
selectedOptions.appendTo('#sub-category');
});
In the above example Car3 should be selected, but Car4 is selected after appending options to the select.
This is a tricky (and interesting) question.
If you test the fiddle on different browsers you'll see that the selected value changes: Chrome (Car4), IE (Car3), Firefox (Car5). So I have made a slight change to your fiddle to "prove a theory". You can see the changes on this link: http://jsfiddle.net/j3oh6s3a/1/. I only added a log to the filter loop so I can see the selected element in each iteration:
if ($(this).is(":selected")) { console.log("Selected value = " + $(this).val()) };
Now this is what happens (or at least my theory): Once the selected element is removed from the list each browser will proceed however thinks adequate to determine the selected option. And in this case each browser will proceed in a different way:
As the selected option has been removed, Chrome will select automatically (by default) the first option of the remaining in the list (Car4). When this option is sent to the new list, it is automatically selected as it is newer than the previous selected option. The log is: 3, 4.
Internet Explorer does nothing, and copies each element the same way they are without caring about if they are selected or not. The original selected value will be the final selected value (Car3). The log is: 3.
Firefox will proceed like Chrome, but every time that the selected element is removed from the list, the first option of the remaining ones will be selected. The log is: 3, 4, 5, 6, 7, 8, 9, 10, 11, 12; but as the last option inserted in the list is 5, it will be the selected one.
I will check later to see if I can find any information to source this, but it will have to be tomorrow as it's a bit late here.
jQuery .remove and .append internally uses .removeChild and .appendChild methods to remove/insert the child elements.
Theory: removeChild/appendChild maintains the attributes but doesn't maintain the element's property (maintaining the selection state)
When you use removeChild and then appendChild to add the options back, the attributes are maintained, but the property of the element are not maintained. You can read more about .prop() vs .attr() here.
In summary, attributes are initial values defined in the HTML that are parsed to set as properties to the Element by the browser, however setting the attributes doesn't guarantee setting the property.
$(function() {
var categoryDD = document.getElementById('category');
var removedOptions = remove.call(categoryDD.options);
add.call(categoryDD, removedOptions);
});
function add(options) { //add all options
for (var i = 0; i < options.length; i++) {
this.appendChild(options[i]);
}
}
function remove() { //removes all options
var el, returnOpt = [];
while (this.length) {
el = this[0];
returnOpt.push(el.parentNode.removeChild(el));
}
return returnOpt;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id="category">
<option value='1'>Categroy 1</option>
<option value='2' selected="selected">Categroy 2</option>
<option value='3'>Categroy 3</option>
<option value='4'>Categroy 4</option>
<option value='5'>Categroy 5</option>
<option value='6'>Categroy 6</option>
</select>
Testing Results:
On testing the above snippet, IE 10 and FF yielded me the same result which is selecting the last option from the drop down, however chrome seems to be bugged as it always selected the next option from the original selection. The results from IE 10 and FF made a little sense as to "Not maintaining the state", however Chrome behavior seems like a bug.
Above is my theory based on my test case, however I couldn't find a legit reference that states the same.
Anyways, tryout below solutions for a consistent output.
Solution 1: Remove only options that are NOT equal to parentId.
$('#sub-category option').filter(function () {
return $(this).data('parentid').toString() !== $('#category').val().toString();
}).remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<select id="category">
<option value='1'>Categroy 1</option>
<option value='2'>Categroy 2</option>
<option value='3'>Categroy 3</option>
</select>
<select id="sub-category">
<option value='1' data-parentid='1'>Car1</option>
<option value='2' data-parentid='1'>Car2</option>
<option selected='selected' value='3' data-parentid='1'>Car3</option>
<option value='4' data-parentid='1'>Car4</option>
<option value='5' data-parentid='1'>Car5</option>
<option value='6' data-parentid='2'>Car6</option>
<option value='7' data-parentid='2'>Car7</option>
<option value='8' data-parentid='2'>Car8</option>
<option value='9' data-parentid='3'>Car9</option>
<option value='10' data-parentid='3'>Car10</option>
<option value='11' data-parentid='3'>Car11</option>
<option value='12' data-parentid='3'>Car12</option>
</select>
Solution 2: [based on your original answer] The solution is simple, just get the select value before removing the options and set the selection after using .append.
var $subcategory = $('#sub-category');
var selectedOption = $subcategory.val();
var allsuboptions = $subcategory.find('option').remove();
var selectedOptions = allsuboptions.filter(function() {
return $(this).data('parentid').toString() === $('#category').val().toString();
});
selectedOptions.appendTo('#sub-category');
$subcategory.val(selectedOption);
<select id="category">
<option value='1'>Categroy 1</option>
<option value='2'>Categroy 2</option>
<option value='3'>Categroy 3</option>
</select>
<select id="sub-category">
<option value='1' data-parentid='1'>Car1</option>
<option value='2' data-parentid='1'>Car2</option>
<option selected='selected' value='3' data-parentid='1'>Car3</option>
<option value='4' data-parentid='1'>Car4</option>
<option value='5' data-parentid='1'>Car5</option>
<option value='6' data-parentid='2'>Car6</option>
<option value='7' data-parentid='2'>Car7</option>
<option value='8' data-parentid='2'>Car8</option>
<option value='9' data-parentid='3'>Car9</option>
<option value='10' data-parentid='3'>Car10</option>
<option value='11' data-parentid='3'>Car11</option>
<option value='12' data-parentid='3'>Car12</option>
</select>
What you're not seeing is the difference between the "selected" property and the "selected" attribute.
If you put this at the end of your code you can see it:
// Attribute
console.log( $("#sub-category").find("[selected]").val() );
// Property
console.log( $("#sub-category").find(":selected").val() );
Your option with value "3" has the selected attribute, but not the property, it's the opposite for the option with value "4".
Whenever you add options inside a select, you must re-select the desired one:
$("#sub-category").find("[selected]").prop("selected", true);
Firefox selects the last element. This behavior is probably correct and explainable. In order to understand, please keep the following in mind:
jQuery append and remove methods process the elements one by one behind the scene.
The current state of an input element should be retrieved or set using the corresponding property, not attribute.
Expected Behavior (Firefox)
Removing all options from a select element as demonstrated in your example works as follows:
Car1 is removed (Car3 remains selected)
Car2 is removed (Car3 remains selected)
Car3 is removed. Since this is the selected element, removing it will cause the next element to become selected
Car4 is removed. Since this is the selected element, removing it will cause the next element to become selected
This will repeat until all options are moved from DOM to the memory. At this point the options will have the following properties:
// allsuboptions.each(function() { console.log(this.value, this.selected); });
value: 1, selected: false
value: 2, selected: false
value: 3, selected: true
value: 4, selected: true
...
value: 12, selected: true
There are 3 options with selected = true. When you add the options back to the select element, the browser sets the last selected element as the selected one.
Internet Explorer and Chrome
While the options are removed one by one, these two browsers do not update the selected element immediately (they possibly wait for JavaScript execution to finish). This causes the following discrepancies:
Internet Explorer does not immediately make the next option selected when currently selected option is removed. Therefore the removed options contain only one selected element.
Chrome seems to immediately make the next option selected when currently selected option is removed, but it does that only once. Therefore the removed options contain two selected elements.
In order to prove the point about immediate and deferred updates, here is a Fiddle containing:
The original code
A variation that forces the browser to update the select element each time an option is removed
http://jsfiddle.net/salman/j3oh6s3a/9/
Solution
As suggested in other answers, the correct workaround is to use a variable that references the currently selected option before removing the options. Something like:
var $selectedOption = $("#sub-category option").filter(function() {
return this.selected;
});
Once the options are re-inserted, you can check if that element was added back and select it again:
if ($selectedOption.parent().length) {
$selectedOption.prop("selected", true);
}
// or
$("#sub-category option").filter($selectedOption).prop("selected", true);
Your script is doing what you created it to do.
The reason car4 is selected, is because
<option selected='selected' value='3' data-parentid='1'>Car3</option>
is initially selected, then you are appending parentid='1' to the value which causes car4 to be the new selection.
What is the purpose of this script?

Get value of input, only after select option change has happened

I have a <"select'>, with some options and onChange listerner. When an option is selected certain values are set in some hidden fields. So if this change event won't happen, it means the values of those fields will remain in their initial state i.e 0.
What I want to achieve is that, only when an onchange has happened, that means hidden fields values has been set, I get the values from those hidden fields and perform some ajax with the data
This is what I have so far:
<select class="form-control choosedegree" name="sem" id="semester">
<option value="" selected="selected" disabled>Select Semester</option>
<option value="1">Year 1, Semester 1</option>
<option value="2">Year 1, Semester 2</option>
<option value="3">Year 2, Semester 1</option>
</select>
After this has fired, and finished,
$('select#semester').on('change', function(){});
then find some hidden input and set the new value gotten as a result of the onChange.
$('div.tab-content div.tab-pane.active form').find('input[type=hidden]').val()
How can i achieve that! Any kind of help is highly appreciated.
do like this:
$('select#semester').on('change', function(){
if($(this).val() != "")
{
// send ajax call here
setTimeout(SendAjaxCall,3000); // execute SendAjaxCall after 3 secs
}
});
function SendAjaxCall()
{
var val = $('div.tab-content div.tab-pane.active form').find('input[type=hidden]').val();
}

Jquery/ javascript : Select all the selected values from drop down

Select box
<select id="update-select" multiple="multiple">
<option value="3">Test1 </option>
<option value="4">Test2 </option>
<option value="5">Test3 /option>
<option value="6">Test4</option>
<option value="15">Test5</option>
</select>
I am selecting the options from another jquery click function based on some manipulation .
(say i have selected values 3 and 4)
later i want to see the values of selected option
i tried,
selectedVals = $("#update-select option:selected").val() ;
alert(selectedVals) // alerts 3
it shows only the first value selected.
Any suggestion?
this should do
selectedVals = $("#update-select").val() ;
You should use:
$("#update-select option:selected").each(function(i,elem){
alert($(elem).val());
});
Here's an example: http://jsfiddle.net/5jNWY/
Hope this helps!

Obtain the number of the item in an options menu?

I'm using .val() in jQuery to retain the value of an options menu onChange.
How would I retain the number (as in as it is ordered) of the item in the drop down using jQuery?
<select>
<option> //option 1
<option> //option 2
</select>
Here is what I have set up now:
<select id="start_month" onChange="getMonthDay()">
<option>Jan</option>
<option>Feb</option>
<option>March</option>
<option>April</option>
<select>
Using,
function getMonthDay()
{
$('#start_month').val()
}
I can get whatever value is selected, but my question is how do I get the Number down of this value in the markup? For March, I would want 3.. and so on
Can you reformulate your question better? I'm still lost in what do you want.
But, nevertheless here is how <select> works in jQuery
<select id="selection">
<option value="val_1">value 1</option>
<option value="val_2">value 2</option>
</select>
$("#selection").val() will give you val_1 or val_2 depending on witch item is currently selected.
If you want to go through all options and check the selected on, you can use
$("#selection option:selected").val();
or itenerate through all <option>'s
$("#selection option").each(function() {
if( $(this).is(":selected") ) {
var v = $(this).val();
}
});
If you want to retain all options you can easily clone them or assign them as data, if you want to keep those values throughout the pages, use Local Database or Cookies to persist the data.
To answer your question after your update:
First: Why don't you have:
<select id="start_month" onChange="getMonthDay()">
<option value="1">Jan</option>
<option value="2">Feb</option>
<option value="3">March</option>
<option value="4">April</option>
<select>
And use the value of the selected item?
Second: Just use what I wrote above and itenerate through the options
$("#start_month option").each(function(index, element) {
if( $(this).is(":selected") ) {
// get index position, remember to add 1 as arrays start at 0
var n = index;
// break each
return false;
}
});
You'd get a list of the <option> elements, find the selected one, and use index:
var $opts = $('#start_month option');
var zero_based_index = $opts.index($opts.filter(':selected'));
Demo: http://jsfiddle.net/ambiguous/HyukW/
Just add 1 if you want a one-based index.
I made something like this,with zero based key ;
<select id='deneme'>
<option>Val1</option>
<option>Val2</option>
<option>Val3</option>
<option>Val4</option>
</select>
$('#deneme').change(function(){
$.each( $('#deneme').children('option'),function(key,value){
if($(this).is(':selected'))
alert(key)
})
})
u can check from here http://jsfiddle.net/8JZCw/
No need for any iteration here, let jQuery do that for you, just get the selected index and increment...
$('#start_month option:selected').index() + 1

Categories

Resources