it-swarm.com.ru

jQuery Datepicker: предотвратить закрытие при нажатии на дату

Привет, товарищ, stackoverflow:

Я использую плагин jQuery Datepicker вместе с Martin Milesich Timepicker плагин. Все работает отлично, за исключением того, что нажатие на дату в указателе даты закрывает виджет, не оставляя времени для выбора времени. 

Вопрос: Мне интересно, есть ли способ предотвратить закрытие виджета при щелчке по дате и вместо этого заставить пользователей нажимать кнопку «Готово» (которая появляется при включении опции «showButtonPanel: true») или щелкать вне виджета. Я не хочу, чтобы мои пользователи дважды открывали виджет! Смотрите поведение онлайн на демо Timepicker

Любая помощь в решении этой проблемы, или даже указатели в правильном направлении, приветствуется!

Дополнительная информация: Я использую файлы, предоставленные по ссылке для скачивания Martins: http://milesich.com/tpdemo/timepicker-0.2.0.Zip

  • jQuery-щ-1.7.2.custom.min.js
  • timepicker.js (последняя версия 0.2.0)

Вот варианты, которые я использую:

$(document).ready(function(){
    $(".datepicker").datepicker({
        duration: '',  
        showTime: true,  
        constrainInput: false,  
        stepMinutes: 5,  
        stepHours: 1, 
        time24h: true,
        dateFormat: "yy-mm-dd",
        buttonImage: '/static/images/datepicker.png',
        buttonImageOnly: true,
        firstDay: 1,
        monthNames: ['Januari','Februari','Mars','April','Maj','Juni','Juli','Augusti','September','Oktober','November','December'],
        showOn: 'both',
        showButtonPanel: true
     });
})
16
Emil Stenström

вместо изменения источника лучше использовать существующие события

onSelect: function() {
    $(this).data('datepicker').inline = true;                               
},
onClose: function() {
    $(this).data('datepicker').inline = false;
}
24
Min Hur

Для справки, а так как люди спрашивали меня об этом по почте. Вот фрагмент кода, который нужно добавить в timepicker.js:

/**
 * Don't hide the date picker when clicking a date
 */
$.datepicker._selectDateOverload = $.datepicker._selectDate;
$.datepicker._selectDate = function(id, dateStr) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    inst.inline = true;
    $.datepicker._selectDateOverload(id, dateStr);
    inst.inline = false;
    this._updateDatepicker(inst);
}

Удачи в работе на вашем сайте!

27
Emil Stenström

Вам придется взломать сборщик данных самостоятельно. Это код, который он использует. Если он не встроен, он будет скрыт при выборе даты. 

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

if (inst.inline)
        this._updateDatepicker(inst);
else {
      this._hideDatepicker(null, this._get(inst, 'duration'));
      this._lastInput = inst.input[0];
      if (typeof(inst.input[0]) != 'object')
      inst.input[0].focus(); // restore focus
      this._lastInput = null;
}
8
redsquare

Вот решение:

onSelect: function ( dateText, inst ) {
    ..... // Your code like $(this).val( dateText );`


    //Set inline to true to force "no close"
    inst.inline = true;
},
onClose: function(date,inst){
    //Set inline to false => datapicker is closed
    // onClose is called only if you click outside the datapicker, onSelect will not
    // trig onClose due to inline = true
   inst.inline = false;
}

`

3
TomPAP

Почему все комментарии предоставляют обходной путь? это прямолинейное слово:

Используйте встроенный календарь с altField :)

    <input type="text" id="alternate" size="30" />
    <div id="datepicker"></div>

    <script>
       $("#datepicker").datepicker({
          altField: "#alternate"
       });
    </script>

проверьте эту скрипку: http://jsfiddle.net/menocomp/y2s662b0/1/

2
Mina Luke

Следуя совету Эмиля, я нашел более удобный и простой способ изменить виджет, чтобы он поддерживал не закрывающийся виджет в событии select.

Во-первых, я добавил еще одно свойство в dict defaults на виджете:

closeOnSelect:true //True to close the widget when you select a date

Во-вторых, найдите это утверждение в методе _selectDate:

if (inst.inline)
        this._updateDatepicker(inst);
else {
        ...
    }

И измените условие так:

var closeOnSelect = this._get(inst, "closeOnSelect");        
if (inst.inline || !closeOnSelect)
        this._updateDatepicker(inst);
else {
        ...
    }

Попробуйте, это работает для меня. Я сделал это поверх версии JQuery UI 1.8.5.

0
FernandoEscher

Вы должны переопределить нативную функцию js:

 /* Update the input field with the selected date. */
        _selectDate: function(id, dateStr) {
            var target = $(id);
            var inst = this._getInst(target[0]);
            dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
            if (inst.input)
                inst.input.val(dateStr);
            this._updateAlternate(inst);
            var onSelect = this._get(inst, 'onSelect');
            if (onSelect)
                onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback
            else if (inst.input)
                inst.input.trigger('change'); // fire the change event
            if (inst.inline)
                this._updateDatepicker(inst);
            else {
                if(inst.settings.hideOnSelect != false){
                    this._hideDatepicker();
                }
                this._lastInput = inst.input[0];
                if (typeof(inst.input[0]) != 'object')
                    inst.input.focus(); // restore focus
                this._lastInput = null;
            }
        },

И добавьте соответствующую опцию в конфигурацию datepicker, например:

var defaultDatePickerOptions = {
        hideOnSelect: false,
        ...
    }; 
 var birthDate = jQuery.extend({}, defaultDatePickerOptions);
 $('#birthdate').datepicker(birthDate);
0
Ihor Kruk

хорошо это грязный обходной путь ... но он работает для меня ... даже с showButtonPanel: true

  $(function() {
    var dp_c = null, dp_once = false;
    $( '#datepicker' ).datepicker({
      showButtonPanel: true,
      onSelect: function() {
        $(this).data('datepicker').inline = true;  
        setTimeout(function () {
          $('#ui-datepicker-div').find('.ui-datepicker-buttonpane').append(dp_c);
        }, 1);

      },
      onClose: function() {
        $(this).data('datepicker').inline = false;
      }
    }).click(function () {
      if(!dp_once) {
        setTimeout(function () {
          dp_c = $('#ui-datepicker-div').find('.ui-datepicker-close').clone();
        }, 500);
        dp_once = !!1;
      }
    });

    $('#ui-datepicker-div').on('click', '.ui-datepicker-close', function () {
      $('#datepicker').datepicker( "hide" );
    });

  });
0
s4ty

Круто, если вы используете jquery-ui-1.8.5.custom.min.js и jquery-ui.multidatespicker.js, вы можете изменить jquery-ui-1.8.5.custom.min.js: From :

if(a.inline)this._updateDatepicker(a);

в:

if(a.inline || !this._get(a, 'closeOnSelect'))this._updateDatepicker(a);
0
diyism