2011-05-10 101 views
6

我遇到了beforeShowDay問題。jQuery Datepicker beforeShowDay僅在第一次點擊後纔有效

當我的頁面加載時,我告訴突出顯示的日子直到我點擊日曆中的某一天才突出顯示。另外,如果我點擊下一個月按鈕並返回到原始月份,則「預定」日期將按預期突出顯示。

所以,只有在日曆的最初繪製日期做日期不突出,因爲我已經編程他們做。日曆中的任何點擊都會修復其自身。

我是否缺少init選項?請參閱下面的代碼示例。我的測試網址在用戶/測試/測試通過的受保護目錄中。看看右下角的迷你卡。切換到下個月,然後返回以查看我的問題。請注意突出顯示的日子即將到來另外,請注意,點擊發生之前,「年份」下拉菜單也會丟失。

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> 

回答

1

我看不到你的例子,因爲我得到提示輸入用戶名和密碼。但是,請參閱下文,瞭解我相信正在發生的事情。

$.get簡單地說就是製作一個AJAX獲取請求。 AJAX是異步的,意思是你稱之爲,它不會等待響應。所以基本上,可能發生的情況是,日曆在獲取請求完成之前顯示。

有兩種方法可以解決這個問題。一個將是改變你的一個完整的Ajax調用,並設置async : true

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

其他選項(可能是更好的選擇)是使用whenWhen基本上允許你在做其他事情之前等待ajax請求完成。這允許它仍然是異步的,但確保不會過早地執行依賴代碼。這樣,可以在ajax調用和從屬代碼之間執行其他操作。

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

4

感謝@kingjiv你是100%正確的。日曆在獲取請求完成之前顯示。我嘗試使用when方法,但不能異步獲取日期。基本上我必須有日期才能突出之前日曆顯示,所以我不得不使用async: false(不正確)。

我已經包含了我的完整代碼,演示瞭如何使用beforeShowDay選項突出顯示從數據庫中提取的多個事件。使用asyc: false解決了突出顯示日期在初始繪製時未突出顯示的問題。也包括用於更改單元格背景顏色的CSS。

仍然存在一個小問題,其中「年」下拉菜單不顯示在初始繪圖上,但我確認這隻發生在FireFox 4中。任何點擊日曆都會導致顯示年份菜單。 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> 
2

我看不出jQuery.when將如何幫助(它看起來並不像它會推遲從日期選取器事件),但我設法避免異步=虛假通過禁用選擇器,然後刷新數據時在ajax回調中收到

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", 
     }); 
    } 
); 
相關問題