2 Stimmen

Einstellen der Standardschaltfläche im Ajaxified Wizard Control

Ich habe ein Wizard-Steuerelement auf meinem ASP.NET-Webformular. Ich bin die Standardschaltfläche auf jedem Schritt in der ApplicationWizard PreRender-Ereignis in Code-Behind wie folgt festgelegt:

Page.Form.DefaultButton = ApplicationWizard.FindControl("StepNavigationTemplateContainerID").FindControl("StepNextButton").UniqueID;

Dies funktioniert perfekt, aber wenn ich das Wizard-Steuerelement ajaxify es nicht funktioniert. Die Standardschaltfläche wird auf das Steuerelement gesetzt, das ich beim anfänglichen Laden des Formulars angebe (StartNextButton), wird aber bei anderen Schritten nicht auf StepNextButton aktualisiert. Was mache ich falsch?

1voto

Brian Punkte 2702

Nach ein oder zwei Tagen, in denen ich mir die Haare raufte, gelang es mir, dies zu knacken... ich hoffe, das hilft anderen, die genauso frustriert waren wie ich:

Jeder, der diesen Beitrag gefunden hat, weiß, dass die intuitive Antwort, die Standardschaltfläche des Formulars auf die Schaltfläche "Weiter" Ihres Assistenten zu setzen, nichts bewirkt. Der nächste logische Schritt ist also zu versuchen, das Problem zu umgehen, indem man die Schaltfläche im Namen des Benutzers anklickt. Nehmen wir an, dass ich den untenstehenden Handler an mein Textfeld aus dem Codebehind angehängt habe und dass myButtonId die ID der Schaltfläche ist, die ich als Standard benötige:

            function textKeyDown(e) {
                if (e.keyCode == 13) {
                    var myBtn = $get(myButtonId);
                    myBtn.click();
                }
            }

Man könnte meinen, dass das oben beschriebene gut funktionieren würde, aber es stellte sich heraus, dass das Erzwingen eines Klicks auf die Schaltfläche des Assistenten einen äußerst heimtückischen Konflikt verursachte - die erste Schaltfläche auf der Seite würde ebenfalls klicken, wodurch der von mir per Skript erzwungene Klick auf die erste Schaltfläche überschrieben würde und sehr seltsame Ergebnisse erzielt würden. In meinem Fall ist die erste Schaltfläche auf meiner Musterseite eine Schaltfläche mit der Aufschrift "Startseite", und wenn der Benutzer darauf klickt, kehrt er zu seiner Startseite zurück. Wenn ich also versuchte, die Schaltfläche "Weiter" des Assistenten zum Klicken zu zwingen, landete ich ohne ersichtlichen Grund direkt auf meiner Homepage. Nach dem Anhängen an PageRequestManager.initializeRequest konnte ich sehen, dass ich zwei getrennte Postbacks initiiert hatte: 1 für meine gezwungenen Assistenten Schaltfläche klicken, und 1 für eine Schaltfläche, die nicht einmal auf meinem Radar zu der Zeit war - die Startseite Schaltfläche.

Also, lange Geschichte kurz, wenn ich das Formular Standard-Schaltfläche (Page.Form.DefaultButton) aus dem Code hinter aktualisieren, dann emittieren Sie dieses Skript aus dem Code hinter und verweisen Sie es von meinem Textfeld sowie, alles funktioniert ganz gut:

    public static void ExampleAssignDefaultButton(WizardStepBase activeWizardStep, TextBox myTextBox, IButtonControl myButton)
    {
        // create the format string for the script
        string javaScript = @"function defaultButton(src, evt){{
                                if(evt.keyCode == 13){{
                                    var btn = $get('{0}');
                                    setTimeout(new function() {{ btn.click(); }}, 5);
                                }}
                            }}";

        // format it ...
        javaScript = String.Format(javaScript, ((WebControl)myButton).ClientID);
        // register it...
        ScriptManager.RegisterClientScriptBlock(activeWizardStep, activeWizardStep.GetType(), "defaultButton", javaScript, true);

        // assign it to my textbox
        myTextBox.Attributes.Add("onkeydown", "defaultButton(this, event);");

        // also update the form's default button:
        myTextBox.Page.Form.DefaultButton = ((WebControl)myButton).UniqueID;
    }

Es ist erwähnenswert, dass ich die obige Methode immer über das OnPreRender-Ereignis des aktiven Assistentenschritts aufrufe. Es ist auch erwähnenswert, dass ich, da ich nur ein Textfeld pro Schritt in meinem Assistenten habe, dieses Verhalten nur einem einzigen Steuerelement zuweisen musste. Ich habe nicht versucht, diese Korrektur auf das Drücken der Eingabetaste auf der gesamten Seite zu übertragen, obwohl ich mir nicht vorstellen kann, dass es sich in diesem Kontext anders verhalten würde. Wenn Sie viele Eingaben pro Schritt haben, müssen Sie die Eingabetaste wahrscheinlich nicht bei jedem Steuerelement in Ihrem Assistenten abfangen.

Da haben Sie es also - nur 12 Stunden Fehlersuche für etwas, das eigentlich nur 10 Minuten dauern sollte.

Viel Spaß beim Kodieren.

