2009-04-28 23 views
22

Wir verwenden das Autocomplete-jquery-Plugin, das von Jörn Zaefferer geschrieben wurde, und versuchen zu überprüfen, ob eine gültige Option eingegeben wurde.JQuery Autocomplete überprüfen ausgewählten Wert

Das Plugin hat result() -Ereignis, das ausgelöst wird, wenn eine Auswahl getroffen wird. Das ist in Ordnung, aber ich muss den Wert in der Textbox überprüfen, wenn ein Benutzer auch klickt. Wir haben also eine .change() - und. Blur() -Ereignisse ausprobiert, aber beide stellen ein Problem dar: Wenn Sie auf einen Eintrag im Ergebnis-Div klicken (die 'Vorschlagsliste'), werden .change() und .blur() Ereignisse feuern, und dies ist, bevor das Plugin einen Wert in das Textfeld geschrieben hat, so dass an dieser Stelle nichts zu überprüfen ist.

Könnte mir jemand helfen, Ereignisse zu konfigurieren, also wenn immer jemand klickt, aber nicht in der Ergebnisbox kann ich nach einem gültigen Wert in der Box suchen. Wenn dies der falsche Ansatz ist, informieren Sie mich bitte über den richtigen. Wir gingen ursprünglich mit diesem Plugin wegen seiner "mustMatch" -Option. Diese Option scheint nicht in allen Fällen zu funktionieren. Oftmals wird ein gültiger Eintrag in das Textfeld geschrieben und dann vom Plugin als ungültig gelöscht, ich konnte nicht feststellen warum.

Basic-Code Beispiel:

<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

fand ich die beste Antwort hier von Victor http://stackoverflow.com/questions/4952094/jquery-ui-autocomplete-only-allow-selected-valued-from-suggested-list –

+0

Das ist eine anständige Lösung. Ich werde das nächste Mal versuchen müssen, wenn ich diese Funktionalität brauche. – Brettski

+0

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

Antwort

4

UPDATE: Das sollte funktionieren. Ich lade die Liste der Namen in ein Array mit dem Namen ListOfNames, das im Ereignis onBlur() verwendet wird, um den Namen zu bestätigen, der mit den Daten eingegeben wurde. Möglicherweise müssen Sie einige Verbesserungen vornehmen, aber ich denke, es sollte tun, was Sie suchen.

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

Vielen Dank für Ihre Antwort. Das tut es nicht ganz.Wenn ich einen Wert auswähle, wird dieser korrekt ausgefüllt, sobald ich ihn weggebe, fehler, ungültig. Wenn ich ein paar Zeichen eingebe, dann klicke weg, es wird kein Fehler angezeigt, obwohl ich meinen DB-Check anzeigen muss. – Brettski

+0

Was wird zuerst ausgelöst, .blur() oder .change()? – Brettski

+0

Nochmals vielen Dank für Ihre Antwort. Mögliche Namen, die von fetchnames.asp zurückkommen können, sind 32.000, nicht sicher, ob ich alle diese Daten in einem Array speichern möchte. Ich mag den Ansatz obwohl – Brettski

9

Ich denke eher, als die eigene Funktion zu schreiben, um zu überprüfen, ob die Daten übereinstimmt, können Sie einfach search() nennen. Wenn result() mit einem Null-data-Parameter aufgerufen wird, wissen Sie, dass die automatische Vervollständigung nicht verwendet wurde, und indem Sie search() auf Unschärfe aufrufen, werden Sie garantiert mindestens result() aufgerufen.

Ich habe diesen Code für a similar question gepostet, es kann auch hier helfen.

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

Gute Antwort! Wissen Sie vielleicht, wie Sie verhindern können, dass das Ereignis zweimal ausgelöst wird? Dies ist das Problem, wenn dieses Ereignis eine komplexe Logik ausführt, wie die Eingabe auf dem Server über eine Ajax-Anfrage validieren. – Kamarey

+0

Wenn Sie in '.result()' viel verarbeiten, können Sie versuchen, ein Flag zu erhalten, um zu sehen, ob Ihr 'if (data)' - Zweig bereits aufgerufen wurde. Ich kann Sie warnen, dass dies nicht-trivial sein wird: Sie können die Markierung am Ende von "if (data)" leicht setzen, aber Sie müssen es löschen, wenn der Benutzer den automatisch vervollständigten Vorschlag bearbeitet. Ich würde versuchen, '.change()' dafür zu verwenden. Viel Glück! – npdoty

0

Ich benutze eine Struktur globalen Datenspur der Werte zu halten, die

var ac_sent = {}; 

die .RESULT() Ereignishandler vor dem .change() aufgerufen wird Event-Handler gefunden wurden, so in. Ergebnis (Ereignis, Daten, formatiert) ich die Daten der Struktur hinzufügen:

ac_sent[ data ] = true; 

dann im .change (Ereignis) Ereignishandler ich überprüfen, um zu sehen, ob es sich um ein Angebot an ac_sent [Daten], und wenn es gibt keine, ich weiß, dass die wo rd wurde nicht gefunden:

$("#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

Das Ereignis result(), das vor dem Ereignis change() ausgelöst wird, ist nicht 100% genau. Es geschieht in dieser Reihenfolge, wenn die Eingabetaste zum Auswählen eines Elements aus der Liste verwendet wird. Wenn die Maus jedoch verwendet wird, wird die Reihenfolge der Ereignisse umgekehrt - change() passiert zuerst, gefolgt von result(). – Jason

1

Dies ist der Code, den ich in der Vergangenheit verwendet habe. Sehr sauber und einfach.

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

Sauberste Lösung bei weitem. Beachten Sie, dass Sie sicherstellen müssen, dass das "val" entsprechend groß ist, um Ihre Datenquelle zu erfüllen, andernfalls wird es nicht übereinstimmen. Z.B. 'actionscript' ist nicht dasselbe wie 'ActionScript'. – Optimae