I've got the following select menu (jsFiddle):
<select>
<option value="volvo">Cars</option>
<option value="saab">------------</option>
<option value="volvo">Volvo</option>
<option value="saab">Saab</option>
<option value="mercedes">Mercedes</option>
<option value="audi">Audi</option>
</select>
Using Javascript, how would I re-sort the list alphabetically, excluding the first 2 options (Cars and -------), which must remain at the top? Thanks in advance for any help.
Being a purist, I would say that at no point was jQuery specifically mentioned or asked for, it may not be in use in this project for one reason or another. Here's an example using pure javascript.
function sortlist(){
var cl = document.getElementById('carlist');
var clTexts = new Array();
for(i = 2; i < cl.length; i++){
clTexts[i-2] =
cl.options[i].text.toUpperCase() + "," +
cl.options[i].text + "," +
cl.options[i].value + "," +
cl.options[i].selected;
}
clTexts.sort();
for(i = 2; i < cl.length; i++){
var parts = clTexts[i-2].split(',');
cl.options[i].text = parts[1];
cl.options[i].value = parts[2];
if(parts[3] == "true"){
cl.options[i].selected = true;
}else{
cl.options[i].selected = false;
}
}
}
sortlist();
http://jsfiddle.net/GAYvL/7/
Updated to be case neutral.
My first approach was similar to Koolinc's, using Array.prototype.slice to convert the <select> element's children NodeList to an array. However, this doesn't work in Internet Explorer 8 and lower so I changed it to extract, sort and then re-insert:
var sel = document.getElementsByTagName("select")[0],
opts = [];
// Extract the elements into an array
for (var i=sel.options.length-1; i >= 2; i--)
opts.push(sel.removeChild(sel.options[i]));
// Sort them
opts.sort(function (a, b) {
return a.innerHTML.localeCompare(b.innerHTML);
});
// Put them back into the <select>
while(opts.length)
sel.appendChild(opts.shift());
Working demo: http://jsfiddle.net/3YjNR/2/
This is just a more generic answser based on #Jeff Parker's one!
function sortSelect(select, startAt) {
if(typeof startAt === 'undefined') {
startAt = 0;
}
var texts = [];
for(var i = startAt; i < select.length; i++) {
texts[i] = [
select.options[i].text.toUpperCase(),
select.options[i].text,
select.options[i].value
].join('|');
}
texts.sort();
texts.forEach(function(text, index) {
var parts = text.split('|');
select.options[startAt + index].text = parts[1];
select.options[startAt + index].value = parts[2];
});
}
I have also created a fiddle; http://jsfiddle.net/4u86B/1/
I would start by giving a class name to all of the entries I want to sort, and giving and ID to the select:
<select id="sortableCars">
<option value="volvo">Cars</option>
<option class="sortMe" value="saab">------------</option>
<option class="sortMe" value="volvo">Volvo</option>
<option class="sortMe" value="saab">Saab</option>
<option class="sortMe" value="mercedes">Mercedes</option>
<option class="sortMe" value="audi">Audi</option>
</select>
as for the javascript
var mylist = $('#sortableCars');
var listitems = mylist.children('option.sortMe').get();
listitems.sort(function(a, b) {
var compA = $(a).text().toUpperCase();
var compB = $(b).text().toUpperCase();
return (compA < compB) ? -1 : (compA > compB) ? 1 : 0;
})
$.each(listitems, function(idx, itm) { mylist.append(itm); });
Related
with vanilla javascript I'd like to loop through my dropdown, and change the selected one, and then change the text that is displayed. I have it selecting, but I'm not getting the object name correct to change the optionText? of the item.
var textToFind = 'LdapUsers';
var dd = document.getElementById('membershipProvider');
for (var i = 0; i < dd.options.length; i++) {
if (dd.options[i].text === textToFind) {
dd.selectedIndex = i;
i.options.text = "Edgewood Login"; //This is WRONG
break;
}
}
guidance is appreciated.
You can use a querySelector and a selector to access it without a loop.
v = "222";
selProvider = document.querySelector("#membershipProvider option[value='" + v + "']");
if (selProvider) {
selProvider.text = "CHANGED!";
selProvider.selected = true;
}
<select id="membershipProvider">
<option value='111'>AAA</option>
<option value='222'>BBB</option>
</select>
You need to modify the option at that index. Right now you are trying to modify the index itself.
should be:
dd.options[i].text
not
i.options.text
var textToFind = 'LdapUsers';
var dd = document.getElementById('membershipProvider');
for (var i = 0; i < dd.options.length; i++) {
if (dd.options[i].text === textToFind) {
dd.selectedIndex = i;
dd.options[i].text = "Edgewood Login"; //This is WRONG
break;
}
}
<select id="membershipProvider">
<option value="cifs">CIFS</option>
<option value="LdapUsers">LdapUsers</option>
<option value="nfs">NFS</option>
<option value="test">Test</option>
</select>
You should use
dd.options[i].text = "Edgewood Login";
just like when checking for its value
I have a project where I need to set the select options in alphabetical order. Here's my HTML code:
<select id=”carmakes”>
<option value="Volvo">Volvo</option>
<option value="Mercedes">Mercedes</option>
<option value="Audi">Audi</option>
<option value="Saab">Saab</option>
</select>
And here is my script:
function alphabeticalOrder() {
let value = document.getElementsByTagName("select")[0];
for (let i = 0; i < value.children.length - 1; i++) {
if (value.children[i].innerHTML < value.children[i + 1].innerHTML) {
let temp = value.children[i].innerHTML;
value.children[i].innerHTML = value.children[i + 1].innerHTML;
value.children[i + 1].innerHTML = temp;
}
}
return value;
}
I've tried using sort but I couldn't seem to get it to work.
As scunliffe mentioned, it's best to start with the values in JS rather than in HTML in this case. Try this:
const makes = [
'Volvo',
'Mercedes',
'Audi',
'Saab'
];
const sortedMakes = makes.sort((a,b) => {
if (a === b)
return 0;
if (a < b)
return -1;
return 1;
});
const selectEl = document.getElementById('carmakes');
for(const make of sortedMakes) {
const newOpt = document.createElement('option');
newOpt.value = make;
newOpt.innerHTML = make;
selectEl.appendChild(newOpt);
}
<select id="carmakes"></select>
If you must sort it with the values starting in HTML, you can do it like this:
const selectEl = document.getElementById('carmakes');
const makes = Array.from(selectEl.getElementsByTagName('option'))
.map(el => el.innerText);
const sortedMakes = makes.sort((a,b) => {
if (a === b)
return 0;
if (a < b)
return -1;
return 1;
});
while(selectEl.firstChild) {
selectEl.firstChild.remove();
}
for(const make of sortedMakes) {
const newOpt = document.createElement('option');
newOpt.value = make;
newOpt.innerHTML = make;
selectEl.appendChild(newOpt);
}
<select id="carmakes">
<option value="Volvo">Volvo</option>
<option value="Mercedes">Mercedes</option>
<option value="Audi">Audi</option>
<option value="Saab">Saab</option>
</select>
I have a function which will return max value for me. In my view I have select list which i want to show options from 1 - maxvalue . How can I implement this
thanks
function getmatch_value(){
for (i=1;i<=7;i++){
var left = $('#lc'+i).val();
var right = $('#rc'+i).val();
if(isblank(left) || isblank(right) ){
var maxval = i-1;
return maxval;
break;
}
}
}
and i my view I have
<select id="match_ans2" name="mathRowAnswer[]" class="select" style="width: 150px;">
<option value='0'>Select Answer</option>
I want options based on my getmatch_value() so that if It will return 3 to me then the options list automatically have 1 2 and 3 options
var selectList = document.getElementById('match_ans2');
for (var i = 1; i <= getmatch_value(); i++) {
var opt = document.createElement('option');
opt.value = i;
opt.appendChild(document.createTextNode(i.toString()));
selectList.appendChild(opt);
}
I have a select dropdownlist with 1 item selected at page load in html.
<select name = "options">
<option value = "1">Item1</option>
<option value = "2" selected>Item2</option>
<option value = "3">Item3</option>
<option value = "4">Item4</option>
</select>
Now I want to capture new select option when user press shift and select another option such as "Item 3".
I have the following code to find all the selections in the list
var value = "";
for (var intLoop = 0; intLoop < Form.elements[index].length; intLoop++) {
if(Form.elements[index][intLoop].selected )
value = value + Form.elements[index][intLoop].value;
}
I can see the "Item 2" and "Item 3" are selected but i want to get capture "Item 3" only. Is it possible?
Here's code that will tell you what has been selected and what has been deselected http://jsfiddle.net/8dWzB/
It uses Array.prototype.indexOf, and it's not the fastest way to do it. But it should get you going in the right direction.
HTML
<select id="options" multiple="multiple">
<option value = "1">Item1</option>
<option value = "2" selected>Item2</option>
<option value = "3">Item3</option>
<option value = "4">Item4</option>
</select>
JS
function getSelectedIndexes(select) {
var selected = [];
for (var i = 0; i < select.options.length; i++) {
if(select.options[i].selected ) {
selected.push(i);
}
}
return selected;
}
var select = document.getElementById("options");
var prevSelected = getSelectedIndexes(select);
select.onchange = function(e) {
var currentlySelected = getSelectedIndexes(this);
for (var i =0; i < currentlySelected.length; i++) {
if (prevSelected.indexOf(currentlySelected[i]) == -1) {
console.log("Added to selection ", this.options[currentlySelected[i]].text);
}
}
for (var i =0; i < prevSelected.length; i++) {
if (currentlySelected.indexOf(prevSelected[i]) == -1) {
console.log("Removed from selection ", this.options[prevSelected[i]].text);
}
}
prevSelected = currentlySelected;
};
If you really only want to know which item was last clicked, you can use the following code. I'll use jQuery so I can easily set a handler on all the option objects. Remember this won't work if you change the selection with the keyboard
$('option').click(function(e){
var parentNode = this.parentNode;
for (var i=0; i < this.parentNode.options.length; i++) {
if (parentNode.options[i] == this) {
console.log('Clicked item with index', i);
break;
}
}
});
You could check the value of the selected options before a change event (e.g. item 1 and 2 are selected) and then again after the event (e.g. item 1, 2 and 3 are selected), and compare the difference.
Here is an example.
Fiddle here: http://jsfiddle.net/FnAuz/4/
I modified your select to allow multiple selections since I take it that's the crux of the problem.
HTML:
<form id="my-form">
<select name = "options" id="options" multiple>
<option value = "val1">Item1</option>
<option value = "val2">Item2</option>
<option value = "val3">Item3</option>
<option value = "val4">Item4</option>
</select>
</form>
JS:
var oldValue = "";
document.getElementById('options').onchange = function() {
var myForm = document.getElementById ('my-form');
var value = "";
for (var intLoop = 0; intLoop < myForm.elements[0].length; intLoop++) {
if(myForm.elements[0][intLoop].selected) {
value = value + myForm.elements[0][intLoop].value;
}
}
for (var intLoop = 0; intLoop < myForm.elements[0].length; intLoop++) {
var optionVal = myForm.elements[0][intLoop].value;
if(myForm.elements[0][intLoop].selected && value.indexOf(optionVal) !== -1 && oldValue.indexOf(optionVal) === -1) {
console.log('Last clicked was ' + myForm.elements[0][intLoop].value)
}
}
oldValue = value;
};
EDIT: I just noticed that my example works when the user makes command/ctrl selections, but if they make a shift selection then ALL the new values will be counted as the 'last clicked item'. So my code would need some work to account for this scenario. I'm out of time, but hopefully my code is useful in its current state nevertheless!
Try this :
var e = document.getElementById("ID_of_Select_Element");
var _selectedValue= e.options[e.selectedIndex].value;
It started looking messy so I'm posting it as an answer:
<html>
<head>
<script type="text/javascript">
<!--
var value = '0';
document.getElementById('options').onchange = function() {
value = parseInt(value) + parseInt(this.value);
alert(value);
}
-->
</script>
</head>
<body>
<select name="options" id="options">
<option value = "1">Item1</option>
<option value = "2" selected>Item2</option>
<option value = "4">Item3</option>
<option value = "8">Item4</option>
</select>
</body>
</html>
Edition for selecting multiple items:
well, if you want to accumulate items you can assign binary IDs to each product and then you can extract all the selected products from the total. for example, if the total is: 7 you can easily translate it to a binary string "111" which means they selected items 1,2,4. Sounds a bit crazy, I know, just an idea ;)
I have a couple select elements:
<select name="empID" onchange='setSupervisor(this);'>
<option value="111" sid="222">Eric Employee</option>
...
</select>
<select name="supervisorID">
<option value="333">Susie Supervisor</option>
<option value="222">Stan Supervisor</option>
</select>
And a javascript function:
function setSupervisor(sender)
{
??
}
How can I set the supervisor dropdown after the user selects from the employee dropdown? The tricky part here (at least to me) is having to use a custom sid and not the value from the employee dropdown.
function setSupervisor(sender) {
var selectedOption = sender.getElementsByTagName("option")[sender.selectedIndex];
var sid = selectedOption.getAttribute("sid");
var supervisorSelect = document.getElementsByName("supervisorID")[0];
for (var i = 0, len = supervisorSelect.options.length, option; i < len; ++i) {
option = supervisorSelect.options[i];
if (option.value == sid) {
option.selected = true;
return;
}
}
}
Try this:
var empID = document.getElementsByName("empID").item(0);
var supervisorID = document.getElementsByName("supervisorID").item(0); //This becomes a bit easier if you set an ID as well as a name in your HTML
var index = empID.selectedIndex;
var sid = empID.options[index].getAttribute("sid");
for(var i=0; i<supervisorID.options.length; i++)
{
if(supervisorID.options[i].value == sid)
{
supervisorID.selectedIndex = i;
break;
}
}