Кнопка «Сегодня» в jQuery Datepicker не работает

61

Я использую jQueryUI Datepicker и показываю кнопку "Сегодня". Но это не сработает. Он также не работает в демо: http://www.jqueryui.com/demos/datepicker/#buttonbar

Я хочу заполнить ввод сегодня, когда нажимаем эту кнопку.

Можно ли заставить его работать?

Теги:
datepicker

18 ответов

36
Лучший ответ

Их код на самом деле не сломан. Это просто не делает то, что ожидали бы от большинства людей. Который должен ввести сегодня дату в поле ввода. То, что он делает, является ключевым моментом для того, чтобы пользователь мог видеть сегодняшнюю дату в календаре. Если они отключились через месяц или другой год, календарь возвращается к сегодняшнему просмотру без отмены выбора даты, которую пользователь уже выбрал.

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

Вам нужно получить несжатую версию jquery-ui javascript. Я смотрю версию 1.7.2, а функция "_gotoToday" находится в строке 6760. Просто добавьте вызов в этот _gotoToday, который отключает функцию _selectDate() в строке 6831.:) Happy Coding.

  • 20
    Мне не нравится решение изменения исходного кода jQuery, потому что оно устраняет возможность использования CDN. Смотрите мой ответ о том, как изменить функцию _gotoToday без изменения файла кода плагина. (Я бы сохранил это как комментарий, а не как ответ, если бы комментарии могли включать подсветку синтаксиса)
  • 0
    Мне больше нравится предложение Грегла.
Показать ещё 4 комментария
78

Мне не нравится решение для изменения исходного кода jQuery, поскольку оно удаляет возможность использования CDN. Вместо этого вы можете переназначить функцию _gotoToday, включив этот код на основе @meesterjeeves answer где-нибудь в вашем файле области видимости страницы:

$.datepicker._gotoToday = function(id) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
            inst.selectedDay = inst.currentDay;
            inst.drawMonth = inst.selectedMonth = inst.currentMonth;
            inst.drawYear = inst.selectedYear = inst.currentYear;
    }
    else {
            var date = new Date();
            inst.selectedDay = date.getDate();
            inst.drawMonth = inst.selectedMonth = date.getMonth();
            inst.drawYear = inst.selectedYear = date.getFullYear();
            // the below two lines are new
            this._setDateDatepicker(target, date);
            this._selectDate(id, this._getDateDatepicker(target));
    }
    this._notifyChange(inst);
    this._adjustDate(target);
}

Вышеприведенный код по существу такой же, как и jQuery UI Datepicker от версии 1.10.1, за исключением двух строк, указанных выше. Весь mumble-jumbo с gotoCurrent можно фактически удалить, поскольку этот параметр не имеет смысла с нашим новым значением "сегодня".

  • 0
    ломает кнопку для меня.
  • 0
    Я использую его с jquery-1.6.2.min.js и /1.8.15/jquery-ui.min.js, которые не являются последними версиями. Возможно, в новых версиях произошли изменения кода, которые нарушают этот хак.
Показать ещё 12 комментариев
23

Я думаю, что лучший способ справиться с этим - переопределить метод _goToToday вне самой библиотеки. Это решило проблему для меня:

var old_goToToday = $.datepicker._gotoToday
$.datepicker._gotoToday = function(id) {
  old_goToToday.call(this,id)
  this._selectDate(id)
}

Простой и не требует взлома любых событий или изменения каких-либо базовых функций

  • 0
    Небольшая ошибка (календарь не будет появляться, пока не будет удален фокус), но в остальном работает отлично.
  • 0
    Используя 1.10.2, и работает блестяще. Добавил его в мою конфигурацию shim для init для requirejs: shim: shim: { 'datepicker': { deps: ['jquery','ui_core'], init: function ($, core) { var oldGoToToday = $.datepicker._gotoToday $.datepicker._gotoToday = function(id) { oldGoToToday.call(this, id); this._selectDate(id); }; } }, }
Показать ещё 5 комментариев
8

Хотя я знаю, что это уже принято, вот мое расширенное решение, основанное на Идея Сами Зина. Это использовало jQuery 1.6.3 и jQuery UI 1.8.16 и работал у меня в Firefox 6.

