it-swarm.com.ru

Конфликт с двумя jquery DatePickers на одной странице

Итак, вот настройка: У меня есть два средства выбора даты jquery, внутри вкладки jquery, внутри модального диалогового окна jquery:

\---/\---/\---/_______________
/                            /
\                            \
/  DATEPICKER1               /
\                            \
/  DATEPICKER2               /
\                            \
/                            /
\                            \
/____________________________/

Первый указатель даты работает нормально, но когда я пытаюсь щелкнуть дату во втором указателе даты, он просто активирует первое. Вы следили за этим? :)

Итак, чтобы подвести итог, нажатие на дату в datepicker2 активирует datepicker1.

Я понятия не имею, почему это происходит - у них разные идентификаторы и имена, как показано ниже.

Для создания DatePickers я просто использую:

$(function() {
    $("#datepicker1").datepicker();
    $("#datepicker2").datepicker();
});

Поля просто:

<input type="text" id="datepicker1" name="datepicker1" value="" />
<input type="text" id="datepicker2" name="datepicker2" value="" />

Я использую jQuery v1.9.0 и jQueryui v1.10.0.

Есть мысли по этому поводу? В качестве предупреждения, я не могу опубликовать фактический код из-за ограничений со стороны моего работодателя, но я могу ответить на большинство вопросов, если вам нужны какие-либо разъяснения. Любая помощь будет принята с благодарностью!

22
musicmunky

UPDATE: Похоже, что описанное ниже поведение было рассмотрено в другом вопросе о стекопереработке здесь:
Запретить диалогу jQuery UI установить фокус на первое текстовое поле

Извиняюсь за «дублирующий» вопрос - если бы я знал, что это была проблема, я бы понял это быстро !!!

################################################## ##############################

Ну, решение очень простое, и, возможно, кто-то может объяснить мне, почему это работает таким образом, потому что я немного невежественен в данный момент.

Вот что я сделал:
Я добавил в форму еще два поля ввода текста (они были необходимы) и изменил порядок расположения так, чтобы одно из этих новых полей ввода было «первым» элементом (в верхнем левом углу), например, так:

\---/\---/\---/_______________
/                            /
\                            \
/  TEXTFIELD1   DATEPICKER1  /
\                            \
/  TEXTFIELD2   DATEPICKER2  /
\                            \
/                            /
\                            \
/____________________________/

Внезапно проблема исчезла! Тем не менее, я замечаю интересное поведение:
Когда я выбираю дату в EITHER datepicker, курсор сразу же переходит обратно к первому текстовому полю . Так что, если бы это происходило, когда у меня были указатели даты без текстовых полей, такое поведение означало бы, что курсор будет немедленно перескочил назад к первому сборщику дат, который мог вызвать проблему, с которой я столкнулся.

Теперь о том, ПОЧЕМУ это работает, я понятия не имею. Я попытался установить параметры tabindex для различных текстовых полей/указателей даты, но это не изменило поведение.

В любом случае, я ценю вклад всех, кто принимал участие - это была странная проблема, но я никогда не забуду, как ее исправить сейчас. Спасибо всем за вашу помощь!!

9
musicmunky

Попробуйте этого друга: В вашем JS

 $(function() {   
       $( "#from" ).datepicker({   
      defaultDate: "+1w",  
      changeMonth: true,   
      numberOfMonths: 1,  
      onClose: function( selectedDate ) {  
        $( "#to" ).datepicker( "option", "minDate", selectedDate );  
      }  
    });  
    $( "#to" ).datepicker({
      defaultDate: "+1w",
      changeMonth: true,
      numberOfMonths: 1,
      onClose: function( selectedDate ) {
        $( "#from" ).datepicker( "option", "maxDate", selectedDate );
      }
    });  
  });  
  
	<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css"/>
 <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
Start date: <input type="text" id="from" name="from"> 
End date: <input type="text" id="to" name = "to">

В вашем входе

Дата начала: input type = "text" id = "from" name = "from" 

Дата окончания: input type = "text" id = "to" name = "to"

Это сработало для меня :)

макЭли М.

4
McElie

Я думаю, что у вас есть другой код, который мешает JavaScript как Это: http://jsfiddle.net/fMD62/

