ASP.Net ScriptManager и UpdatePanel игнорируют JavaScript после публикации - PullRequest
2 голосов
/ 09 февраля 2010

У меня серьезные проблемы с использованием UpdatePanels на веб-сайте. Проблема в том, что когда я использую ScriptManager, весь клиентский JavaScript, который был активен при первоначальной загрузке страницы, теряется, как только панель обновления отправляет обратно.

Вот что я пытаюсь сделать ...

У меня есть несколько элементов управления календарем .net на одной странице, каждый из которых находится на своей собственной панели обновлений. Календари изначально скрыты, пока вы не щелкнете в соответствующем текстовом поле (также на панели обновлений), после чего появится календарь, чтобы вы могли выбрать дату. Они отлично работают, пока вы действительно не измените дату (отправьте обратно), после чего календари больше не всплывают, когда вы нажимаете в текстовых полях, JavaScript «onfocus» теряется.

Посмотрев в Google на то, что кажется часами, я могу полу-работать, динамически добавив атрибут «onfocus» в TextBox и зарегистрировав скрипт запуска в ScriptManager, когда календарь отправляет назад.

Пример:

TextBox1.Attributes.Add("onfocus", "document.getElementById('searchArrivalDateCalendarDiv').style.display = 'block';")
ScriptManager.RegisterStartupScript(Page, GetType(Page), "StopTxtClick", "$(document).ready(function(){$('.txtArrivalDate').click(function(event){event.stopPropagation(); $('div.searchArrivalDateCalendarDiv').show(); });});", True)

Это кажется непрактичным, особенно когда я представляю главную страницу. Я собираюсь в конечном итоге перерегистрировать чертовски много скриптов запуска.

Должен быть более легкий путь?

Ответы [ 3 ]

0 голосов
/ 27 февраля 2010

Проблема в том, что обновление UpdatePanel полностью уничтожает DOM в его элементах (элементах). Самый простой способ исправить это - по возможности использовать функциональность live (), например ::10000

$(document).ready(function () {
  $('.txtArrivalDate').live('click', function (event) {
    event.stopPropagation();

    $('div.searchArrivalDateCalendarDiv').show();
  });
});
0 голосов
/ 04 марта 2010

Спасибо за ответы.

Мне так и не удалось решить эту проблему. Тем не менее, я нашел альтернативное решение для всплывающего календаря.

Я сейчас использую CalendarExtender элемент управления, который является частью ASP.Net AJAX Control Toolkit. Это гораздо лучшее решение для того, что мне нужно. Календарь в целом гораздо плавнее и аккуратнее, и мне больше не нужно использовать панель обновления. Он также поддерживает несколько культур без какого-либо дополнительного кодирования, что здорово.

Приветствие.

0 голосов
/ 27 февраля 2010

Похоже, вы хотите использовать делегирование событий. Основная идея заключается в том, что события всплывают, и поэтому вы бы прикрепили обработчик событий за пределами панели обновлений (возможно, к div или таблице, в которой находится панель обновления). Этот обработчик отвечает за все события, которые он получает, поэтому даже когда ваша панель обновлений отправляет ответ и новое текстовое поле отображается, вам не нужно повторно подключать обработчик событий. Когда новое текстовое поле вызывает событие, ваш существующий обработчик событий может попытаться обработать его.

Следующее является лишь одним из способов делегирования событий в javascript (с использованием jquery и взято из http://www.danwebb.net/2008/2/8/event-delegation-made-easy-in-jquery)

jQuery.delegate = function() {
            return function(e) {
                var target = $(e.target);
                if (target.attr("showCalendar")) {
                    var calendar = $("#" + target.attr("showCalendar"));
                    calendar.css("display", "block");
                }
            }
        }

        $(document).ready(function() 
        {
            $('#test').click($.delegate());
        });

<form id="form1" runat="server">
        <asp:ScriptManager runat="server" EnablePartialRendering="true"/>
        <div id="test" style="width:100%;">
            <asp:UpdatePanel runat="server">
                <ContentTemplate>
                    <input type="text" id="testText" showCalendar="testCalendarDiv" />
                    <div id="testCalendarDiv" style="display:none;">
                        <asp:Calendar runat="server" ID="testCalendar1"/>
                    </div>
               </ContentTemplate>
           </asp:UpdatePanel>
        </div>
    </form>

В этом простом примере я регистрирую метод делегата по щелчку этого div (текстовое поле и календарь находятся внутри этого div). Когда вы щелкаете текстовое поле, событие щелчка всплывает до div. Метод делегата вызывается, и я проверяю атрибут showCalendar от элемента, вызвавшего событие. Если этот атрибут существует, я нахожу элемент, на который указывает этот атрибут, и обновляю его стиль отображения. Это довольно простой пример, но вы можете легко расширить метод делегата, чтобы он брал функции, которые он будет вызывать, основываясь на каких-то правилах, которые вы регистрируете.

...