Thomas Bandt

Über mich | Kontakt | Archiv

ASP.NET 2.0: DefaultButton

Weil das Thema immer wieder einmal aufkommt, und ich es (zumindest nach meiner Suche) noch nicht hier erwähnt habe, kurz ein paar Worte zum Thema DefaultButton-Attribut des Panel-WebControls.

Das Ganze gehört in die Rubrik "Dinge, die das Leben leichter machen".

Worum geht es?

Jeder, der mit ASP.NET entwickelt, gelangt früher oder später an den Punkt, wo er "mehrere Formulare" in seiner Seite benötigt. PHP-Entwickler werden sich hier verwundert die Augen reiben - aber ja, mit dem WebForm wurde quasi das Konzept des WinForm übernommen, in ASP.NET gibt es seit jeher nur noch ein Formular. Zumindest ein intelligentes, mit dem sich arbeiten lässt.

Trotzdem kommt man natürlich oft in die Situation, eigentlich mehrere logisch von einander getrennte Formularbereiche nutzen zu wollen oder zu müssen. Vielleicht lagert man diese auch noch in UserControls aus, und hat nun wirklich die Logik serverseitig getrennt. Am Client landet aber - wohl am häufigsten von mir gepredigt - wieder nur eine dumme HTML-Seite.

Füllt man nun in eines der Formulare seine Werte ein und hackt dann als geübter Benutzer nur noch einmal auf die Enter-Taste, kann das zu einer unliebsamen Überraschung führen: nämlich dann, wenn der betätigte Button bzw. das abgeschickte "Formular" nicht an erster Stelle steht.

Dann wird zwar ein Postback ausgelöst, ASP.NET kann diesen aber nicht richtig zuordnen - Folge: das Ereignis am Server, d.h. die Behandlung des Codes im UserControl etwa, tritt nicht ein - es passiert nichts.

Was kann man dagegen tun?

Unter ASP.NET 1.1 musste man sich noch eigene Lösungen basteln und dabei zu eigenem JavaScript-Clientcode greifen. Bei 2.0 wurde an das Problem gedacht, und es für 99% aller Fälle auch gelöst. Wie? Ganz einfach: man packe einfach ein Panel um sein Formular, bestimme den DefaultButton, fertig:

<asp:Panel id="MeinLogischesFormular" runat="server" DefaultButton="Button1">
    <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
    <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
</asp:Panel>

Betätigt man nun z.B. in der TextBox die Enter-Taste, wird automatisch Button1 ausgeführt, egal wie viele andere Buttons sich noch auf der Seite befinden.

Was macht ASP.NET 2.0?

Es rendert aus dem Panel ein DIV-Element, welches ein entsprechendes JS-Event definiert:

<div id="ctl00_ContentPlaceHolder1_EasyTabs1_ctl08_1_container" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'ctl00_ContentPlaceHolder1_EasyTabs1_ctl08_1_Button1')">

Das gilt nun für alles, was darin steht, d.h. alle Formularelemente. Das Script, was hier ausgeführt wird, ist selbst übrigens keine Hexerei. Für alle, die noch mit 1.1 oder gar 1.0 arbeiten müssen, füge ich es mal bei:

function WebForm_FireDefaultButton(event, target) {
        if (event.keyCode == 13 && !(event.srcElement && (event.srcElement.tagName.toLowerCase() == "textarea"))) {
        var defaultButton;
        if (__nonMSDOMBrowser) {
            defaultButton = document.getElementById(target);
        }
        else {
            defaultButton = document.all[target];
        }
        if (defaultButton && typeof(defaultButton.click) != "undefined") {
            defaultButton.click();
            event.cancelBubble = true;
            if (event.stopPropagation) event.stopPropagation();
            return false;
        }
    }
    return true;
}

Kommentare

  1. bülent schrieb am Mittwoch, 16. Juli 2008 14:32:00 Uhr:

    habe heute so ein problem gehabt. vielen dank für den blog


« Zurück  |  Weiter »