2009-07-29 3 views
2

ASP.NET 웹 양식에 마법사 컨트롤이 있습니다. 이 완벽하게 작동하고Ajax 처리 된 마법사 컨트롤의 기본 단추 설정

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

,하지만 난 마법사 컨트롤을 ajaxify 때 작동하지 않습니다 그래서 같이 뒤에 코드에서 ApplicationWizard PreRender 이벤트의 각 단계에서 기본 설정 버튼을하고있다. 기본 단추는 폼을 처음로드 할 때 지정하는 컨트롤 (StartNextButton)로 설정되지만 다른 단계에서는 StepNextButton으로 업데이트되지 않습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

답변

0

기본 버튼의 정의는 무엇입니까? 텍스트 양식 필드 (입력 유형 = 텍스트)에서 enter를 누르면 모든 브라우저에서 양식의 첫 번째 제출 또는 이미지 버튼 (input type = submit | image) 인 단추 인 경우, 존재한다면.

당신이 할 수있는 일은 클라이언트 스크립트를 모든 컨트롤에 추가하는 것입니다. [enter]에 폼을 제출하는 것과 같은 규칙이 적용됩니다 (예 : input 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;}"); 

키 코드 == 13은이 입력 인 키
키 코드 == 27 키 이스케이프 후

1

인 하루 또는 이틀 동안 머리를 깎아 내었습니다. 나는 이것을 해소 할 수있었습니다. 다른 사람들이 저처럼 좌절감을 갖기를 바랍니다.

이 게시물을 발견 한 사람은 누구나 직관적 인 대답을 알고 있으며, 양식의 기본 버튼을 설정합니다. 다음 부토에게 마법사의 n은 아무것도하지 않습니다. 따라서 다음 논리적 단계는 사용자 대신 버튼을 클릭하여 문제를 해결하려고 시도하는 것입니다. 나는 코드 숨김 내에서 내 텍스트 상자에 아래의 핸들러를 첨부했습니다 그 myButtonId 내가 내 기본으로 필요한 버튼의 id 가정 : 당신은 위의 생각

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

가 잘 작동 것이지만, 등 마법사 버튼을 강제로 클릭하면 매우 부적절한 충돌이 발생합니다. 페이지의 첫 번째 버튼도 클릭하여 스크립트를 통해 강제로 클릭하고 매우 이상한 결과를 생성하는 초기 버튼을 무시합니다. 필자의 경우 마스터 페이지의 첫 번째 버튼은 홈이라고하는 버튼이며 사용자가 클릭하면 홈 페이지로 돌아갑니다. 따라서 마법사의 다음 버튼을 클릭하기 위해 시도한 시도에서 아무런 이유없이 보였던 것을 제 홈페이지에서 바로 끝낼 것입니다. 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 키를 누르지 않아도됩니다.

약 10 분이 걸릴 것으로 예상되는 작업을 수행하는 데 12 시간의 문제 해결 만 있습니다.

해피 코딩.

B

+0

이 문제가 있습니다. 난 당신의 대답을 기반으로 해결하려고 노력하고 있지만 그냥 작동하도록 할 수 없습니다. javascript가 추가되었지만 페이지가 다음 버튼이 아닌 홈페이지 버튼에 계속 응답합니다 .... ....? 어떤 아이디어? –

+0

안녕하세요 @ Mad Pierre - 여러 브라우저에서 사용해 보셨나요? "click()"을 결정한 Chrome과 같은 브라우저를 호출 할 수 없으며 대신 DOM2 이벤트를 생성하여 마우스 클릭을 시뮬레이트해야합니다. – Brian

+0

아직 없습니다. 나는 IE (9)로 먼저 노력하고있다. 위의 다른 의견을 다시 보았습니까? 경고를 추가하면 스크립트가 작동합니까? –

1

감사 브라이언, 스크립트는 RadAjax 여러 사용자 컨트롤 및 패널의 여러 유형을 사용하는 경우 내 자신을 설정하는 저를 도왔다. 버튼 ID를 스크립트에서가 아니라 컨트롤에서 전달하여 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로 변경했다, 나를 위해 작동하지 않았다)

+0

이것은 이상한 것입니다! 내 C# 코드를 바탕으로 기본 단추가 자바 스크립트 함수 끝에 경고가있는 경우에만 작동합니다! 즉. 내가 넣으면 function defaultButton (btnid, src, evt) { if (evt.keyCode == 13) { var btn = $ get (btnid); setTimeout (새 함수() {btn.click();}, 5); 알림 ('테스트'); } } 작동합니다! 그러나 경고 ('테스트')를 제거하면 내 기본 홈페이지 버튼이 '승리'합니다. 누구든지 아이디어가있어? 이것은 나를 위해 며칠을 지금까지 낭비했다 ..... –

0

나는 것 같아요 마침내 이것을 깨뜨렸다! 사실 자바 스크립트에서 (디버그) 경고 메시지가 올바른 방향으로 나를 가리켰다.

나는 내 방식이 비슷해 지도록 작동하도록 자바 스크립트에 몇 줄을 추가해야했다. 이 :

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

여기서는 스크립팅이 필요하지 않다고 생각합니다. 문제는 페이지에 여러 개의 제출 버튼이있는 것 같습니다. 그래서 당신은 asp.net에게 당신이 "기본"제출물로 사용하고 싶은 것을 말해야 만합니다. 페이지 수명주기의 적시에이를 말해야합니다. 내가 최선인지 모르겠지만, PreRender 이벤트에서 일하는 것 같다. 다음 코드 만 추가 된 기본 ajaxified 마법사는 적절한 단추를 사용하는 것 같습니다.

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 
관련 문제