Thomas Bandt

Über mich | Kontakt | Archiv

AutoCompleteExtender - Clientseitig auf Auswahl reagieren

Ich habe beispielhaft ein Eingabeformular für Kundendaten, in das der Anwender lediglich die ersten paar Buchstaben eines Namens oder einer Firmenbezeichnung eintragen muss, um dann vom System automatisch Vorschläge für bereits vorhandene Datensätze zu erhalten:

Das Ganze lässt sich mittels AutoCompleteExtender-Control ganz hervorragend realisieren:

<asp:TextBox ID="BoxLastname1" AutoComplete="off" runat="server"  />

<ajaxToolkit:AutoCompleteExtender
    runat="server"
    ID="AutoCompleteExtender4"
    TargetControlID="BoxLastname1"
    ServiceMethod="FindDepositorOne"
    ServicePath="~/Services/CustomerFinder.asmx"
    MinimumPrefixLength="1"
    CompletionInterval="1000"
    EnableCaching="true"
    CompletionSetCount="10" />

Das Problem: mit diesem Control lassen sich nur einfache Text-Strings darstellen, und eine Ereignisbehandlung für die Auswahl ist ebenfalls nicht vorgesehen, erst recht nicht clientseitig - selbst ist also der Entwickler.

Problem 1: Wie bekommt man nun aus der (String-) Auswahl etwa die ID für den ausgewählten Datensatz?

Ich habe mir schlicht damit beholfen, die ID bei der Ausgabe, wie oben zu sehen, am Ende mit ## abgetrennt, auszugeben, da das keinen Benutzer stören sollte. Nicht schön, aber selten.

Problem 2: Wie reagiert man nun auf eine Auswahl?

Ganz klar, erster Gedanke: AutoPostback anschalten, OnTextChanged-Methode des TextBox-Controls verwenden:

<asp:TextBox ID="BoxLastname1" AutoComplete="off" runat="server" OnTextChanged="BoxLastname1_TextChanged" AutoPostBack="true" />

Am Server wertet man dann die Auswahl aus und kann entsprechend der gewonnen ID den kompletten Datensatz holen und das Formular neu vorbelegen - was aber ein anderes Thema ist:

protected void BoxLastname1_TextChanged(object sender, EventArgs e)
{
    if(BoxLastname1.Text.IndexOf("##") > -1)
    {
        int customerID;
        int.TryParse(BoxLastname1.Text.Substring(BoxLastname1.Text.IndexOf("##") + 2), out customerID);
        if (customerID > 0)
        {
            // Formular vorbelegen
        }
    }
}

Problem 2: Das funktioniert zwar im Firefox, aber nicht im Internet Explorer!

Ja Sch... aber auch, tatsächlich. Selbst die Auswahl aus dem AutoCompleteExtender mittels Entertaste bewirkt: nichts. Also baut man den Spaß jetzt noch manuell mit JavaScript und nutzt die Arbeit gleich, um auch noch bei anderer Gelegenheit zu checken, ob etwas gewählt wurde: nämlich dann, wenn das Control verlassen wurde (JS-blur), was etwa greift, wenn man eine Auswahl mit der Maus getroffen hat, die sich anders leider nicht ohne großen Aufwand abfangen lässt:

function submitForm(field)
{
    if(field.value.lastIndexOf("##") > -1)
    {
        setTimeout('__doPostBack(\'' + field.id + '\',\'\')', 0)
    }
}

<asp:TextBox ID="BoxLastname1" AutoComplete="off" onblur="submitForm(this);" onkeyup="submitForm(this);" runat="server" OnTextChanged="BoxLastname1_TextChanged" AutoPostBack="true" />

Fertig

Siehe da: wählt der User nun mit den Pfeiltasten einen Datensatz aus und bestätigt die Auswahl mit Enter, bekommt man in jedem Browser den gewünschten Postback, um die Auswahl dann am Server sinnvoll weiterzuverarbeiten. Ebenfalls greift die Geschichte, wenn man die Auswahl anderweitig tätigt und dann etwa mit Tab weiterspringt oder den Curser mit der Maus woanders hinsetzt.

Noch ein Nachtrag: "onkeyup" bleibt als einziges zuverlässiges, im IE hier in jedem Fall greifendes Event, onchange mag er leider in dieser Kombination nicht.



« Zurück  |  Weiter »