onchange event for SELECT element trouble with Internet Explorermouse wheel

Discussion in 'Javascript' started by jezaustin@gmail.com, Jan 22, 2008.

  1. Guest

    Hi guys,
    I'm using the onchange event on a SELECT element to pull extra inputs
    into a form based on the value in the SELECT. It works fine in both
    firefox and explorer: user selects an option and relevant extra fields
    appear / disappear immediately.

    However, explorer has a feature that allows a user to scroll through
    the options in a select field using the onmousewheel, and the onchange
    function appears not to fire.

    What's the simplest way around this? I've considered the following:
    1) trap the onmousewheel event
    a) update the fields there and then
    b) repress the change in the SELECT on the mousewheel

    2) alter the server side code to offer a second round of questioning
    if there's a discrepancy between the selected options and the
    dependent fields offered.



    2) is definitely doable, but I feel is a degraded user experience.
    I've attempted both 1a) and 1b) but I can't make either work.
    With 1a) I do seem to be able to trigger the function on a mouse
    scroll, but it doesn't do the actual DOM work. I don't know why, I
    believe it should work, I'm not using "this" or the event object at
    all. See below for code, am I doing something stupid?
    With 1b) I've just had no luck at all. Returning false doesn't stop
    the scroll wheel altering values in the SELECT. Anybody know how or if
    you can do this? Or is there another solution to this that I haven't
    thought of?

    I'd be very grateful for any help or advice, general or specific.

    Thanks,
    Jez Austin.

    Here's the function:
    <pre>
    function
    select_traits(i)
    {
    // i is
    integer
    // usually called from "measure"+i
    onchange
    var elem =
    document.getElementById("measure"+i);

    // record array of selected
    measures
    var selected_measures =
    [];
    var
    measureIndex;
    for (var j=1; j<5; j+
    +)
    if (0 != (measureIndex
    =

    document.getElementById("measure"+j).selectedIndex))
    // all measure selects have the same
    options

    selected_measures.push(elem.options[measureIndex].value);

    // hide irrelevent traits
    // that is, move them to a hidden div outside the
    form
    var traits = get_trait_fieldset(); // returns the fieldset
    element, creates it if it doesn't yet
    exist
    var hidden_traits =
    document.getElementById("traits_hidden");

    var row_div =
    traits.firstChild;
    while (row_div)
    {
    if ("div" != row_div.nodeName.toLowerCase())
    {
    row_div =
    row_div.nextSibling;

    continue;
    }

    // Each of these spans has an attribute "measures",
    // a comma separated list of the measures it is associated
    with
    var my_measures
    =
    row_div.getElementsByTagName("span")
    [0].getAttribute("measures").split(",");
    if (array_overlap(my_measures, selected_measures))
    {
    row_div =
    row_div.nextSibling;

    continue;
    }

    var next_div =
    row_div.nextSibling;

    hidden_traits.appendChild(row_div);
    row_div =
    next_div;
    }


    // reveal relevent
    inputs
    row_div =
    hidden_traitts.firstChild;
    while (row_div)
    {
    if ("div" != row_div.nodeName.toLowerCase())
    {
    row_div =
    row_div.nextSibling;

    continue;
    }

    var my_measures
    =
    row_div.getElementsByTagName("span")
    [0].getAttribute("measures").split(",");

    if (! array_overlap(my_measures, selected_measures))
    {
    row_div =
    row_div.nextSibling;

    continue;
    }

    var next_div =
    row_div.nextSibling;

    traits.appendChild(row_div);
    row_div =
    next_div;
    }

    if (0 ==
    traits.getElementsByTagName('div').length)

    traits.parentNode.removeChild(traits);

    // test: is this called be wheel
    code?
    return 'called select_traits('+i+')';
    // needn't / shouldn't return
    anything
    }
    </pre>

    and here's where I set the onchange events
    <pre>
    for (var i=1; i<5; i++)
    {
    var measure_select =
    document.getElementById("measure"+i);

    measure_select.onchange = measure_select.onleave = function(evt)
    {
    // alert("hello
    world");

    refuse_duplicates();

    evt = (evt) ? evt : ( (event) ? event :
    null );
    if(evt)
    {
    var elem = (evt.target) ?
    evt.target :
    ((evt.srcElement) ? evt.srcElement :
    null);
    if(elem)
    {
    elem = (elem.nodeType==1 || elem.nodeType==9) ? elem :
    elem.parentNode;

    select_traits(elem.id.substring(7));
    }
    }
    };
    }
    select_traits(1);
    </pre>
    That last line pulls in the relevant traits when editing an existing
    record, and proves that the function works in IE both when called
    explicitly and when called by the event.

    Here's how I attach it to the onmousewheel event
    <pre>
    var soc_id =
    null;
    function update_on_wheel_for_ie( code, delay )
    {
    delay = delay || 1000; // default
    1s

    window.clearTimeout( soc_id );
    // appears as though the select_traits function isn't getting
    purchase on the DOM elements when called this
    way... ??
    //
    alert(select_traits(1));
    soc_id = window.setTimeout( code,
    delay );
    }

    document.onmousewheel = window.onmousewheel = function()
    {
    // alert("hello
    world");
    update_on_wheel_for_ie('refuse_duplicates(); select_traits(1);
    select_traits(\
    2); select_traits(3);
    select_traits(4);');

    //'document.getElementById("measure1").onchange();');
    return
    true;
    };
    </pre>

    Sorry if this bit isn't very clear, I've just been trying out a few
    things, thought I'd include it though.
     
    , Jan 22, 2008
    #1
    1. Advertising

  2. David Mark Guest

    On Jan 22, 6:56 am, wrote:
    > Hi guys,
    > I'm using the onchange event on a SELECT element to pull extra inputs
    > into a form based on the value in the SELECT. It works fine in both
    > firefox and explorer: user selects an option and relevant extra fields
    > appear / disappear immediately.


    The change event won't fire in some browsers until the SELECT element
    loses focus. IIRC, most fire it immediately when a pointing device is
    used, IE fires immediately when using the keyboard as well. I thought
    for sure that IE did the same when using the mousewheel.

    >
    > However, explorer has a feature that allows a user to scroll through
    > the options in a select field using the onmousewheel, and the onchange
    > function appears not to fire.
    >
    > What's the simplest way around this? I've considered the following:
    > 1) trap the onmousewheel event
    >   a) update the fields there and then
    >   b) repress the change in the SELECT on the mousewheel


    No.

    >
    > 2) alter the server side code to offer a second round of questioning
    > if there's a discrepancy between the selected options and the
    > dependent fields offered.


    You should do that anyway. You can't count on client-side script to
    guarantee valid input.

    >
    > 2) is definitely doable, but I feel is a degraded user experience.
    > I've attempted both 1a) and 1b) but I can't make either work.
    > With 1a) I do seem to be able to trigger the function on a mouse
    > scroll, but it doesn't do the actual DOM work. I don't know why, I
    > believe it should work, I'm not using "this" or the event object at
    > all. See below for code, am I doing something stupid?
    > With 1b) I've just had no luck at all. Returning false doesn't stop
    > the scroll wheel altering values in the SELECT. Anybody know how or if
    > you can do this? Or is there another solution to this that I haven't
    > thought of?


    You don't want to block mousewheel input. Can't the application wait
    until the use changes focus (in which case the change event should
    certainly fire?)
     
    David Mark, Jan 22, 2008
    #2
    1. Advertising

  3. Guest

    On 22 Jan, 14:33, David Mark <> wrote:
    >
    > The change event won't fire in some browsers until the SELECT element
    > loses focus. IIRC, most fire it immediately when a pointing device is
    > used, IE fires immediately when using the keyboard as well. I thought
    > for sure that IE did the same when using the mousewheel.


    Well, based on your surprise I decided to test on a different setup
    (I'd been using explorer using wine under linux) and it seems that
    explorer acts as you say, and onchange does happen during mousewheel
    scrolls.
    So this is just a bug on an unsupported operating system, and can be
    reasonably ignored.

    Anyhow, I'll use both onchange and onleave events for extra safety.

    >
    >
    >
    > > 2) alter the server side code to offer a second round of questioning
    > > if there's a discrepancy between the selected options and the
    > > dependent fields offered.

    >
    > You should do that anyway. You can't count on client-side script to
    > guarantee valid input.


    Yep, of course.

    Thanks for the help David,

    Jez.
     
    , Jan 22, 2008
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Covad
    Replies:
    1
    Views:
    200
    Richard Cornford
    Nov 3, 2003
  2. Ryan McGeary
    Replies:
    2
    Views:
    197
    Thomas 'PointedEars' Lahn
    Jan 7, 2004
  3. Robert Carlson
    Replies:
    2
    Views:
    134
    Richard Cornford
    Sep 14, 2004
  4. Replies:
    0
    Views:
    111
  5. andypb123
    Replies:
    14
    Views:
    288
    David Mark
    Mar 21, 2011
Loading...

Share This Page