Ajax callback called on textfield typing
here my solution:

first you've to create (or alter) a text field

$form['user_search'] = array(
  '#type' =&gt; 'textfield',
  '#title' =&gt; t('Search'),
  '#description' =&gt; t('Cool description'),
  '#ajax' =&gt; array(
    'callback' =&gt; 'MODULE_ajax_user_search',
    'wrapper' =&gt; 'user-search-replace',
    'event' =&gt; 'finished_input', // custom event called by js code
    'effect' =&gt; 'fade',
  ),
  '#attributes' =&gt; array(
    'class' =&gt; array(
      'delayed-search-submit' // custom class to attach behavior to
    ),
    'data-delay' =&gt; '300', // custom property to set submit delay
    //'data-event' =&gt; 'finished_input', // custom event name, default is "finished_input"
  ),
);


then you'll have to create some js code to attach to your form

(function($){
  $(function(){
    Drupal.behaviors.delayedSearchSubmit = {
      attach: function (context, settings) {
        $('input.delayed-search-submit').once('event', function (){
          var $self = $(this);
          var timeout = null;
          var delay = $self.data('delay');
          var triggerEvent = $self.data('event');
          if (!delay) {
            delay = 1000;
          }
          if (!triggerEvent) {
            triggerEvent = 'finished_input';
          }
          // Every time a keyup event is fired
          // timer is reset
          $self.bind('keyup', function(){
            clearTimeout(timeout);
            timeout = setTimeout(function(){
              $self.trigger(triggerEvent);
            }, delay);
          });
        });
      }
    }
  });
})(jQuery);


now attach js file to your form

drupal_add_js(drupal_get_path('module', 'MODULE') . '/js/MODULE.textsearch.js');