$('.ui-datepicker-current').live('click', function() {
    // extract the unique ID assigned to the text input the datepicker is for
    // from the onclick attribute of the button
    var associatedInputSelector = $(this).attr('onclick').replace(/^.*'(#[^']+)'.*/gi, '$1');
    // set the date for that input to today date
    var $associatedInput = $(associatedInputSelector).datepicker("setDate", new Date());
    // (optional) close the datepicker once done
    $associatedInput.datepicker("hide");
});

Вы также можете также blur() $associatedInput и сосредоточиться на следующем вводе/выборе на своей странице, но это не так, чтобы делать это в общем случае или специфично для реализации.

В качестве примера я сделал это на странице, на которой я работал над используемыми таблицами для макета (не заставляйте меня начинать, я знаю, что это плохая практика!):

$associatedInput.closest('tr').next('tr').find('input,select').first().focus();
  • 1
    Обновление: я действительно нашел проблемы с моим решением здесь, в IE (большинство версий). Вместо этого я остановился на подходе Уолтера Стабоша, который работал в IE (как и в других браузерах).
8

Просто добавьте следующие две строки кода в функцию _gotoToday...


/* Action for current link. */
_gotoToday: function(id) {
    var target = $(id);
    var inst = this._getInst(target[0]);
    if (this._get(inst, 'gotoCurrent') && inst.currentDay) {
        inst.selectedDay = inst.currentDay;
    inst.drawMonth = inst.selectedMonth = inst.currentMonth;
    inst.drawYear = inst.selectedYear = inst.currentYear;
    }
    else {
        var date = new Date();
        inst.selectedDay = date.getDate();
        inst.drawMonth = inst.selectedMonth = date.getMonth();
        inst.drawYear = inst.selectedYear = date.getFullYear();
    }
    this._notifyChange(inst);
    this._adjustDate(target);

    /* ### CUSTOMIZATION: Actually select the current date, don't just show it ### */
    this._setDateDatepicker(target, new Date());
    this._selectDate(id, this._getDateDatepicker(target));
},

6

Мне не нравится идея добавления дополнительного кода в исходный код jQuery. И я не хочу переопределять метод _gotoToday, копируя его реализацию где-то в коде javascript и добавляя дополнительные строки внизу.

Итак, я изменил его с помощью этого кода:

(function(){
    var original_gotoToday = $.datepicker._gotoToday;

    $.datepicker._gotoToday = function(id) {
        var target = $(id),
            inst = this._getInst(target[0]);

        original_gotoToday.call(this, id);
        this._selectDate(id, this._formatDate(inst, inst.selectedDay, inst.drawMonth, inst.drawYear));
    }
})();
1

jQuery UI Datepicker Today Link

$('button.ui-datepicker-current').live('click', function() { $.datepicker._curInst.input.datepicker('setDate', new Date()).datepicker('hide').blur(); });

  • 0
    Это правильно устанавливает текущую дату, но она открывает всплывающее окно DatePicker после установки.
1

Я добавил параметр datepicker для этой цели: selectCurrent.

Чтобы сделать то же самое, вам просто нужно добавить следующее в несжатый файл js:

1) К концу функции Datepicker() добавьте:

selectCurrent: false // True to select the date automatically when the current button is clicked

2) В конце функции _gotoToday добавьте:

if (this._get(inst, 'selectCurrent'))
  this._selectDate(id, this._formatDate(inst, inst.selectedDay, inst.drawMonth, inst.drawYear));
1

Вы также можете попробовать использовать приведенный ниже код, чтобы заполнить текущую дату в поле ввода при нажатии кнопки "Сегодня". Просто поставьте код ниже в функции _gotoToday (в конце функции) в jquery.ui.datepicker.js.

this._selectDate(id, this._formatDate(inst,
inst.selectedDay, inst.drawMonth, inst.drawYear));

Обратите внимание, что я использую версию 1.8.5 jquery datepicker.

1

Я просто избавился от него.

В некоторых файлах CSS эта часть вашей страницы:

.ui-datepicker-current {
    visibility:hidden
}
  • 1
    Нет смысла делать это таким образом, так как вы можете просто пропустить опцию, чтобы скрыть кнопки. showButtonPanel:false - и это значение по умолчанию в любом случае.
  • 2
    Нет, он только спрятал кнопку «Сегодня», а не «Готово».
