Какой способ добавить текст в ячейку jQuery ui datepicker?

Мне нужно показать пользовательский текст на некоторых датах в jQuery UI datepicker, чтобы быть более точным, чтобы сделать определенную цену для некоторых дат. Моя идея состояла в том, чтобы использовать beforeShowDay, чтобы прикрепить определенную цену в заголовках таких дат, а затем, в beforeShow, проверить каждый td и поместить текст заголовка в ячейку. Пример:

var m, d, y, checkDate, specificPrice = '';    
var specificPrices = {"2013-3-8":"300 EUR", "2013-2-26":"263 EUR"}

$('#my-datepicker').datepicker({
    beforeShowDay:     function checkAvailable(date) {
    m = date.getMonth();
    d = date.getDate();
    y = date.getFullYear();
    checkDate = y + '-' + (m+1) + '-' + d;
    if(specificPrices[checkDate]){
        specificPrice = specificPrices[checkDate];
    }else{
        specificPrice = '';
    }
    return [true, "", specificPrice];
},
    beforeShow: function(elem, inst){
        $('table.ui-datepicker-calendar tbody td', inst.dpDiv).each(function(){
            var calendarPrice = $(this).attr('title');
            if(calendarPrice != undefined){
                $(this).find('a').append('<span class="calendar-price">' + calendarPrice + '<span>');
            }
        });         
    }
});

это отобразит цены на первом календарном рендеринге (до изменения месяца / года) и для встроенного календаря только.

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

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

Спасибо за внимание, ваши идеи приветствуются.

2 ответов


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

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

создать свой datepicker

$('#DatePicker').datepicker({
    changeMonth: true,
    changeYear: true,
    minDate: 0,
    //The calendar is recreated OnSelect for inline calendar
    onSelect: function (date, dp) {
        updateDatePickerCells();
    },
    onChangeMonthYear: function(month, year, dp) {
        updateDatePickerCells();
    },
    beforeShow: function(elem, dp) { //This is for non-inline datepicker
        updateDatePickerCells();
    }
});
updateDatePickerCells();

создайте метод для вставки содержимого ячейки

function updateDatePickerCells(dp) {
    /* Wait until current callstack is finished so the datepicker
       is fully rendered before attempting to modify contents */
    setTimeout(function () {
        //Fill this with the data you want to insert (I use and AJAX request).  Key is day of month
        //NOTE* watch out for CSS special characters in the value
        var cellContents = {1: '20', 15: '60', 28: '100'};

        //Select disabled days (span) for proper indexing but apply the rule only to enabled days(a)
        $('.ui-datepicker td > *').each(function (idx, elem) {
            var value = cellContents[idx + 1] || 0;

            /* dynamically create a css rule to add the contents with the :after                         
               selector so we don't break the datepicker functionality */
            var className = 'datepicker-content-' + value;

            if(value == 0)
                addCSSRule('.ui-datepicker td a.' + className + ':after {content: "\a0";}'); //&nbsp;
            else
                addCSSRule('.ui-datepicker td a.' + className + ':after {content: "' + value + '";}');

            $(this).addClass(className);
        });
    }, 0);
}

добавьте метод для создания новых правил CSS на лету, отслеживая уже созданные.

var dynamicCSSRules = [];
function addCSSRule(rule) {
    if ($.inArray(rule, dynamicCSSRules) == -1) {
        $('head').append('<style>' + rule + '</style>');
        dynamicCSSRules.push(rule);
    }
}

и, наконец, некоторые css по умолчанию для нового содержимого ячейки

.ui-datepicker td a:after
{
    content: "";
    display: block;
    text-align: center;
    color: Blue;
    font-size: small;
    font-weight: bold;
}  

это работает для основного контента, но если вы хотите получить фантазию с чем-то вроде "$20.95 " (содержит специальные символы CSS), вы можете использовать хэш md5 контента для создания className переменной.

редактировать JSFiddle изменено из JSFiddle @yuga, чтобы включить хэш MD5 уникального имени класса для более сложного содержимого.


на основе ответа @PrestonS и этот пост, у меня есть хорошее простое решение, которое не нужно добавлять <style> теги в заголовок.

мое решение обновляет Престона как такового:

измененupdateDatePickerCells функция:

function updateDatePickerCells(dp) {
    /* Wait until current callstack is finished so the datepicker
       is fully rendered before attempting to modify contents */
    setTimeout(function () {
        //Fill this with the data you want to insert (I use and AJAX request).  Key is day of month
        //NOTE* watch out for CSS special characters in the value
        var cellContents = {1: '20', 15: '60', 28: '100'};

        //Select disabled days (span) for proper indexing but apply the rule only to enabled days(a)
        $('.ui-datepicker td > *').each(function (idx, elem) {
            var value = cellContents[idx + 1] || 0;

            /***** MAGIC! *****/

            $(this).attr('data-content', value);

            // and that's it! (oh, so easy)
        });
    }, 0);
}

С этим решением вам не нужно