JS - apply global function to all select boxes - javascript

I have 200+ select boxes, each individually named and with Yes / No / NA as answer options, and now would like to have the background of the <option value="No> option highlighted in red once it is selected.
This works fine via the onchange attribute when adding it to the specific select box, however since I have 200 of those, I do not want to apply this code one by one, but rather apply a global JS function to all <select> boxes, which is where I am stuck. How can I address all select boxes with one JS function?
Javascript:
$('select').on('change', function () {
$(this).focus();
$(this).select();
$(this).className = this.options[this.selectedIndex].className;
});
CSS:
.green{ background-color:green; }
.red{ background-color:red; }
HTML:
<select id="boh_corridor" name="boh_corridor">
<option value=""></option>
<option value="Yes" class="green">Yes</option>
<option value="No" class="red">No</option>
</select>
EDIT: to be exact, the problem is that the option is not highlighted in either red or green at the moment, hence I am suspecting that the function is not being applied. The goal is to have the option highlighted in red/green when selected and while being selected from the dropdown menu.

Two things:
jQuery objects don't have a className property; DOM elements do. Instead of
$(this).className = ...
use
this.className = ...
Your code hooks the change event on select elements that exist as of when that code runs. So you need to be sure they exist prior to running that code. You can do that by ensuring your script tag is at the end of the document, just prior to the closing </body> tag; or by using jQuery's ready callback. Alternately, you can use event delegation (covered later).
Example expecting that the script tag will be at the end of the document (which is where Stack Snippets put it), which is best practice:
$('select').on('change', function() {
$(this).focus();
$(this).select();
this.className = this.options[this.selectedIndex].className;
});
.green {
background-color: green;
}
.red {
background-color: red;
}
<select id="boh_corridor" name="boh_corridor">
<option value=""></option>
<option value="Yes" class="green">Yes</option>
<option value="No" class="red">No</option>
</select>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
If you don't control where your script tags go or prefer to do something else, using jQuery's ready:
$(document).ready(function() {
// ...the code here...
});
Another option is event delegation. Although change doesn't natively bubble, jQuery makes it bubble, and so you can do this:
$(document).on("change", "select", function() {
$(this).focus();
$(this).select();
this.className = this.options[this.selectedIndex].className;
});
Then it doesn't matter whether the select elements exist or not when you run that code; the event handler is on document, not the individual selects. So it doesn't matter where the script tag is, and you don't need ready.
Example:
$(document).on('change', 'select', function() {
$(this).focus();
$(this).select();
this.className = this.options[this.selectedIndex].className;
});
.green {
background-color: green;
}
.red {
background-color: red;
}
<select id="boh_corridor" name="boh_corridor">
<option value=""></option>
<option value="Yes" class="green">Yes</option>
<option value="No" class="red">No</option>
</select>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Side note: You can use chaining with jQuery objects, rather than repeatedly calling $(): $(this).focus().select();

Do you have a common class for those select boxes? If you do, you can select them doing this:
$(".your_class").on("change", function(){
$(this).addClass("border_red"); //add border to select
$("option",this).removeClass("red"); //clear classes
$("option:selected", this).addClass("red"); //add .red class
});
Check out the fiddle: https://jsfiddle.net/m5mzwyt2/

The code below works for me, both in the sense of highlighting the option value in green / red, and to keep the background color once the option has been selected
JS:
$(document).ready(function() {
$('select').on('change', function () {
$(this).focus();
$(this).select();
this.className = this.options[this.selectedIndex].className;
});
});

I'm not sure what exactly you want to achieve.
I changed your code to:
$('select').on('change', function () {
$(this).focus();
$(this).select();
$(this).css("background-color",$(this).find(":selected").attr("class"));
});
It sets the background color after select based on class name.
Tested on Firefox

Related

How to trigger a <select> to expand (like it does after a mouse click) [duplicate]

