2009-04-28 32 views
22

Estamos utilizando el complemento de jquery de autocompletar escrito por Jörn Zaefferer, y estamos tratando de verificar que se ingrese una opción válida.JQuery Autocompletar verificar el valor seleccionado

El complemento tiene el evento result() que se dispara cuando se realiza una selección. Esto está bien, pero necesito verificar el valor en el cuadro de texto cuando un usuario hace clic también. Así que hemos probado los eventos .change() y .blur(), pero ambos plantean un problema: cuando haces clic en una entrada en el resultado div (la lista 'suggest') el .change() y .blur() los eventos se disparan, y esto es antes de que el complemento haya escrito un valor para el cuadro de texto, por lo que no hay nada que verificar en este momento.

Podría alguien ayudarme a configurar los eventos para que cada vez que alguien hace clic, pero no en el cuadro de resultados, pueda verificar un valor válido en el cuadro. Si este es el enfoque equivocado, infórmeme cuál es el correcto. Originalmente fuimos con este complemento debido a su opción 'mustMatch'. Esta opción no parece funcionar en todos los casos. Muchas veces se escribirá una entrada válida en el cuadro de texto y, una vez borrado por el complemento como no válido, no he podido determinar por qué.

Ejemplo de código básica:

<html> 
<head> 
<title>Choose Favorite</title> 
<script language="JavaScript" src="jquery-1.3.2.min.js" ></script> 
<script language="JavaScript" src="jquery.autocomplete.min.js" ></script> 
<script> 
    $(".suggest").autocomplete("fetchNames.asp", { 
     matchContains:false, 
     minChars:1, 
     autoFill:false, 
     mustMatch:false, 
     cacheLength:20, 
     max:20 
    }); 

    $(".suggest").result(function(event, data, formatted) { 
     var u = this; 
     // Check value here 

    }); 

    /* OR */ 

    $(".suggest").change(function(me) { 
     //check value here 
    }); 

</script> 
</head> 
<body> 
    <label for="tbxName">Select name (I show 10):</label><br /> 
    <INPUT type="text" id="tbxName" name="tbxName" class="suggest"><br /> 
</body> 
</html> 
+0

He encontrado la mejor respuesta aquí por Victor http://stackoverflow.com/questions/4952094/jquery-ui-autocomplete-only-allow-selected-valued-from-suggested-list –

+0

Es decir una solución decente Tendré que intentarlo la próxima vez que necesite esta funcionalidad. – Brettski

+0

ver que: http://stackoverflow.com/questions/1267149/how-to-detect-when-user-ignores-jquery-autocomplete-suggestions –

Respuesta

4

ACTUALIZACIÓN: Esto debería funcionar. Estoy cargando la lista de nombres en un Array llamado ListOfNames, esto se usa en el evento onBlur() para verificar el nombre ingresado contra los datos. Es posible que deba hacer algunos ajustes, pero creo que debería hacer lo que está buscando.

var listOfNames = []; 
$(document).ready(function(){ 
    $.get("fetchNames.asp", function(data){ 
    listOfNames = data.split("\r\n");  
    }); 
    $(".suggest").autocomplete("fetchNames.asp", { 
     matchContains:false, 
     minChars:1, 
     autoFill:false, 
     mustMatch:false, 
     cacheLength:20, 
     max:20 
    }); 
    $("#tbxName").blur(function(){ 
     if(!listOfNames.containsCaseInsensitive(this.value)){ 
      alert("Invalid name entered"); 
     } 
    });   
}); 

Array.prototype.containsCaseInsensitive = function(obj) { 
    var i = this.length; 
    while (i--) { 
    if (this[i].toUpperCase() === obj.toUpperCase()) { 
     return true; 
    } 
    } 
    return false; 
} 
+0

Gracias por su respuesta. Esto no lo está haciendo del todo.Si selecciono un valor, se completa correctamente, una vez que hago clic en él, los errores no son válidos. Si ingreso un par de caracteres y hago clic en "de distancia", no se genera ningún error, aunque sí tengo que agregar mi verificación de BD. – Brettski

