jQuery Datepicker beforeShowDay работает только после первого клика - PullRequest
6 голосов
/ 11 мая 2011

У меня проблема с beforeShowDay.

Когда моя страница загружается, дни, которые я выделил, не выделяются, пока я не нажму на день в календаре. Также, если я нажму кнопку следующего месяца и вернусь к исходному месяцу, «выбранные» дни будут выделены, как и ожидалось.

Таким образом, только на начальном этапе календаря даты не выделяются, как я их запрограммировал. Любой клик в календаре исправляется.

Мне не хватает опции инициализации? Пожалуйста, смотрите мой пример кода ниже. Мой тестовый URL находится в защищенном каталоге с пользователем / pass of test / test. Посмотрите на мини-кал в правом столбце внизу. Переключитесь на следующий месяц и вернитесь, чтобы увидеть мою проблему. Обратите внимание на выделенные дни в мае. Также обратите внимание, что выпадающий список «год» также отсутствует, пока не произойдет щелчок.

http://www.urbanbands.com/dev/cgi-bin/links/eventmgr.cgi?do=list

код:

  <script>
$(document).ready(function(){

    // get the current date
    var today = new Date();
    var m = today.getMonth(), d = today.getDate(), y = today.getFullYear();

    // Need list of event dates for THIS month only from database.
    // Declare 'dates' var before adding "beforeShowDay" option to the datepicker,
    // otherwise, highlightDays() does not have the 'dates' array.
    dates = [];
    fetchEventDays(y, m+1);

    $('#datepicker').datepicker({
        dateFormat: 'yy-mm-dd',
        changeMonth: true,
        changeYear: true,
        setDate: today,
        inline: false
    });


    $('#datepicker').datepicker('option', 'onChangeMonthYear', fetchEventDays);
    $('#datepicker').datepicker('option', 'beforeShowDay', highlightDays);
    $('#datepicker').datepicker('option', 'onSelect', getday);


    // ------------------------------------------------------------------
    // getday
    // ------------------------------------------------------------------
    function getday(dateText, inst) { 
        $('#content').load('http://www.mydomain/eventmgr.cgi?do=view_day;date='+dateText+' #eventMgr_content', function() {
    alert('Load was performed. '+dateText);
        });
    }

    // ------------------------------------------------------------------
    // fetchEventDays
    // ------------------------------------------------------------------
    function fetchEventDays(year, month) {
        var paramStr ='?do=get_event_dates&yr=' + year + '&mo=' + month;
        $.get('<%config.db_cgi_url%>/eventmgr-ajax.cgi'+ paramStr, function(data) {
            var recur_dates = data.split(',');
            for(var i = 0; i < recur_dates.length; i++) {
                var date_parts = recur_dates[i].split('-');
                dates.push(new Date(date_parts[0], date_parts[1]-1, date_parts[2]));
            }                       

// This causes dates with events to highlight on initial draw, but
// when clicking to the next month, it switches back to orig month.
//        $('#datepicker').datepicker('option', {}); // Refresh

        });
    }

    // ------------------------------------------------------------------
    // highlightDays
    // ------------------------------------------------------------------
    function highlightDays(date) {
        for (var i = 0; i < dates.length; i++) {
            if ((dates[i].getTime() == date.getTime())) {
                return [true, 'highlight'];
            }
        }
        return [true, ''];
    }


});
  </script>

Ответы [ 3 ]

4 голосов
/ 13 мая 2011

Спасибо @kingjiv Вы были на 100% правы.Календарь отображался до завершения запроса на получение.Я попытался использовать метод when, но не смог получить даты асинхронно.По сути, у меня должны быть даты, чтобы выделить до календаря, поэтому мне пришлось использовать async: false (не соответствует действительности).

Я включил свой полный код, который демонстрирует, каквыделить несколько событий, извлеченных из базы данных, используя параметр beforeShowDay.Использование asyc: false исправило проблему, при которой выделенные даты не выделялись при первоначальном розыгрыше.Также включена CSS для изменения цвета фона ячеек.

Есть еще небольшая проблема, когда выпадающее меню «год» не отображается при первоначальном рисовании, но я подтвердил, что это происходит только в FireFox4. Любой щелчок по календарю приводит к отображению меню года.Safari правильно отображает меню года на начальном этапе.

     <link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"></script>
  <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>

<style type="text/css">
/* Dates with events on them. Text color - red, background - pastel yellow. */
td.highlight, table.ui-datepicker-calendar tbody td.highlight a { 
    background: none !important;
    background-color: #fffac2 !important; 
    color: #FF0000;
}

/* This is Today's day in rightsidebar mini calendar (datepicker). */
/* Restore style to that of a default day, then just bold it. */
.ui-state-highlight, .ui-widget-content .ui-state-highlight {
    border: 1px solid #d3d3d3; 
    background: #e6e6e6 url(http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png) 50% 50% repeat-x; 
    font-weight: bold;
    color: #555555;
}

/* This is the selected day in the inline datepicker. */
.ui-state-active, .ui-widget-content .ui-state-active {
    color: #000000;
    opacity: 1.0;
    filter:Alpha(Opacity=100);
    border: 1px solid #000000;
}

/* Add a little separation between month and year select menus */
.ui-datepicker select.ui-datepicker-month {
    width: 42%;
    margin-right: 6px;
}