работает отлично (с jquery 1.9.1 и jqueryui 1.9.2

может быть попробовать

$(function() {
    $("#datepicker1,#datepicker2").datepicker();
});
3
Stanislas Nichini

Это полный выстрел в темноте, но вы пытались инициализировать каждый отдельно? Что-то вроде следующего

$(function() {
    $('.datepicker').each(function(){
        $(this).datepicker();
    });
});

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

1
Tom Yeldham

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

Использует ли ваш реальный код разные идентификаторы и имена для обоих указателей даты?

1
Bardo

В качестве предисловия, я программист базы данных, поэтому мало знаю о JavaScript, поэтому постарался найти этот пост с точно таким же вопросом. Исходя из того, что я прочитал выше, и сравнивая с моим существующим кодом, я изменил свой JavaScript, чтобы он работал, и решил поделиться им.

Единственным предостережением было то, что мои существующие формы с одиночными селекторами даты больше не работали, поэтому мне пришлось добавить немного, чтобы справиться с ними, и теперь все выглядит нормально. В этом случае поля базы данных на самом деле являются меткой времени Unix, поэтому форма обрабатывается при отправке с двумя полями, преобразованными по мере необходимости, но для ясности я не включил этот код здесь.

$(document).ready(function(){ 
       $( "#StartDate" ).datepicker({   
                                altField: '#datepicker',
                                altFormat: 'yy-mm-dd',
                                dateFormat: 'D M d, yy', 
                                firstDay: 1,
      onClose: function( selectedDate ) {  
        $( "#StartDate" ).datepicker( "option", "minDate", selectedDate );  
      }  
    });  
    $( "#EndDate" ).datepicker({
                                altField: '#datepicker',
                                altFormat: 'yy-mm-dd',
                                dateFormat: 'D M d, yy', 
                                firstDay: 1,
      onClose: function( selectedDate ) {
        $( "#EndDate" ).datepicker( "option", "maxDate", selectedDate );
      }
    }); 
        $( "#datepicker" ).datepicker({
                                altField: '#datepicker',
                                altFormat: 'yy-mm-dd',
                                dateFormat: 'D M d, yy', 
                                firstDay: 1,
      onClose: function( selectedDate ) {
        $( "#datepicker" ).datepicker( "option", "maxDate", selectedDate );
      }
    });     
  });
0
DonP

Случай 1:
@ Комментарий Антония (включая ссылку jsfiddle под вопросом) работает с
версия jquery-1.9.1 и 1.9.2/jquery-ui.js

Случай 2:
Случай OP, когда datepicker1 работает хорошо, но выбор datepicker2 откроет datepicker1
версия: jQuery v1.9.0 и jQueryui v1.10.0

Случай 3:
Мой случай, когда выбор datepicker1 работает хорошо, но выбор datepicker2 не имеет никакого эффекта.
версия: jquery-3.1.1.min.js и jQueryui v1.12.1

Решение для случая 3:
инициализировать date1 first $('date1').datepicker() date1 будет работать
Для date2 сначала уничтожить date1, а затем инициализировать date2 

$('date1').datepicker('destroy');
$('date2').datepicker();

Теперь для date1, уничтожьте date2 и инициализируйте date1.

0
vusan

Попробуйте поместить содержимое диалогового окна JQuery UI в IFrame. Это может помочь вам обойти некоторые из ваших проблем. 

\---/\---/\---/_______________
/                            /
\  ####IFRAME######          \
\  #              #          \
/  #DATEPICKER1   #          /
\  #              #          \
/  #DATEPICKER2   #          /
\  #              #          \
/  ################          /
\                            \
/____________________________/
0
Robert Bolton

ОБЪЯСНЕНИЕ вопроса

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

if ( $.ui.dialog.overlayInstances ) {
    this._on( this.document, {
        focusin: function( event ) {
            if ( !$( event.target ).closest(".ui-dialog").length ) {
                event.preventDefault();
                $(".ui-dialog:visible:last .ui-dialog-content")
                    .data("ui-dialog")._focusTabbable();
            }
        }
    });
}

Поэтому, когда вы устанавливаете фокус в элементе, который не находится внутри .ui-dialog, он запускает функцию _focusTabbable(), которая устанавливает фокус на первый вход в диалоге.

Проблема в том, что $.datepicker создает div на конце тела - поэтому он находится за пределами .ui-dialog

Если есть другой вход, который _focusTabbable() даст фокус, то все в порядке, так как datepicker может с этим справиться. Но если этот вход имеет привязку DatePicker, он закроет предыдущий DatePicker, откроет другой на первом входе, и выбор на предыдущем DatePicker не будет запущен.

Одно из возможных решений

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

Я просто использую этот HTML-код в качестве первого ввода в начале содержимого диалога, где в противном случае ввод DatePicker будет на первом месте:

<span class="ui-helper-hidden-accessible"><input type="text" /></span>
0
Gh61