2011-09-11 3 views
10

J'ai une zone de texte saisie semi-automatique qui doit répondre à 2 événements:jQuery autocomplete

  • Lorsque l'utilisateur se fait taper quelque chose dans la zone de texte (J'utilise actuellement focusout à assumer lorsque l'utilisateur se fait Ainsi, si un utilisateur tabule hors d'une zone de texte, cela signifie que l'utilisateur a fini de taper.)
  • Lorsque l'utilisateur sélectionne un élément dans la liste de valeurs de saisie semi-automatique (j'utilise l'événement select de saisie semi-automatique pour le déterminer)

Le problème:

Lorsque l'utilisateur sélectionne un élément dans la liste de saisie semi-automatique des valeurs, la chaîne de l'événement est telle que focusout est appelée d'abord, puis le select. En focusout, je n'ai accès qu'à ce que l'utilisateur a tapé, pas à ce que l'utilisateur a sélectionné dans la liste de valeurs de saisie semi-automatique - et c'est ce dont j'ai réellement besoin. Comment résoudre ce problème?

Procédure pour reproduire le problème:

  1. Dans la zone de texte, tapez la lettre a
  2. Sélectionnez ActionScript dans la liste autocomplete des valeurs
  3. Observe messages console.debug:

    focusout event called 
    a 
    select event called 
    ActionScript 
    

Voici le code:

<?xml version="1.0" encoding="ISO-8859-1" ?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
     <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> 
     <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/> 
     <title>Data Matching</title> 
    </head> 
    <body> 
     <form> 
      <input id="1" type="text"></input> 
      <input id="2" type="submit"></input> 
     </form> 

     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script> 
     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script> 

     <script> 
     $('#1').autocomplete(
     { 
      select: function (event, ui) 
      { 
       "use strict"; 
       console.debug('select event called'); 
       console.debug(ui.item.value); 
      }, 
      source: ["ActionScript", "AppleScript", "Asp", "BASIC", "C", "C++", "Clojure", "COBOL", "ColdFusion", "Erlang", "Fortran", "Groovy", "Haskell", "Java", "JavaScript", "Lisp", "Perl", "PHP", "Python", "Ruby", "Scala", "Scheme"], 

      minLength: 1 
     }); 

     $('#1').focusout(function() 
     { 
      "use strict"; 
      console.debug('focusout event called'); 
      console.debug($(this).attr('value')); // At this point, I need the value that was selected from autocomplete. I only get the value that the user typed, though 
     }); 
     </script> 
    </body> 
</html> 

Répondre

8

C'est précisément la raison pour laquelle jQueryUI a présenté un événement spécial pour changeautocomplete:

Déclenché lorsque le champ est floue, si la valeur a changé; ui.item fait référence à l'élément sélectionné.

Cet événement peut faire une double fonction à la fois de vos besoins:

$("#1").autocomplete({ 
    /* snip */ 
    change: function(event, ui) { 
     if (ui.item) { 
      console.log("ui.item.value: " + ui.item.value); 
     } else { 
      console.log("ui.item.value is null"); 
     } 
     console.log("this.value: " + this.value); 
    } 
}); 
  • ui.item ne seront pas définis lorsque l'utilisateur n'a pas sélectionné une valeur dans la liste des candidats de saisie semi-automatique.
  • D'autre part, this.value sera toujours être correct.

Voici un exemple: http://jsfiddle.net/33GJb/

+1

Cela a fonctionné. Je me suis débarrassé du gestionnaire d'événement 'focusout'. Merci. – StackOverflowNewbie

+0

Génial, heureux d'aider. –

+0

Aussi, s'il vous plaît n'oubliez pas d'accepter la réponse si elle a aidé ':)' –

0

Tout d'abord, juste à des fins éducatives, il est important pour tous ceux qui comprennent que ces événements perticular sera toujours le feu dans cet ordre. Cela étant, je crois qu'il y a plusieurs façons de résoudre le problème et voici ce que j'ai trouvé. Un: Construire l'application afin que plusieurs valeurs sélectionnées par l'utilisateur (type ou sélectionné) n'interfèrent pas. Par exemple, si l'application corrige automatiquement l'orthographe et que quelqu'un a tapé "orphelinat" sur le focus, le code recherchant l'orthographe la plus proche remplacerait la valeur par "orphelinat", et si quelqu'un sélectionnait "orphelinats", il remplacerait le valeur avec la valeur sélectionnée. Il n'y a probablement pas de problème ici, sauf le désir d'optimisation. Deux: Avoir une valeur signalée soit en Javascript ou dans l'élément HTML ("data-corrected = false") qui existe. Sur FocusOut, définissez SetTimeout pour qu'il attende une durée. Ensuite, si les utilisateurs ont sélectionné une valeur, définissez la valeur de votre indicateur sur true. Lorsque la durée est écoulée, vérifiez la valeur signalée, si elle est vraie ne faites rien, sinon utilisez la valeur dans le champ de saisie pour quelque chose.

+0

Erik, je contemplais des solutions comme celles que vous proposez. J'espère que je n'aurai pas à emprunter cette route car cela me semble un peu hack (mais peut-être que ce n'est pas le cas, peut-être que c'est juste comme ça et que je dois y faire face). D'autres idées? – StackOverflowNewbie

+0

Pas vraiment, si vous ne l'aimez pas, alors deux est une méthode de signalisation, c'est un peu comme le fonctionnement du filetage. –

+0

Ouais ... # 2 est probablement un meilleur ajustement pour mon problème. – StackOverflowNewbie