views:

303

answers:

2

I'm using YUI as javascript framework, and can successfully react when the user changes the value of basic input fields, the reaction being to sent an Ajax query.

However, I'm not so lucky with multiselect dropdown lists:

  • listening to "change" would send my query each time the user adds/removes an item to his selection
  • listening to "blur" requires the user to click elsewhere in order to loose the focus and send the query (not very usable), plus it would send the query if the user only scrolls on the list without changing anything (useless, confusing).

Any idea (with YUI), that would use a clever behavior? Or should I really listen to change and implement a timeout (to wait for subsequent changes before sending a query)?

+1  A: 

you could run a setTimeout after the onChange event and keep track of a number of changes to determine whether or not a change had been made since the event was fired. if no changes were made within that time, then the query could be sent.

e.g., something like:

var changes = 0;

function myOnChangeHandler(e)
{
  changes++;
  var local_change = changes;

  setTimeout(function() { 
    if (local_change === changes) {
      sendRequest();
    }
  }, 500);
}
Jonathan Fingland
+3  A: 

I use the same kind of timeout you want on key events, to detect when the user have finished typing, the same approach can be used on your problem:

// helper function
var timeout = (function(){
  var timer = 0;
  return function(callback, ms){
    clearTimeout (timer);
    timer = setTimeout(callback, ms);
  };
})();

Usage:

// YUI 2
YAHOO.util.Event.addListener(oElement, "change", function () {
  timeout(function () {
    // one second since the last selection change
  }, 1000);
}); 

// YUI 3
Y.on("click", function () {
  timeout(function () {
    // one second since the last selection change
  }, 1000);
}, oElement);

Basically in this timeout function, I reset the timer if the function is called before the specified delay.

CMS