4

Please read carefully the title - this is not the common onchange thing.

There exists a selectbox on a webpage. The selectbox its selectedIndex can be changed programmatically by javascript, external js.

I would like to be notified when the index changes (crossbrowser solution). Is this possible?


Consider the jsfiddle example


Or HTML:

<select id="mySelect">
    <option>opt 1</option>
    <option>opt 2</option>
    <option>opt 3</option>
</select>​

JavaScript:

// Code I cannot manipulate
var select = document.getElementById("mySelect");
select.selectedIndex = 2; // I would like to be notified now

Awaiting your insights :-)

Update:

This doesn't answer my original question, but using this I managed to accomplish what I initially wanted (not part of the post):

select.selectedIndex = 2;
select.onchange();
EricG
  • 3,788
  • 1
  • 23
  • 34
  • No, you can't. However, why would you want to do that? I guess your application design is a bit flawed if you need to be informed what other code - especially one you can't edit - does "without your knowledge". – Bergi Jul 12 '12 at 10:48
  • The reason is obvious: because I would like to interfere/manipulate the default processing that is being performed by the external JS. And I admit the external JS is not flawless - it's Microsofts'. But these details are not that relevant, I believe. Triggers "Without my knowledge" i.e. without being notified does not imply flaws - it is just not designed with the intend to enable interference. – EricG Jul 12 '12 at 11:06
  • Yes, if that script is not designed to allow interference you should look for another solution :-) – Bergi Jul 12 '12 at 11:13
  • Obvious comment is obvious. "Not designed to allow interference" doesn't imply "Unable to interfere" either.. i.e. Looking for "a" way, if possible - whether or not it was intended to do so. – EricG Jul 12 '12 at 11:19

4 Answers4

0

Javascript change events require a browser event initiated by the user. They do not work when changes are triggered by JavaScript itself.

If you really really want to do this, you should write a function that polls the value of the <select> at regular intervals using setInterval, and does comparisons.

var selectold =  select.selectedIndex;
setInterval(function(){
    if(selectold != select.selectedIndex)
       {
           console.log("there was a change");
           selectold = select.selectedIndex;

       }
},500);

Edited Fiddle

Anirudh Ramanathan
  • 46,179
  • 22
  • 132
  • 191
  • Thank you for your suggestion. As for lack of elegance, I will not use this, though. – EricG Jul 12 '12 at 11:09
  • Dont blame you :D. It is a really inelegant way to do it. But `setInterval` doesn't affect User Experience. http://stackoverflow.com/questions/6650134/is-setinterval-cpu-intensive – Anirudh Ramanathan Jul 12 '12 at 11:12
  • Lol at least it is "a" way - you did answer my question.. From what I know it is just scheduled as an instruction (no countdowns or so), so not quite CPU demanding. – EricG Jul 12 '12 at 11:26
0

I realized that I indirectly triggered the change of the selectbox. This enables me to do a check just after that.. Not just as good as listeners, but it will work and won't be that dirty :-)

At least I got confirmed that there is no such an event to listen to. Thank you for that.

EricG
  • 3,788
  • 1
  • 23
  • 34
-1

If you control the code which is updating the selectedIndex, you could inject a callback into it which will give you event like behavior.

/* code that I do not wish/'cannot' change: */
function startSelectScroll(indexChangeCallback) {
    var select = document.getElementById("mySelect");

    var index = 0;
    var myInterval = setInterval( function() { // Change index every 500ms

        index++;
        select.selectedIndex = index % 3;

        indexChangeCallback.call(select);
    }, 500 );

    setTimeout( function() { // Remove automatic change after 3000ms
        clearInterval( myInterval );
        alert(callCount);
    }, 3000 );
}
/* end unmodifiable code */

startSelectScroll(function() {
    callCount++;
});

var callCount = 0;

If you don't control it, whatever framework your using should support callbacks in the same manner.

just.another.programmer
  • 8,579
  • 8
  • 51
  • 90
  • I appreciate your effort, but the /* code that I do not wish/'cannot' change: */ should/can not be changed by me. – EricG Jul 12 '12 at 11:09
-2

First thing came to my mind is;

function alertMe(theSelect) {
    var mySelectList = document.getElementById(theSelect);  
    var result = mySelectList.options[mySelectList.selectedIndex].value;
    alert(result); // Alerts selected option
}

html:

<select id="mySelect" onchange="javascript:alertMe("mySelect")">
    <option value="A"> A text </option>
    <option value="B"> B text </option>
    <option value="C"> C text </option>
<select>

this gives the selected options value field you can also get text field with replacing ".value" with ".text" at the end..

Berker Yüceer
  • 7,026
  • 18
  • 68
  • 102
  • How is **this** a solution to the problem? – Anirudh Ramanathan Jul 12 '12 at 11:14
  • Your answer is not helpful, sorry. As I tried to make explicitly clear, the change (of the index) is executed by JavaScript, not by a mouseaction or so. No event is thrown, and 'alertMe' will not be executed. – EricG Jul 12 '12 at 11:16
  • my bad, when another javascript code triggers an event on the element i guess only way to catch it is setting interval as @DarkXphenomenon mentioned it. when jQuery releases "listen()" i hope they would think about this too. – Berker Yüceer Jul 16 '12 at 06:57