Goffer
Goffer

Reputation:

Detect programmatical changes on a html select box

Is there a way to make a HTML select element call a function each time its selection has been changed programmatically?

Both IE and FF won't fire 'onchange' when the current selection in a select box is modified with javascript. Beside, the js function wich changes the selection is part of framework so I can't change it to trigger an onchange() at then end for example.

Here's an example:

<body>
<p>
<select id="sel1" onchange="myfunction();"><option value="v1">n1</option></select>
<input type="button" onclick="test();" value="Add an option and select it." />
</p>
<script type="text/javascript">
    var inc = 1;
    var sel = document.getElementById('sel1');
    function test() {
        inc++;
        var o = new Option('n'+inc, inc);
        sel.options[sel.options.length] = o;
        o.selected = true;
        sel.selectedIndex =  sel.options.length - 1;
    }

    function myfunction() {
        document.title += '[CHANGED]';
    }
</script>
</body>

Is there any way to make test() call myfunction() without changing test() (or adding an event on the button)?

Thanks.

Upvotes: 6

Views: 9587

Answers (5)

Nlinscott
Nlinscott

Reputation: 796

With JQuery, you could do something like

$(document).ready(function(){ 

          $('#select-id').change(function(e){
               e.preventDefault();
               //get the value of the option selected using 'this'
               var option_val = $(this).val();

                  if(option_val == "v1"){
                       //run your function here
                  }
                return true; 
            });
   });

This would detect the change programmatically and let you respond to each item changed

Upvotes: 0

Sam
Sam

Reputation: 11

Define your own change function that calls the framework function and then calls a callback function.

e.g.:

function change(callback)
{
    frameworkchange();
    callback();
}

Upvotes: 1

Sean.C
Sean.C

Reputation: 152

ahem...

you can access the event 'onpropertychange' it contains a property within the event arguments to identify which property was changed.

It detects both 'selectedIndex' and 'value' changes - simply case test 'propertyName' I'm currently working with the ASP.NET js framework here is some straight copy-paste code for that:

1) define handler:

this._selectionChangedHandler = null;

2) assign handler

this._selectionChangedHandler = Function.createDelegate(this, this._onSelectionChanged);

3) attach handler to event

$addHandler(element, "propertychange", this._selectionChangedHandler);

4) create function

_onSelectionChanged: function(ev) {

if (ev.rawEvent.propertyName == "selectedIndex")
        alert('selection changed');
},

Upvotes: 0

Chii
Chii

Reputation: 14738

If you can extend/modify the framework to give a hook/callback when they change the select options, it would be better (one way could be to use the dynamic capabilities of js to duck type it in?).

Failing that, there is an inefficient solution - polling. You could set up a setTimeout/setInteval call that polls the desired select option dom element, and fire off your own callback when it detects that something has changed.

as for the answer to your question

Is there any way to make test() call myfunction() without changing test() (or adding an event on the button)?

yes, by using jquery AOP http://plugins.jquery.com/project/AOP , it gives an easy-ish solution.

<body>
<p>
<select id="sel1" onchange="myfunction();"><option value="v1">n1</option></select>
<input type="button" onclick="test();" value="Add an option and select it." />
</p>
<script type="text/javascript">
    var inc = 1;
    var sel = document.getElementById('sel1');
    function test() {
        inc++;
        var o = new Option('n'+inc, inc);
        sel.options[sel.options.length] = o;
        o.selected = true;
        sel.selectedIndex =  sel.options.length - 1;
    }

    function myfunction() {
        document.title += '[CHANGED]';
    }

    //change to aop.after if you want to call afterwards       
      jQuery.aop.before( {target: window, method: 'test'}, 
        function() { 
          myfunctino(); 
        }
      );
</script>
</body>

Upvotes: 4

AnthonyWJones
AnthonyWJones

Reputation: 189457

The answer is .... no.

The DOM only fires the onchange event as a result of user action not code. It does not provide any additional events to hook in this regard.

You will need to customise the framework or drop your requirement.

Upvotes: 0

Related Questions