Обратные вызовы вкладок JQuery UI не работают - PullRequest
0 голосов
/ 26 декабря 2009

Я пытался заставить это работать в течение последних 7 часов, поэтому, пожалуйста, извините за небольшой тон разочарования.

Я успешно реализовал замечательный набор вкладок jquery ui, которые загружают их содержимое через ajax.

Контент, загружаемый через ajax, имеет форму. Я хотел, чтобы первое поле в форме (с идентификатором #title) было сфокусировано автоматически при загрузке вкладки. Это не сработало, когда я попытался поместить скрипт во внешний документ, поэтому я подумал, что обратный вызов будет хорошей идеей.

setTimeout( function() { $("#title").focus(); }, 500 );

Я получил эту идею от здесь . Задержка вызвана тем, что у меня были проблемы с полем, которое не фокусировалось должным образом при нажатии на каждую вкладку. Сначала я подумал, что это решило некоторые проблемы, однако после еще большего тестирования я обнаружил, что это поле фокусировки работает только на вкладке, которая была первоначально загружена.

Я решил очистить голову и реализовать текстовое поле nice jquery autocomplete.

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

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

Я пытался использовать события выбора, загрузки и показа, но все они не работают.

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

Очевидно, я делаю что-то очень неправильное.

Пожалуйста, соберите мой код и расскажите, что я делаю не так.

<script type="text/javascript">
    $(function() {
        $("#tabs").tabs({
         load: function(event, ui) { setTimeout( function() { $("#title").focus(); }, 500 );
                $("#role").autocomplete(
                    "/profile/autocomplete",
                    {
                        delay:10,
                        minChars:1,
                        matchSubset:1,
                        matchContains:1,
                        cacheLength:10,
                        onItemSelect:selectItem,
                        onFindValue:findValue,
                        formatItem:formatItem,
                        autoFill:true
                    }
                );

            alert('callback');
                }
            });

        });
    </script>

Ответы [ 3 ]

2 голосов
/ 26 декабря 2009

Ваша проблема не совсем понятна из вопроса. Я бы сказал, что часть $ (document) .ready определенно не нужна, но, вероятно, не вызовет никаких проблем, так как я думаю, что она запустится немедленно.

В чем я не уверен, так это в том, как вы создаете свои вкладки, и в особенности в том, что вы подразумеваете под «только при первой загрузке вкладок, загрузка другой вкладки не фокусирует поле». Что именно вы подразумеваете под нагрузкой? Загружаются ли вкладки с помощью вызова Ajax или вы просто имеете в виду, что страница отображается? Вы хотите, чтобы конкретный элемент был сфокусирован на теге PER, или просто при каждой загрузке тега? (В вашем коде написано одно конкретное поле, но ваш текст неясен).

Хорошо, основываясь на ваших пояснениях, теперь я понимаю, что проблема в том, что у вас есть несколько экземпляров 'title' и 'role', но вы используете идентификаторы для именования и ссылки на них. В HTML у вас есть что-то вроде этого

<div id="tabs">
    <div class="tab">
        <input id="title">
        <input id="role">
    </div>
    <div class="tab">
        <input id="title">
        <input id="role">
    </div>
    ...
    etc
</div>

Проблема в том, что поле 'id' должно быть уникальным для всех ваших элементов, в противном случае вы можете ссылаться только на один из них (а не только на каждую вкладку). Поэтому, когда вы говорите $ ('# title'), вы можете ссылаться только на первый элемент с идентификатором 'title'. Многие люди решают эту проблему, добавляя числа и идентификаторы на вкладках «tab1», «tab2» и т. Д., А также «title1», «title2» и т. Д. Это на самом деле плохая идея с jquery. Вместо этого вы должны использовать классы и очень полезный метод jquery .find (), например:

<script type="text/javascript">
    $(function() {
        $("#tabs").tabs({
            load: function(event, ui) {
                var tab_content = $(ui.panel);
                setTimeout( function() { tab_content.find(".title").focus(); }, 500 );
                tab_content.find(".role").autocomplete(
                    "/profile/autocomplete",
                    {
                        delay:10,
                        minChars:1,
                        matchSubset:1,
                        matchContains:1,
                        cacheLength:10,
                        onItemSelect:selectItem,
                        onFindValue:findValue,
                        formatItem:formatItem,
                        autoFill:true
                    }
                );
                alert('callback');
            }
        });
    });
</script>

Все еще не уверен, что тайм-аут на фокусировке необходим. Вы должны удалить это, если это была просто попытка «заставить что-то работать».

2 голосов
/ 26 декабря 2009

Я считаю, что проблема в том, что у вас нет уникальных идентификаторов. Если ваш HTML похож на это:

<div class="tabs">
 <ul>
  <li><a href="tab1.htm">Tab1</a></li>
  <li><a href="tab2.htm">Tab2</a></li>
 </ul>
</div>

Плагин Tab загрузит обе страницы (tab1.htm и tab2.htm) на текущую страницу. А поскольку на первой вкладке есть и #title, и #role, jQuery прекращает поиск дубликата (это правильно). Таким образом, простым решением было бы сделать их классами, а затем настроить функцию show на выбранную вкладку и вызвать плагин focus и автозаполнение.

$(function(){
 $(".tabs").tabs({
  show: function(e, ui) {
   $(ui.panel)  // target the current tab contents
    .find('.title').focus().end()
    .find('.role').autocomplete(
      "/profile/autocomplete",
      {
       delay:10,
       minChars:1,
       matchSubset:1,
       matchContains:1,
       cacheLength:10,
       onItemSelect:selectItem,
       onFindValue:findValue,
       formatItem:formatItem,
       autoFill:true
      }
     );
  }
 });
});

И чтобы ответить на вопрос, который у вас был в комментарии, обратный вызов - это, по сути, то, что вы хотите сделать после того, как все, что вы делали, завершено. Например, приведенная ниже функция будет скрывать элемент с классом hideme, а затем, когда эффект fadeOut будет завершен, функция обратного вызова удаляет элемент со страницы (и DOM)

$('.hideme').fadeOut('slow', function(){
 $(this).remove();
})

Кроме того, если вы не знакомы с .end(), это позволяет вам связывать объекты. Точнее говоря, он возвращает селектор обратно к самому последнему объекту, который в этом случае ui.panel. Подробнее об этом здесь , а также обязательно ознакомьтесь с .andSelf() здесь .

0 голосов
/ 26 декабря 2009

Не уверен на 100%, но это может быть потому, что вы включили код обработки в $(document).ready(function() { ... });.

...