ASP.NET: прокрутите для управления

У меня на странице особенно большая форма. Когда форма проверена и поле недействительно, я хочу прокрутить окно до этого элемента управления. Вызов элемента управления Focus (), похоже, этого не делает. Я нашел обходной путь JavaScript для прокрутки окна до элемента управления, но есть ли что-нибудь встроенное в ASP.NET?


person core    schedule 14.04.2009    source источник


Ответы (9)


Вы используете на своей странице сводку проверки?

Если это так, ASP.NET отображает некоторый javascript для автоматической прокрутки вверху страницы, что вполне может переопределить автоматическое поведение проверки на стороне клиента, чтобы сфокусироваться на последнем недопустимом элементе управления.

Кроме того, вы отключили проверку на стороне клиента?

Если вы посмотрите на 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;
}

Чтобы заставить это поведение работать, вам в идеале необходимо убедиться, что все ваши валидаторы настроены на клиентскую сторону - валидаторы на стороне сервера, очевидно, потребуют обратной передачи, и это может повлиять на вещи (например, потерять фокус / позицию) - и установить MaintainScrollPositionOnPostBack значение true, вероятно, приведет к перезагрузке страницы на кнопку отправки, а не на недопустимый элемент формы.

Использование метода .Focus на стороне сервера приведет к тому, что ASP.NET будет отображать некоторый javascript «при загрузке страницы» (т. Е. В нижней части страницы), но это может быть отменено одним из других механизмов, рассмотренных выше.

person Zhaph - Ben Duguid    schedule 15.04.2009

Итак, я считаю, что проблема в том, что я пытался сосредоточиться на 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 ()).

person core    schedule 14.04.2009

Добавление MaintainScrollPositionOnPostback является наиболее близким из того, что встроено в ASP.NET, но не обязательно будет переходить к недопустимым полям.

<%@ Page MaintainScrollPositionOnPostback="true" %>
person Lance Harper    schedule 14.04.2009
comment
Он описывает не это - он хочет, чтобы страница перешла к той части формы, которая не прошла валидацию, не обязательно к той позиции, в которой пользователь был в последний раз. - person Rex M; 14.04.2009
comment
Это не отвечает на вопрос, но он решил мою проблему. Спасибо! - person Randy Stegbauer; 02.12.2009

Очень простое решение - установить для свойства SetFocusOnError RequiredFieldValidator (или любого другого элемента управления-валидатора, который вы используете) значение true.

person Community    schedule 01.06.2010
comment
weblogs.asp.net/dfindley/archive/2007/06/29/ - person softwaredeveloper; 12.08.2011

Вы уверены, что Focus () не будет делать то, что вы описываете? Под капотом он, по сути, выполняет «обходной путь JavaScript» - он записывает некоторый JS на страницу, которая вызывает focus () для элемента управления с соответствующим идентификатором:

Какой бы элемент управления ни был вызван Focus () последним перед завершением обработки страницы, записывает это на страницу:

<script type="text/javascript">
//<![CDATA[
WebForm_AutoFocus('txtFocus2');//]]>
</script>
person Rex M    schedule 14.04.2009

Вам следует изучить jQuery и плагин ScrollTo.

http://demos.flesler.com/jquery/scrollTo/

person Superdumbell    schedule 14.04.2009

Я добился чего-то подобного, используя базовые фрагменты HTML. . Вы просто оставляете элемент с известным идентификатором:

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

А затем либо через скрипт, либо на стороне сервера измените URL-адрес:

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

В первом случае страница не перезагружается, а просто прокручивается до элемента управления.

person DreamSonic    schedule 14.04.2009

Вставьте следующий 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.

Вот и все.

person emalamisura    schedule 28.02.2012
comment
Отличное предложение. Я немного улучшил его, чтобы прокрутить фактический оскорбительный элемент управления в поле зрения, изменив строку на: document.getElementById (topMostValidator.controltovalidate) .scrollIntoView (); - person Derek Wade; 14.01.2020

person    schedule
comment
А где именно писать Page.MaintainScrollPositionOnPostBack = False? - person Masoud Keshavarz; 27.08.2014