+0

¿Qué se dispara primero, .blur() o .change()? – Brettski

+0

Gracias de nuevo por su respuesta. Los nombres posibles que pueden volver de fetchnames.asp son 32,000, no estoy seguro si quiero almacenar todos esos datos en una matriz. Me gusta el enfoque aunque – Brettski

9

creo que en lugar de escribir su propia función para verificar si los datos coinciden, sólo puede llamar a search(). Si se llama al result() con un parámetro data nulo, entonces usted sabe que no se utilizó el autocompletado y llamando al search() en blur, se garantiza que obtendrá result() llamada al menos una vez.

He publicado este código para a similar question, puede ayudar aquí también.

autocompleteField.result(function(event, data, formatted) { 
    if (data) { 
     //auto-complete matched 
     //NB: this might get called twice, but that's okay 
    } 
    else { 
     //must have been triggered by search() below 
     //there was no match 
    } 
}); 

autocompleteField.blur(function(){ 
    autocompleteField.search(); //trigger result() on blur, even if autocomplete wasn't used 
}); 
+0

¡Buena respuesta! ¿Sabes cómo evitar que el evento resultante se active dos veces? Este es el problema, si este evento realiza alguna lógica compleja, como validar la entrada en el servidor a través de la solicitud ajax. – Kamarey

+0

Si está procesando mucho en '.result()', puede intentar mantener una marca para ver si su rama 'if (data)' ya ha sido llamada. Sin embargo, puedo advertirle que esto no será trivial: puede establecer fácilmente el indicador al final de 'if (data)', pero deberá borrarlo en los casos en que el usuario edite la sugerencia completada automáticamente. Yo trataría de usar '.change()' para eso. ¡Buena suerte! – npdoty

0

utilizo una estructura global de datos para realizar un seguimiento de los valores que se encontraron

var ac_sent = {}; 

el controlador de eventos .result() es llamado antes de que el controlador de eventos .Cambiar(), por lo que en. (resultado de eventos, datos, formateados) añado los datos de la estructura:

ac_sent[ data ] = true; 

luego en la .Cambiar (evento) gestor de eventos puedo comprobar para ver si hay un tema en ac_sent [datos], y si no hay ninguno, sé que el wo no se encontró rd:

$("#textbox").change(function(event) { 

    var data = event.target.value; 

    if (!ac_sent[ data ]) { 
    // result was not found in autocomplete, do something... 
    ac_sent[ data ] = true; // remember that we processed it 
    } 

    return false; 
}); 
+0

El desencadenante del evento result() antes del evento change() no es 100% exacto. Sucede en ese orden si la tecla Intro se usa para seleccionar un elemento de la lista. Sin embargo, si se usa el mouse, el orden de los eventos se invierte: change() ocurre primero, seguido de result(). – Jason

1

Este es el código que he usado en el pasado. Muy limpio y simple.

var availableTags = [ 
    "ActionScript", 
    "AppleScript", 
    "Asp", 
    "BASIC", 
    "C", 
    "C++", 
    "Clojure", 
    "COBOL", 
    "ColdFusion", 
    "Erlang", 
    "Fortran", 
    "Groovy", 
    "Haskell", 
    "Java", 
    "JavaScript", 
    "Lisp", 
    "Perl", 
    "PHP", 
    "Python", 
    "Ruby", 
    "Scala", 
    "Scheme" 
]; 
$("#currentSelectedLevel").autocomplete({ 
    source: availableTags, 
    change: function(event, ui) { 
     val = $(this).val(); 
     exists = $.inArray(val,availableTags); 
     if (exists<0) { 
      $(this).val(""); 
      return false; 
     } 
     } 
}); 
+0

Solución más limpia con diferencia. Tenga en cuenta que querrá asegurarse de que el 'val' se escribe en mayúscula de acuerdo con su fuente de datos, de lo contrario no coincidirá. P.ej. 'actionscript' no es lo mismo que' ActionScript'. – Optimae

Cuestiones relacionadas