</style>

<script>
$(document).ready(function(){

    // get the current date
    var today = new Date();
    var m = today.getMonth(), d = today.getDate(), y = today.getFullYear();

    // Get a list of dates that contain events in THIS month only from database.
    // Declare and populate 'eventDates' array BEFORE adding "beforeShowDay" option to 
    // the datepicker. Otherwise, highlightDays() will have an empty 'eventDates' array.

    var eventDates = [];
    fetchEventDays(y, m+1);     // Get events for the current year and month.

    $('#datepicker').datepicker();
    $('#datepicker').datepicker('option', 'onChangeMonthYear', fetchEventDays);
    $('#datepicker').datepicker('option', 'beforeShowDay', highlightDays);
    $('#datepicker').datepicker('option', 'onSelect', getday);
    $('#datepicker').datepicker('option', 'dateFormat', 'yy-mm-dd');
    $('#datepicker').datepicker('option', 'changeYear', true);
    $('#datepicker').datepicker('option', 'changeMonth', true);
    $('#datepicker').datepicker('option', 'yearRange', '2010:2012');
    $('#datepicker').datepicker('option', 'showButtonPanel', true);

    // Disable all dates prior to today.
    //  $('#datepicker').datepicker('option', 'minDate', new Date(y, m, d));

    // ------------------------------------------------------------------
    // getday - Replaces the #content div of the current page with 
    // the content of the page that is created and displayed via perl
    // ------------------------------------------------------------------
    function getday(dateText, inst) { 
        $('#content').load('<%config.db_cgi_url%>/eventmgr.cgi?do=view_day;date='+dateText+' #eventMgr_content', function() {
//      alert('load was performed. '+dateText);
        });
    }

    // ------------------------------------------------------------------
    // fetchEventDays - The ajax call below is synchronous (NOT asynchronous).
    // eventDates array must be populated prior to adding the beforeShowDay option
    // to the datepicker, otherwise, highlightDays() will have an empty eventDates array.
    // ------------------------------------------------------------------
    function fetchEventDays(year, month, inst) {
        var url ='<%config.db_cgi_url%>/eventmgr-ajax.cgi?do=get_event_dates&yr=' + year + '&mo=' + month;

        $.ajax({
            url: url,
            async: false,
            success: function(result){
                var event_dates = result.split(',');
                for(var i = 0; i < event_dates.length; i++) {
                    var date_parts = event_dates[i].split('-');
                    eventDates.push(new Date(date_parts[0], date_parts[1]-1, date_parts[2]));
                }                       
            }
        });
    }

    // ------------------------------------------------------------------
    // highlightDays - Add a custom css class to dates that exist in the
    // eventDates array. Must also add the css for td.highlight (above).
    // ------------------------------------------------------------------
    function highlightDays(date) {
        for (var i = 0; i < eventDates.length; i++) {
            if ((eventDates[i].getTime() == date.getTime())) {
                return [true, 'highlight'];
            }
        }
        return [true, ''];
    }

});
</script>
3 голосов
/ 22 февраля 2012

Я не мог понять, как jQuery.when мог бы помочь (не похоже, что он будет откладывать события от средства выбора даты), но мне удалось избежать async = false, отключив средство выбора и затем обновляя при получении данных в ajax callback

var available_days = [];

var data = get_selected();
var today = new Date();
data['year'] = today.getFullYear();
data['month'] = today.getMonth() + 1;
$.get('{% url views.get_availability %}', data,
    function(get_data) {
        $("#datepicker").datepicker("destroy");
        available_days = get_data['available_days'];
        $("#datepicker").datepicker({
            onChangeMonthYear: function(year, month, inst) {
                 $("#datepicker").datepicker("disable");
                 available_days = [];
                 data['year'] = year;
                 data['month'] = month;
                 $.get('{% url views.get_availability %}', data,
                     function(get_data) {
                         available_days = get_data["available_days"];
                         $("#datepicker").datepicker("refresh");
                         $("#datepicker").datepicker("enable");
                     }
                 );
             },            
             beforeShowDay: function(date) {
                return [$.inArray(date.getDate(), available_days) >= 0, ''];
             },
             onSelect: function(dateText, inst) { showTimes(dateText, data); },
             dateFormat: "dd-mm-yy",
         });
     }
);
1 голос
/ 11 мая 2011

Я не вижу ваш пример, потому что мне предлагается ввести имя пользователя и пароль. Тем не менее, см. Ниже о том, что, по моему мнению, происходит.

$.get - это просто сокращение для запроса на получение AJAX. AJAX является асинхронным, то есть вы называете его, и он не ждет ответа. Таким образом, в основном, вероятно, происходит то, что календарь отображается до завершения запроса get.

Есть два способа избежать моей головы, что вы можете это исправить. Можно было бы изменить ваш get на полный вызов ajax и установить async : true.

http://api.jquery.com/jQuery.ajax/

Другой вариант (и, возможно, лучший вариант) будет использовать when. When в основном позволяет дождаться завершения ajax-запроса, прежде чем делать что-либо еще. Это позволяет ему оставаться асинхронным, но гарантирует, что зависимый код не будет выполнен преждевременно. Таким образом, между вызовом ajax и зависимым кодом могут выполняться другие действия.

http://api.jquery.com/jQuery.when/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...