Установка кнопки по умолчанию в Ajaxified Wizard Control - PullRequest
2 голосов
/ 29 июля 2009

У меня есть элемент управления Wizard в моей веб-форме ASP.NET. Я устанавливаю кнопку по умолчанию на каждом шаге события ApplicationWizard PreRender в выделенном фрагменте кода следующим образом:

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

Это работает отлично, но когда я настраиваю элемент управления Wizard, он не работает. Кнопка «По умолчанию» установлена ​​на элемент управления, который я указываю при начальной загрузке формы (StartNextButton), но не обновляется до StepNextButton на других этапах. Что я делаю не так?

Ответы [ 6 ]

1 голос
/ 23 сентября 2011

Спасибо, Брайан, ваш скрипт помог мне настроить мой собственный при использовании RadAjax и нескольких пользовательских элементов управления и нескольких типов панелей. Кнопку defaultButton можно упростить, передав идентификатор кнопки из элемента управления, а не из сценария.

На странице:

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

В коде:

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

(Обратите внимание, у меня не работал UniqueID, пришлось изменить его на ClientID)

1 голос
/ 20 июля 2011

После дня или двух, потянув за волосы, мне удалось это взломать ... надеюсь, это поможет другим таким же разочарованным, как и я:

Любой, кто нашел этот пост, знает, что интуитивный ответ здесь, установив для кнопки по умолчанию формы кнопку «Далее» вашего Мастера, ничего не делает. Итак, следующий логический шаг - попытаться обойти проблему, нажав кнопку от имени пользователя. Предположим, что я прикрепил описанный ниже обработчик к своему текстовому полю изнутри codebehind и что myButtonId - это идентификатор кнопки, которая мне нужна по умолчанию:

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

Вы могли бы подумать, что вышеприведенное будет работать просто отлично, но, как оказалось, принудительное нажатие кнопки Wizard вызывало чрезвычайно скрытый конфликт - первая кнопка на странице также будет щелкать, переопределяя исходное нажатие кнопки, которое я принудительно нажал. с помощью сценария и создания очень странных результатов. В моем случае первая кнопка на моей главной странице - это кнопка «Home», и когда пользователь нажимает на нее, он возвращается на свою домашнюю страницу. Поэтому, пытаясь заставить нажать кнопку «Далее» мастера, я снова оказался на своей домашней странице, что было совершенно бессмысленно. После присоединения к PageRequestManager.initializeRequest я смог увидеть, что у меня было два отдельных постбэка, инициирующих: 1 для нажатия кнопки моего принудительного мастера и 1 для кнопки, которой в то время даже не было на моем радаре - кнопка домашней страницы.

Итак, короче говоря, если я обновлю кнопку формы по умолчанию (Page.Form.DefaultButton) изнутри кода, а затем выведу этот скрипт изнутри кода и также буду ссылаться на него из моего текстового поля, все работает просто штраф:

    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;
    }

Стоит отметить, что я всегда вызываю вышеуказанный метод из события OnPreRender активного шага мастера. Также стоит отметить, что, поскольку у меня в мастере только одно текстовое поле на шаг, мне нужно было назначить это поведение только одному элементу управления. Я не пытался использовать это исправление, чтобы поймать нажатие клавиши Enter на всей странице, хотя я не могу представить, что в этом контексте он будет вести себя по-другому. Вам, вероятно, не нужно ловить клавишу Enter на каждом элементе управления в вашем мастере, если у вас много входов на шаг.

Итак, у вас это есть - всего 12 часов на устранение неполадок, чтобы сделать что-то, что должно было занять около 10 минут.

Удачного кодирования.

B

0 голосов
/ 05 июня 2012

Я не думаю, что вам нужен какой-либо сценарий здесь. Кажется, проблема в том, что на странице есть несколько кнопок отправки. Таким образом, вы должны указать asp.net, какой из них вы хотите использовать в качестве отправки по умолчанию. И вы должны сказать это в нужное время в жизненном цикле страницы. Я не уверен, что это оптимально, но кажется, что делать это в событии PreRender. Кажется, что обычный базовый мастер с добавлением следующего кода использует соответствующую кнопку:

Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs)
    MyBase.OnPreRender(e)
    Select Case LoginWizard.ActiveStep.StepType
        Case WizardStepType.Start
            Page.Form.DefaultButton = LoginWizard.FindControl("StartNavigationTemplateContainerID").FindControl("NextStart").UniqueID
        Case WizardStepType.Step
            Page.Form.DefaultButton = LoginWizard.FindControl("StepNavigationTemplateContainerID").FindControl("NextStep").UniqueID
        Case WizardStepType.Finish
            Page.Form.DefaultButton = LoginWizard.FindControl("FinishNavigationTemplateContainerID").FindControl("LastStep").UniqueID
    End Select
End Sub
0 голосов
/ 10 февраля 2012

Я думаю, что наконец-то взломал это! Тот факт, что (отладочное) предупреждающее сообщение в javascript заставило его работать, указало мне правильное направление ...

Мне пришлось добавить пару строк в javascript, чтобы заставить его работать так, чтобы мой метод выглядел следующим образом:

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;
    } 

Я использую __doPostBack вместо клика, но это не проблема.

0 голосов
/ 06 августа 2009

Каково определение кнопки по умолчанию? Если это кнопка, которую нужно вызывать, когда вы находитесь в поле текстовой формы (тип ввода = текст) и нажимаете ввод, то в каждом браузере это первая кнопка отправки или изображения в форме (тип ввода = отправить | изображение) если существует.

Что вы можете сделать, это добавить клиентский скрипт ко всем элементам управления, к которому применяется такое правило, как форма отправки при [enter] (например, при вводе type = "text").

Пример на стороне сервера (может использоваться в Form_Init) только для идеи:

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 - это клавиша ввода
keyCode == 27 - это клавиша Escape

0 голосов
/ 03 августа 2009

Попробуйте ScriptManager.SetFocus .

...