B

1voto

Jack Punkte 35

Danke Brian, dein Skript hat mir geholfen, mein eigenes zu erstellen, wenn ich RadAjax und mehrere Benutzerkontrollen und mehrere Arten von Panels verwende. Sie können den defaultButton vereinfachen, indem Sie die ID der Schaltfläche aus dem Steuerelement und nicht im Skript übergeben.

Auf der Seite:

function defaultButton(btnid, src, evt) {
    if (evt.keyCode == 13) {
        var btn = $get(btnid);
        setTimeout(new function () { btn.click(); }, 5);
    }
}

Im Code:

Private Sub WizardStep_PreRender(sender As Object, e As System.EventArgs) Handles wsUserPass.PreRender, wsCompanyCode.PreRender, wsSetPassword.PreRender
    Dim button As WebControl = Nothing
    Dim activeWizardStep As WizardStepBase = CType(sender, WizardStepBase)
    Select Case activeWizardStep.StepType
        Case WizardStepType.Step
            button = activeWizardStep.FindControl("StepNavigationTemplateContainerID").FindControl("StepNextButton")
        Case WizardStepType.Start
            button = activeWizardStep.FindControl("StartNavigationTemplateContainerID").FindControl("StartNextButton")
        Case WizardStepType.Finish
            button = activeWizardStep.FindControl("FinishNavigationTemplateContainerID").FindControl("FinishButton")
    End Select
    If button Is Nothing Then Return
    Dim ctrls = FindControls(Of RadTextBox)(activeWizardStep)
    For Each ctrl In ctrls
        ctrl.Attributes.Add("onkeydown", String.Format("defaultButton('{0}', this, event);", button.ClientID))
    Next
    pnlMain.DefaultButton = button.UniqueID
End Sub

Public Shared Function FindControls(Of T)(ctrl As Control) As List(Of T)
    Dim controls As New List(Of T)
    If ctrl.Controls.Count > 0 Then
        For Each subctrl In ctrl.Controls
            If [Type].ReferenceEquals(GetType(T), subctrl.GetType()) Then
                controls.Add(subctrl)
            Else
                controls.AddRange(FindControls(Of T)(subctrl))
            End If
        Next
    End If
    Return controls
End Function

(Hinweis: UniqueID hat bei mir nicht funktioniert, ich musste es in ClientID ändern)

0voto

Artem Koshelev Punkte 10344

Versuchen Sie die ScriptManager.SetFocus .

0voto

Viktor Jevdokimov Punkte 1044

Was ist die Definition einer Standardschaltfläche? Wenn es sich um eine Schaltfläche handelt, die aufgerufen werden soll, wenn man sich in einem Textformularfeld (input type=text) befindet und die Eingabetaste drückt, dann ist es in jedem Browser die erste Submit- oder Image-Schaltfläche im Formular (input type=submit|image), falls vorhanden.

Was Sie tun können, ist, ein Client-Skript zu allen Steuerelementen hinzuzufügen, für die eine Regel wie submit form on [enter] gilt (wie bei input type="text").

Serverseitiges Beispiel (kann in Form_Init verwendet werden), nur um eine Idee zu bekommen:

SomeTextBox.Attributes.Add("onkeydown",
    "if((event.keyCode&&event.keyCode==13)){" +
    Page.ClientScript.GetPostBackEventReference(StepNextButton, "") +
    ";return false;}" +
    "if((event.keyCode&&event.keyCode==27)){" +
    Page.ClientScript.GetPostBackEventReference(CancelButton, "") +
    ";return false;}");

keyCode==13 ist eine Eingabetaste
keyCode==27 ist eine Escape-Taste

0voto

Mad Pierre Punkte 440

Ich glaube, ich habe es endlich geknackt! Die Tatsache, dass eine (Debug-) Warnmeldung in der Javascript machte es funktionieren wies mich in die richtige Richtung...

Ich musste ein paar Zeilen zum Javascript hinzufügen, um es zum Laufen zu bringen, so dass meine Methode wie folgt aussieht:

private void SetDefaultButtonScript(WizardStepBase activeWizardStep, IButtonControl myButton)
    {
        string clientID = ((WebControl)myButton).ClientID;
        string uniqueID = ((WebControl)myButton).UniqueID;

        // create the format string for the script 
        string javaScript = @"function defaultButton(btnid, evt) {{ 
                                if (evt.keyCode == 13) {{ 
                                    __doPostBack('{0}', '');
                                    var btn = $get('{1}');
                                    btn.focus();
                                    return;
                                }} 
                            }} 
                            ";
        javaScript = String.Format(javaScript, uniqueID, clientID); 

        // register it... 
        ScriptManager.RegisterClientScriptBlock(activeWizardStep, activeWizardStep.GetType(), "defaultButton", javaScript, true);

        foreach (Control c in activeWizardStep.Controls)
        {
            if (c is TextBox)
            {
                ((TextBox)c).Attributes.Add("onkeydown", "defaultButton(this, event);"); 
            }
            //TODO child controls of controls to find all text boxes, any other controls etc
        }

        Page.Form.DefaultButton = uniqueID;
    } 

Ich verwende __doPostBack anstelle von click zu, aber das war nicht das Problem.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X