Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get last clicked option in multiple select

On a page, I have a select (multiple) box with many options. Now I want to react on the last clicked item to display some data with ajax.

As the "click" event on the option element does not work in IE, I currently use the "change" event.

The problem is, that the "value" and the selectedIndex attribute point to the first selected item, even if I select other options following the first.

The only way I could get the most recently selected option is by comparing the set of selected options before and after the "change" event.

Is there any other way?

like image 995
Wikser Avatar asked Feb 16 '10 20:02

Wikser


2 Answers

The only way I could get the most recently selected option is by comparing the set of selected options before and after the "change" event.

That's probably your best bet -- ie's not going to report click events on the individual options (it will only report clicks on the select box).

If you really want to figure out which option was clicked (when listening for clicks on the select box itself), you can look at the offsetY property of the event object (which will be the vertical offset of the mouse cursor relative to the top of the first option in the select box -- so it includes the select box's scroll offset), and divide that by your pre-determined option size (which will depend on the font-size of the select box).

But obviously, that won't help you when the user selects options via the keyboard.

like image 99
Justin Ludwig Avatar answered Nov 14 '22 23:11

Justin Ludwig


The following code is not perfect. I think it doesn't work entirely correctly in IE6 but it is fine in IE7-8, Firefox, Safari(Win), Opera & Chrome. It only records the last click to select a value so un-selecting a value that was the last selected without selecting another still returns the last selected (now unselected) index. I'll leave you to handle that if you need to...

<html>
<head>
    <title>Multiple selection indices attribute</title>
    <script type='text/JavaScript'>
        function oc(a) {var o={};for (var i=0;i<a.length;i++) {o[a[i]]='';}; return o;};

        function getIndices(ele) 
                {if (!ele.prevSelected) {ele.prevSelected=new Array();}

                 ele.selectedIndices=new Array();

                 while (ele.selectedIndex != -1) 
                    {ele.selectedIndices.push(ele.selectedIndex);

                   if (ele.selectedIndex in oc(ele.prevSelected))   {null;}
                   else {ele.newIndex = ele.selectedIndex;}

                     ele.options[ele.selectedIndex].selected = false;
                    };

                 for (var i=0;i<ele.selectedIndices.length;i++) 
                    {ele.options[ele.selectedIndices[i]].selected = true;};

                 ele.prevSelected=new Array();

                 if (ele.selectedIndices)   
                    {for (var i=0;i<ele.selectedIndices.length;i++) 
                        {ele.prevSelected.push(ele.selectedIndices[i]);}
                    }
                };

            function display(ele)   {if (ele.newIndex) {alert('Last selection: '+ele.newIndex);}};

    </script>
</head>
<body onload='getIndices(document.getElementById("mine"));'>
    <select multiple='multiple' id='mine' size='10' onclick='getIndices(this);'>
        <option value='A'> 0</option><option value='B'> 1</option>
        <option value='C'> 2</option><option value='D'> 3</option>
        <option value='E'> 4</option><option value='F'> 5</option>
        <option value='G'> 6</option><option value='H'> 7</option>
        <option value='I'> 8</option><option value='J'> 9</option>
        <option value='K'>10</option><option value='L'>11</option>
        <option value='M'>12</option><option value='N'>13</option>
        <option value='O'>14</option><option value='P'>15</option>
    </select>
    <input type='button' value='Show' onclick='display(document.getElementById("mine"));' />
</body>

like image 34
Anthony Avatar answered Nov 14 '22 23:11

Anthony