How can you programmatically tell an HTML select to drop down (for example, due to mouseover)?
This used to actually be possible with HTML+Javascript, despite everywhere else people say it is not, but it was deprecated later on and does not work now.
However, this only worked in Chrome. Read more if you're interested.
According to W3C Working Draft for HTML5, Section 3.2.5.1.7. Interactive Content:
Certain elements in HTML have an activation behavior, which means that the user can activate them. This triggers a sequence of events dependent on the activation mechanism [...] for instance using keyboard or voice input, or through mouse clicks.
When the user triggers an element with a defined activation behavior in a manner other than clicking it, the default action of the interaction event must be to run synthetic click activation steps on the element.
<select> being an Interactive Content, I believed that it is possible to programatically display its <option>s. After a few hours of playing around, I discovered that using document.createEvent() and .dispatchEvent() works.
That said, demo time. Here is a working Fiddle.
// <select> element displays its options on mousedown, not click.
showDropdown = function(element) {
var event;
event = document.createEvent('MouseEvents');
event.initMouseEvent('mousedown', true, true, window);
element.dispatchEvent(event);
};
// This isn't magic.
window.runThis = function() {
var dropdown = document.getElementById('dropdown');
showDropdown(dropdown);
};
<select id="dropdown">
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" onclick="runThis()">Show dropdown items</button>​
If anyone finds a way to do the same but not in Chrome, please feel free to modify this fiddle.
​
Xavier Ho's answer is covering how to solve the issue in most browsers currently out there. But, it's good practice 'not to dispatch/modify' events by JavaScript anymore. (Like, mousedown in this case)
From version 53+, Google Chrome will not perform default action for un-trusted events. Such as events created or modified by script, or dispatched via dispatchEvent method. This change is for aligning with Firefox and IE which I think already not performing the action.
For testing purposes, Fiddle provided Xavier's answer won't work in chrome 53+. (I don't test it FF and IE).
Links for reference:
https://www.chromestatus.com/features/5718803933560832
https://www.chromestatus.com/features/6461137440735232
And initMouseEvent is also deprecated
This is the closest I could get, change the size of the element onmouseover, and restore the size onmouseout:
<select onMouseOut="this.size=1;" onMouseOver="this.size=this.length;">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
I have this same problem and the easier way I found to solve this was with HTML and CSS.
First, make you <select> transparent (opacity: 0;). Then, place your button over the <select>. The click over the button will be caught by the <select> component.
select{
opacity: 0;
position: absolute;
}
select:hover~button {
background: orange;
}
div * {
width: 100px;
}
<div>
<select>
<option>option 1</option>
<option>option 2</option>
<option>option 3</option>
</select>
<button>click</button>
</div>
You can't do this with a HTML select tag, but you can do it with JavaScript and HTML. There are variety of existing controls that do this - for instance, the "suggest" list attached to the SO "interesting/ignored tag" entry, or Gmail's lookup for email adresses.
There are many JavaScript+HTML controls that provide this capability--look for autocomplete controls for ideas.
See this link for the Autocomplete control...http://ajaxcontroltoolkit.codeplex.com/
I think this is no longer possible in Chrome.
It seems version 53 of chrome disables this functionality as stated by Asim K T.
According to the spec
http://www.w3.org/TR/DOM-Level-3-Events/#trusted-events
Trusted Events should not fire the default action (except click
event).
They have however enabled it in webview, but I have not tested this.
We have found that some webviews are using fastclick inside them and
due to a risk of breakage we are going to allow mousedown on selects
even if they are untrusted.
And in this discussion the idea to let developers open a dropdown programatically is abandoned.
If any one is still looking for this :
<select id="dropdown">
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select>
<br>
<button id="fire" type="button" >Show dropdown items</button>
Javascript:
var is_visible=false;
$(document).ready(function(){
$('#fire').click(function (e) {
var element = document.getElementById('dropdown');
if(is_visible){is_visible=false; return;}
is_visible = true;
var event;
event = document.createEvent('MouseEvents');
event.initMouseEvent('mousedown', true, true, window);
element.dispatchEvent(event);
/* can be added for i.e. compatiblity.
optionsSelect.focus();
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.SendKeys("%{DOWN}");
*/
e.stopPropagation();
return false;
});
$(document).click(function(){is_visible=false; });
});
Update:
One till there is no perfect solution to this problem, But you can try to avoid this scenario. Why do you want to do this. i was wondering for a solution few months back to make a select plugin for mobile devices
https://github.com/HemantNegi/jquery.sumoselect
Finally ended up with masking the custom div (or any other element) with a transparent select element, so that it can directly interacts with user.
Here's the best way I found. NOTE It only works with IE on Windows and your web would probably need to be in a secure zone - because we access the shell. The trick is that ALT-Down Arrow is a shortcut key to open a select drop down.
<button id="optionsButton" style="position:absolute;top:10px;left:10px;height:22px;width:100px;z-index:10" onclick="doClick()">OPTIONS</button>
<select id="optionsSelect" style="position:absolute;top:10px;left:10px;height:20px;width:100px;z-index:9">
<option>ABC</option>
<option>DEF</option>
<option>GHI</option>
<option>JKL</option>
</select>
<script type="text/javascript">
function doClick() {
optionsSelect.focus();
var WshShell = new ActiveXObject("WScript.Shell");
WshShell.SendKeys("%{DOWN}");
}
</script>
Stop thinking that one thing is impossible, nothing is impossible to do, when you want to do.
Use this expand JS function created by a guy.
http://code.google.com/p/expandselect/
Include this JS and just call that passing the param as your select id, like that:
ExpandSelect(MySelect)
If anyone is still looking for this,
This is how I solved it.
This is a solution based on the fact that the selection looks like it is expanded when the size in increased. We can increase size to make it look expanded. And reduce to make it seem closed. This way we can handle most use-cases by just having focus and blur listeners.
Select element needs to be absolutely positioned because increasing size will increase vertical height of element. If you have elements below, they will be pushed down if this is not done.
I have a wrapper code, that wraps the element and provides open and close methods.
Check this fiddle for usage: https://jsfiddle.net/10ar2ebd/16/
var SelectionWrapper = function(element, maxSize, selectCb) {
var preventDefault = function(e) {
e.preventDefault();
e.stopPropagation();
}
var isOpen = false;
var open = function() {
if (!isOpen) {
element.size = maxSize;
// Remove prevent default so that user will be able to select the option
// Check why we prevent it in the first place below
element.removeEventListener('mousedown', preventDefault);
// We focus so that we can close on blur.
element.focus();
isOpen = true;
}
};
var close = function() {
if (isOpen) {
element.size = 1;
// Prevent default so that the default select box open behaviour is muted.
element.addEventListener('mousedown', preventDefault);
isOpen = false;
}
};
// For the reason above
element.addEventListener('mousedown', preventDefault);
// So that clicking elsewhere closes the box
element.addEventListener('blur', close);
// Toggle when click
element.addEventListener('click', function(e) {
if (isOpen) {
close();
// Call ballback if present
if(selectCb) {
selectCb(element.value);
}
} else {
open();
}
});
return {
open: open,
close: close
};
};
// Usage
var selectionWrapper = SelectionWrapper(document.getElementById("select_element"), 7, function(value) {
var para = document.createElement("DIV");
para.textContent = "Selected option: " + value;
document.getElementById("result").appendChild(para);
});
document.getElementById("trigger").addEventListener('click', function() {
selectionWrapper.open();
});
Here is the solution on https://jsfiddle.net/NickU/ahLy83mk/50/
It uses size="x" to open the dropdown while maintaining the dropdown and parent positions. The code also uses CSS styles to hide the right scroll area when it is not needed. I modified the code I found on stackoverflow, fixed the problems and added styling.
HTML:
<div>DIV example: <select id="dropdownDiv">
<option value="Alpha">Alpha</option>
<option value="Beta">Beta</option>
<option value="Gamma">Gamma</option>
</select>
</div>
<table id='tab1'>
<tr><td>Empty Cell</td></tr>
<tr><td> <select id="dropdown1">
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select>
</td>
<tr><td><select id="dropdown2">
<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="8">8</option><option value="9">9</option><option value="10">10</option><option value="11">11</option><option value="12">12</option><option value="13">13</option><option value="14">14</option><option value="15">15</option><option value="15">1</option><option value="16">16</option><option value="17">17</option><option value="18">18</option><option value="19">19</option><option value="20">20</option><option value="21">21</option></select>
</td></tr>
<tr><td>Empty Cell</td></tr></table>
<br><button id="fire" type="button" onclick="openDropdown('dropdownDiv', this)" >Show dropdownDiv items</button>
<button id="fire" type="button" onclick="openDropdown('dropdown1', this)" >Show dropdown1 items</button>
<button id="fire" type="button" onclick="openDropdown('dropdown2', this)" >Show dropdown2 items</button>
JavaScript:
var lastClosedElem = null;
var maxItemsInDropDown = 12;
function openDropdown(elementId, opener)
{
if (lastClosedElem !== null && lastClosedElem === opener)
{
lastClosedElem = null;
return;
}
lastClosedElem = opener;
function down()
{
var $this = $(this);
var td = $this.closest('td,div');
if (td && td.length > 0)
td.height(td.height());
var pos = $this.offset();
var len = $this.find("option").length;
if (len > 1 && len < maxItemsInDropDown)
{
$this.addClass('no-scroll');
$this.addClass('noArrow');
}
else if (len > maxItemsInDropDown)
{
len = maxItemsInDropDown;
}
$this.css("position", "absolute");
var _zIndex = $this.css("zIndex");
if (!_zIndex)
_zIndex = 'auto';
$this.attr("_zIndex", _zIndex);
$this.css("zIndex", 9999);
$this.attr("size", len); // open dropdown
$this.unbind("focus", down);
$this.focus();
}
var up = function()
{
var $this = $(this);
$this.css("position", "static");
$this.attr("size", "1");
$this.removeClass('no-scroll');
$this.removeClass('noArrow');
var _zIndex = $this.attr("zIndex");
if (_zIndex)
{
$this.css("zIndex", _zIndex);
}
$this.unbind("blur", up);
$this.unbind("click", upClick);
$this.focus();
}
function upClick(e)
{
up.call(this);
lastClosedElem = null;
}
$("#" + elementId).focus(down).blur(up).click(upClick).trigger('focus');
}
CSS:
.no-scroll { cursor: pointer;}
.no-scroll::-webkit-scrollbar {display:none;}
.no-scroll::-moz-scrollbar {display:none;}
.no-scroll::-o-scrollbar {display:none;}
.no-scroll::-google-ms-scrollbar {display:none;}
.no-scroll::-khtml-scrollbar {display:none;}
.noArrow {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
padding-left: 3px;
padding-right: 3px;
}
/* Cosmetic styles */
#tab1 tbody tr:nth-child(even) > td, div
{ background: linear-gradient( 180deg, #efefef 1%, #eeeeee 15%, #e2e2e2 85%);
}
#tab1 tbody tr td
{ padding: 4px;
}
#tab1
{ border: 1px solid silver;
}
I may be wrong, but I don't believe that is possible with the default select box. You could do something with JS & CSS that achieves the desired result, but not (to my knowledge) the vanilla SELECT.
This is not exactly what you asked for, but I like this solution for its simplicity. In most cases where I am wanting to initiate a dropdown, it is because I'm validating that the user has actually made a selection. I change the size of the dropdown and focus it, which nicely highlights what they've skipped:
$('#cboSomething')[0].size = 3;
$('#cboSomething')[0].focus();
Opening an "HTML select" is possible through some workarounds mentioned in this question and similar ones. However a cleaner way of doing this is to add a select library to your project like "select2" or "chosen".
For instance, opening a select2 programmatically would be as easy as:
$('#target-select').select2('open');
I don't know if I'm fully understanding the question, but to open a dropdown, this simple approach worked for me.
You have an element:
<span onclick="openDropdown();">Open dropdown</span>
You have a dropdown:
<select class="dropdown">
<option value="A">Value A</option>
<option value="B">Value B</option>
<option value="C">Value C</option>
</select>
And with JavaScript you can do the following:
document.querySelector('.dropdown').focus();
let elSelected = null;
function bindSelectClick(el){
if(el.target !== elSelected){
$(elSelected).trigger('blur');
$(document).unbind('click', bindSelectClick)
}
}
$('select.shared_date').on('focus', function (){
// do something
elSelected = this;
$(document).on('click', bindSelectClick)
}).on('blur', function (){
// do something
}).on('change', function (){
// do something
})
Select does not lose focus after its menu is closed.
With a separate function, we check whether the click was on the select or elsewhere. If the elements are not equal, then you can fire some kind of event

My plugin doesn't work with multiple selectors

Maybe it's something simple but I have a problem.
I created a plugin, but it only works well with a single selector, if I put several, that's where the problem comes from.
Although I use $(this) to select the current select, it ends up selecting all and replaces the value in all the selects where it finds them.
I leave my jsfiddle for review.
Look at the select # 1 and # 3.
$(document).ready(function() {
$("#sel1, #sel2, #sel3").SelectPopup();
});
See my jsfiddle
I'm not going to rewrite your plugin for you but will show you the basics of isloating the element instances within your plugin.
this inside the plugin function is a jQuery object that includes all of the matching elements from the selectors.
You want an internal each to loop over and isolate each of those element instances.
Following is a very crude plugin that just wraps each of the selects in a parent container and adds a change event listener to each instance. It is not very practical by itself but should give you the foundation to rebuild the one you are working on
$.fn.mySelect = function(options) {
// `this` is jQuery object that contains all elements in collection
// we return it so the plugin can be chained to other jQuery methods if needed
// also use `each` to isolate individual elements in the collection
return this.each(function() {
// `this` is instance of element in collection
var $currentSelect = $(this);
// wrap each element and add a change event listener
$currentSelect.wrap('<div class="select-wrapper">')
.change(function() {
console.log('Select id "' + this.id + '" changed')
});
});
}
$("#sel1, #sel2, #sel3").mySelect()
.select-wrapper {
display: inline-block;
border: 1px solid #ccc;
margin-right: 20px;
padding: 1em
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select id="sel1">
<option value="1">A1</option>
<option value="2">A2</option>
<option value="3">A3</option>
</select>
<select id="sel2">
<option value="10">B1</option>
<option value="20">B2</option>
<option value="30">B3</option>
</select>
<select id="sel3">
<option value="1">C1</option>
<option value="2">C2</option>
<option value="3">C3</option>
</select>

Hide elements in jQuery based on select value

I am building a filtering tool using a select element. When you choose something from the drop down, it should filter the divs below to show only the div for that item.
I am targeting the divs using the select value which is also the class of the div the item is in. So for example, if you choose shirts in the drop down the value would be item-shirts and a div below would have a class of item-shirts.
I have figured out how to hide everything that doesn't have the class of the selected item when something is selected. But I can't figure out how to unhide everything when something else is selected. Any help would be greatly appreciated!
Here is my HTML
<select>
<option value="item-shirts">Shirts</option>
<option value="item-shoes">Shoes</option>
<option value="item-shoes">Pants</option>
</select>
<div class="item-section item-shirt></div>
<div class="item-section item-shoes></div>
<div class="item-section item-pants></div>
Here is my jQuery
$('select').on("change", function() {
var value = $('select').val();
if($('.item-section').hasClass(value)) {
$('.item-section.'+value).siblings().hide();
} else {
$('.item-section.'+value).siblings().show();
}
This is similar to adding an active class to a list/group of elements. Typically what you do is loop through all the elements removing the active class (even though it's only applied to one element), then add the active class to the specific element. In your case you might want to hide all DIVs, then show the specific DIV.
var $sections = $( '.item-section' );
$('select').on( 'change', function ( e ) {
$sections.hide();
$( '.' + this.value ).show();
} );
.item-section {
margin: 2rem 0;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option value="item-shirts">Shirts</option>
<option value="item-shoes">Shoes</option>
<option value="item-pants">Pants</option>
</select>
<div class="item-section item-shirts">Shirt</div>
<div class="item-section item-shoes">Shoes</div>
<div class="item-section item-pants">Pants</div>
Note: You had a few errors in your markup that I changed to make everything work. i.e. Duplicate values for your <option> tags and some missing quotes.
I've done a couple performance improvements too.
You also don't need $( 'select' ).val() inside of your event handler. The context of the handler is the <select> element so you can use the this.value instead and skip jQuery querying the DOM to do the same.
I've also cached the .item-section elements so you're not querying the DOM over and over again on each change of the select.
There was no need to test for hasClass(). All you need to do is get the value from the selected option and show the <div> having that class. I added an extra empty option so that when you select it, it will show all <div>s.
$('select').on("change", function() {
var value = $('select').val();
if (value) {
$(".item-section").hide();
$("." + value).show();
} else {
$(".item-section").show();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select>
<option value=""></option>
<option value="item-shirt">Shirts</option>
<option value="item-shoes">Shoes</option>
<option value="item-shoes">Pants</option>
</select>
<div class="item-section item-shirt">Shirts</div>
<div class="item-section item-shoes">Shoes</div>
<div class="item-section item-pants">Pants</div>

How to synchronize data-attr and select box vaule?

I have two elements like:
<select id="data">
<option value=1>hoge</option>
<option value=2>fuga</option>
<option value=3>hogehoge</option>
</select>
hoge
fuga
hogehoge
if I pick hoge on select box, I want data-id="1" to be selected and do some stuff (changing background etc.) using jQuery.
If I click a[data-id="3"], select box option 'hogehoge' to be selected vice versa.
any help would be appreciated.
Have a look at the last line in the click listener. You can trigger a change on an element which will call the corresponding listener instead of duplicating code.
$(function() {
$("#data").on("change", function() {
$("a").removeClass("active"); // remove active class from all <a>
$("a[data-id='" + $(this).val() + "']").addClass("active"); // add active class to link with corresponding data-id
});
$("a").on("click", function() {
$("#data option[value='" + $(this).data("id") + "']").prop("selected", true); // change the selected value
$("#data").trigger("change"); // trigger change on #data to keep active link synced
});
});
.active {
background-color: cornflowerblue;
color: white;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="data">
<option value=1>hoge</option>
<option value=2>fuga</option>
<option value=3>hogehoge</option>
</select>
hoge
fuga
hogehoge
$(document).ready( function(){
$('a').click(function(){
var id = $(this).data('id');
$('#data').find('option[value='+id+']').prop('selected',true);
)};
)};
I implemented the function in JSFiddle
https://jsfiddle.net/dphf267u/

moving select options up and down via jquery

so I got this code working for Firefox and Chrome...what it does is it allows you to reorder the options within an HTML select form...but then when I tested the code via IE8, it's kind of patchy...it only works for the first few clicks and after that you have to click many times on the button for it to work..
Does anybody know any other code that allows you to reorder select field items that works perfectly in IE8?
<select id="list" multiple="multiple">
<option value="wtf">bahaha</option>
<option value="meh">mwaahaha</option>
</select>
<button id="mup">Move Up</button>
<button id="mdown">Move Down</button>
Add Item
Remove item
<script>
$(document).ready(function(){
$('#mup').click(function(){
moveUpItem();
});
$('#mdown').click(function(){
moveDownItem();
});
});
function moveUpItem(){
$('#list option:selected').each(function(){
$(this).insertBefore($(this).prev());
});
}
function moveDownItem(){
$('#list option:selected').each(function(){
$(this).insertAfter($(this).next());
});
}
Your code for changing the options works fine. It seems IE8 isn't handling a "fast" second-click with the click event but rather expects a double click to be handled.
Using my test code below, you'll notice that in IE8 writes out the following when Move Down/Up is pressed "fast":
Move Down Click
Move Down Double-Click
Move Down Click
Move Down Double-Click
But with FF/Chrome the following is printed:
Move Down Click
Move Down Click
Move Down Double-Click
Move Down Click
Move Down Click
Move Down Double-Click
Here's the code I'm using to test. I haven't done any tests to see if it's jQuery's event binders that are causing the issues.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Test</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.js"></script>
</head>
<body>
<select id="list" multiple="multiple">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
<option value="option3">Option 3</option>
</select>
<button id="mup">Move Up</button>
<button id="mdown">Move Down</button>
<script type="text/javascript">
var $DEBUG = null;
$(document).ready(function ()
{
$DEBUG = $("#debug");
$DEBUG.append("Registering Events<br />");
$("#mup").click(moveUpItem);
$("#mdown").click(moveDownItem);
$("#mup").bind("dblclick", function ()
{
$DEBUG.append("Move Up Double-Click<br />");
});
$("#mdown").bind("dblclick", function ()
{
$DEBUG.append("Move Down Double-Click<br />");
});
});
function moveUpItem()
{
$DEBUG.append("Move Up Click<br />");
}
function moveDownItem()
{
$DEBUG.append("Move Down Click<br />");
}
</script>
<div id="debug" style="border: 1px solid red">
</div>
</body>
</html>
EDIT: I can confirm it is IE8 that is the problem. Swap this IE8-specific code in the $(document).ready() handler:
// $("#mup").click(moveUpItem);
$("#mup")[0].attachEvent("onclick", moveUpItem);
// $("#mdown").click(moveDownItem);
$("#mdown")[0].attachEvent("onclick", moveUpItem);
// $("#mup").bind("dblclick", function ()
$("#mup")[0].attachEvent("ondblclick", function ()
{
$DEBUG.append("Move Up Double-Click<br />");
});
// $("#mdown").bind("dblclick", function ()
$("#mdown")[0].attachEvent("ondblclick", function ()
{
$DEBUG.append("Move Down Double-Click<br />");
});
Example:
to move 3rd option before 1st option, we can use below jquery:
$('select[name="NameOfDropDown"] option:eq(2)').insertBefore($('select[name="NameOfDropDown"] option:eq(0)'));
I think this will give some ideas of how to do it, you can dynamically place any option before one known position just by knowing the values of both, the one to move and the one of the position:
How would you dynamically order an <option select> list using JQuery?
I know this one is a bit old, but I recently made this simple jQuery plugin to be able to reorder elements in a multiple select element.
Have a look and see if it helps for you, I tested in IE8,IE9,Chrome,FireFox,Opera.
http://fedegiust.github.io/selectReorder/

Categories

Resources