JQuery Datepicker beforeShowDay only works after 1st click

I have a problem with beforeShowDay .

When my page loads, the days I said highlight are not highlighted until I click the day on the calendar. Also, if I press the button for the next month and return to the original month, the β€œselected” days will be highlighted as expected.

So, only at the initial draw of the calendar, the dates are not highlighted, as I programmed them. Any click on the calendar captures itself.

Am I missing the init option? See my sample code below. My test url is in a secure directory with the user / pass test / test. Look at the mini-feces at the bottom of the right column. Go to the next month and come back to see my problem. Pay attention to the marked days im May. Also, note that the β€œyear” drop-down is also missing until you click.

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

The code:

  <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> 
+6
source share
3 answers

Thanks @kingjiv You were 100% correct. The calendar was shown until the completion of the request for receipt. I tried using the when method, but could not get the dates asynchronously. Basically, I have to specify dates to highlight before the calendar is displayed, so I had to use async: false (not true).

I have included my complete code, which demonstrates how to highlight several events retrieved from the database using the beforeShowDay parameter. Using asyc: false fixed the issue where highlighted dates were not highlighted at the initial draw. Also included is css to change the background color of the cells.

There is still a slight problem where the "year" drop-down menu is not displayed in the original draw, but I confirmed that this only happens in FireFox 4. Any click on the calendar brings up the year menu. Safari correctly displays the menu of the year at the initial draw.

  <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 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> 
+4
source

I could not see how jQuery.when would help (it does not seem to postpone events from the date picker), but I managed to avoid async = false by disabling the collector and then updating when the data is received in 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", }); } ); 
+2
source

I cannot see your example, because I will be prompted to enter a username and password. However, see below what I think is happening.

$.get is simply a shorthand for an AJAX get request. AJAX is asynchronous, meaning you are calling it and it is not waiting for a response. Thus, basically, it is likely that the calendar is displayed until the completion of the request for receipt.

There are two ways from the head that you can fix. One could change your access to the full ajax call and set async : true .

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

Another option (and probably the best option) is to use when . when basically lets you wait for the ajax request to complete before doing anything else. This allows it to continue to be asynchronous, but ensures that the dependent code is not executed prematurely. Thus, other actions can be performed between the ajax call and the dependent code.

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

+1
source

Source: https://habr.com/ru/post/887765/


All Articles