1

В документации говорится, что кнопка "сегодня", название которой может быть изменено с помощью

.datepicker('option', 'currentText', 'New Title') 

изменяется только текущий месяц. Это поведение также можно настроить

.datepicker('option', 'gotoCurrent', true);

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

Кажется, что дата с этой кнопкой невозможна по дизайну.

  • 0
    Большое спасибо, это спасло меня много раз.
0

Вы должны использовать опцию: todayBtn: "linked". (вместо todayBtn: true).

todayBtn Boolean, "linked". По умолчанию: false

Если значение true или "connected", в нижней части datepicker отображается кнопка "Сегодня", чтобы выбрать текущую дату. Если true, кнопка "Сегодня" будет только перемещать текущую дату в поле зрения; если "связанный", текущая дата также будет выбрана.

Подробнее см. следующую ссылку: http://bootstrap-datepicker.readthedocs.io/en/latest/options.html#todaybtn

0

Это простой хак

$(function() {
var _gotoToday = $.datepicker._gotoToday;
$.datepicker._gotoToday = function(a){
var target = $(a);
var inst = this._getInst(target[0]);
_gotoToday.call(this, a);
$.datepicker._selectDate(a, $.datepicker._formatDate(inst,inst.selectedDay, inst.selectedMonth, inst.selectedYear));
target.blur();
}

$( "#datepicker" ).datepicker({
showButtonPanel: true
});

});
0

$.datepicker._gotoToday = function(id) {
  var inst = this._getInst($(id)[0]);

  var date = new Date();
  this._selectDay(id, date.getMonth(), date.getFullYear(), inst.dpDiv.find('td.ui-datepicker-today'));
}

$.datepicker.setDefaults({
  changeMonth: true,
  maxDate: 'today',
  numberOfMonths: 1,
  showButtonPanel: true
});
<link href="/jquery-ui.css" rel="stylesheet" type="text/css" />
<script src="/jquery.min.js"></script>
<script src="/jquery-ui.min.js"></script>

<input type="text" id="id">
0

Это хак, который работал у меня, который использует функцию обратного вызова Datepicker beforeShow, в отличие от метода live().

     ,beforeShow: function(input, datepicker) {
         setTimeout(function() {
             datepicker.dpDiv.find('.ui-datepicker-current')
                .text('Select Today')
                .click(function() {
                     $(input)
                         .datepicker('setDate', new Date())
                         .datepicker('hide');
                });
         }, 1);
         return {};
     }
  • 0
    Это работает только до тех пор, пока вы не измените месяц / год в календаре, если вы измените месяц один раз, кнопка «Сегодня» будет работать так же, как обычно.
0

Вы также можете попробовать добавить это в свой script:

$('.ui-datepicker-current').live('click', function() {
       $(".datepicker").datepicker("setDate", date);
});

(используйте функцию .live, а не .click)

0

Датпикер реорганизуется как минимум в 10 раз более удивительным. Новая версия рассмотрит эту проблему.

http://wiki.jqueryui.com/w/page/12137778/Datepicker

-1

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

Я не мог заставить datepicker оставаться скрытым с любыми другими ответами. Календарь закрывается, а затем снова открывается. Следующий код работал у меня, чтобы изменить кнопку "Сегодня", чтобы установить дату в текущий день и закрыть календарь.

jQuery UI - v1.11.4 jQuery JavaScript Library v1.11.1 IE 11.0.28

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

    $.datepicker._gotoToday = function(id) {
      var inst = this._getInst($(id)[0]);

      var date = new Date();
      this._selectDay(id, date.getMonth(), date.getFullYear(), inst.dpDiv.find('td.ui-datepicker-today'));
    }

    $.datepicker.setDefaults({
      changeMonth: true,
      maxDate: 'today',
      numberOfMonths: 1,
      showButtonPanel: true
    });
  • 0
    Область Ответов предназначена для ответов, а не для последующих вопросов. Пожалуйста, рассмотрите возможность размещения этого как Вопроса (ссылка на него внутри него), или как комментарий к вопросу, или как один из существующих ответов.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню