2009-04-14 65 views
8

我在頁面中獲得了特別大的表單。當表單被驗證並且一個字段無效時,我想將窗口滾動到該控件。調用控件的Focus()似乎並不這樣做。我找到了一種JavaScript解決方法將窗口滾動到控件,但是ASP.NET中是否有內置的內容?ASP.NET:滾動控制

回答

2

添加MaintainScrollPositionOnPostback是ASP.NET有建於最接近的,但不一定會跳轉到無效的字段(一個或多個)。

<%@ Page MaintainScrollPositionOnPostback="true" %> 
+1

這不是他所描述的 - 他希望頁面跳轉到未通過驗證的表單部分,而不一定是用戶上次的位置。 – 2009-04-14 02:08:54

+1

它沒有回答這個問題,但他確實解決了我的問題。謝謝! – 2009-12-01 21:06:34

1

你確定Focus()不會做你所描述的嗎?在底層,它實質上是在做「JavaScript解決方法」 - 它將一些JS寫入頁面,該頁面使用匹配的ID調用控件上的focus():

Focus()在頁面完成之前調用的最後一個控件處理將其寫入頁面:

<script type="text/javascript"> 
//<![CDATA[ 
WebForm_AutoFocus('txtFocus2');//]]> 
</script> 
0

我使用基本的HTML fragments實現了類似的功能。你只是離開元素具有與已知ID:

<span id="CONTROL-ID"></span> 

,然後要麼通過腳本,在服務器端更改URL:

window.location += "#CONTROL-ID"; 

在頁面不會重新加載第一種情況下,它會向下滾動到控件。

5

所以我相信問題是因爲我試圖專注於HtmlGenericControls而不是WebControls。

我剛剛結束了做基於關閉的解決方法:

http://ryanfarley.com/blog/archive/2004/12/21/1325.aspx http://www.codeproject.com/KB/aspnet/ViewControl.aspx

......在時間的興趣。

public static void ScrollTo(this HtmlGenericControl control) 
{ 
    control.Page.RegisterClientScriptBlock("ScrollTo", string.Format(@" 

     <script type='text/javascript'> 

      $(document).ready(function() {{ 
       var element = document.getElementById('{0}'); 
       element.scrollIntoView(); 
       element.focus(); 
      }}); 

     </script> 

    ", control.ClientID)); 
} 

用法:

if (!this.PropertyForm.Validate()) 
{ 
    this.PropertyForm.ErrorMessage.ScrollTo(); 
    failed = true; 
} 

(儘管似乎Page.RegisterClientScriptBlock()已被棄用用於Page.ClientScript.RegisterClientScriptBlock())。

5

您是否在頁面上使用驗證摘要?

如果是這樣,那麼ASP.NET renders some javascript to automatically scroll to the top of the page可能會覆蓋客戶端驗證的自動行爲以關注最後一個無效控件。

另外,你有沒有關閉客戶端驗證?

如果你在客戶端驗證產生的JavaScript來看看你會看到這樣的方法:

function ValidatorValidate(val, validationGroup, event) { 
    val.isvalid = true; 
    if ((typeof(val.enabled) == "undefined" || val.enabled != false) && 
     IsValidationGroupMatch(val, validationGroup)) { 
    if (typeof(val.evaluationfunction) == "function") { 
     val.isvalid = val.evaluationfunction(val); 
     if (!val.isvalid && Page_InvalidControlToBeFocused == null && 
      typeof(val.focusOnError) == "string" && val.focusOnError == "t") { 
     ValidatorSetFocus(val, event); 
     } 
    } 
    } 
    ValidatorUpdateDisplay(val); 
} 

注意調用ValidatorSetFocus,這是一種試圖將焦點設置一個相當長的方法有問題的控制,或者如果你有多個錯誤,這是有效的,使用(最終)以下行的最後控制:

if (typeof(ctrl.focus) != "undefined" && ctrl.focus != null) { 
    ctrl.focus(); 
    Page_InvalidControlToBeFocused = ctrl; 
} 

要獲得這種行爲的工作,你會非常需要確保所有的驗證器都被設置o是客戶端 - 服務器端驗證器顯然需要回發,這可能會影響事物(即失去焦點/位置) - 並將MaintainScrollPositionOnPostBack設置爲true可能會導致頁面重新加載到提交按鈕,而不是無效的表單元素。

使用服務器端.Focus方法將導致ASP.NET呈現出一些javascript「在頁面加載」(即接近頁面底部),但這可能被上面討論的其他機制之一重寫。

2

很簡單的解決方法是設置(取其或者您正在使用驗證器控制)的RequiredFieldValidator的SetFocusOnError屬性爲true

+0

http://weblogs.asp.net/dfindley/archive/2007/06/29/a-quick-fix-for-the-validator-setfocusonerror-bug.aspx – softwaredeveloper 2011-08-12 12:55:09

0

將以下JavaScript:

function ScrollToFirstError() { 
     Page_ClientValidate(); 
     if (Page_IsValid == false) { 
      var topMostValidator; 
      var lastOffsetTop; 
      for (var i = 0; i < Page_Validators.length; i++) { 
       var vld = Page_Validators[i]; 
       if (vld.isvalid == false) { 
        if (PageOffset(vld) < lastOffsetTop || lastOffsetTop == undefined) { 
         topMostValidator = vld; 
         lastOffsetTop = vld.offsetTop; 
        } 
       } 
      } 
      topMostValidator.scrollIntoView(); 
     } 
     return Page_IsValid; 
    } 

    function PageOffset(theElement) { 
     var selectedPosY = 0; 
     while (theElement != null) { 
      selectedPosY += theElement.offsetTop; 
      theElement = theElement.offsetParent; 
     } 
     return selectedPosY; 
    } 

然後在調用ScrollToFirstError()你OnClientClick正在保存的按鈕,請確保該按鈕的CausesValidation = true。

你有它。

6
Page.MaintainScrollPositionOnPostBack = False 
Page.SetFocus(txtManagerName)