Events in jQuery UI Datepicker with json data source - javascript

I want to display events in the jQuery UI Datepicker. I want the days that have events to be styled differently from days that don't have events, and I want to display a custom tooltip with the event details when hovering dates with events.
The solution to the question "jQuery UI Datepicker with jQuery tipsy" gets very close, but doesn't work with the Datepicker configuration I use. I use the "showOtherMonths" option, and it throws the date link calculation off.
The event data is available at http://mydomain.com/events.json
Mockup of what I want:
This is the code I use for creating the Datepicker:
$('#dateDiv').datepicker({
altField: '#dateInput',
altFormat: 'yy-mm-dd',
dateFormat: 'yy-mm-dd',
firstDay: '1',
showOtherMonths: 'true',
});
I'm not concerned about the CSS part of the solution at this time, just the javascript part. How do I make my custom tooltip appear when hovering the dates with events attached to them? And how do I attach the events (calendar events, not javascript/DOM events ;) )?

This is not a very elegant solution, but it does seem to work. Can someone please come up with something better?
EDIT: Here's a jsFiddle with the code running: http://jsfiddle.net/Tobbe/JrkSN/3/
EDIT2: It works until I click on a date, then all the events disappears because the beforeShowDay callback isn't called in that case. How do I work around that?
getEvents();
$(function() {
$('#dateDiv').datepicker({
altField: '#dateInput',
altFormat: 'yy-mm-dd',
dateFormat: 'yy-mm-dd',
firstDay: '1',
showOtherMonths: 'true',
beforeShowDay: beforeShowDay,
onChangeMonthYear: getEvents
});
});
var enqueuedDates = [];
var tryCounter = 0;
var events = [];
function getEvents() {
events = [];
enqueuedDates = [];
$.getJSON('events.json', function(json) {
events = json;
});
}
function beforeShowDay(date) {
enqueuedDates.push(new Date(date));
if (enqueuedDates.length == 35) {
processEnqueuedDates();
}
return [true, '', ''];
}
function processEnqueuedDates() {
if (!events || events.length === 0) {
tryCounter++;
if (tryCounter < 100) {
setTimeout(processEnqueuedDates, 10);
} else {
tryCounter = 0;
}
return;
}
tryCounter = 0;
for (var i = 0; i < enqueuedDates.length; ++i) {
var event = getEvent(events, enqueuedDates[i]);
if (event) {
var theDateCells = $('#dateDiv .ui-datepicker-calendar td');
var hideTimeoutID;
theDateCells.eq(i).addClass('eventPlanned').
bind('mouseenter', function(eventText) {
return function() {
if (hideTimeoutID) {
clearTimeout(hideTimeoutID);
hideTimeoutID = null;
}
var popup = $('#eventPopup');
if (popup.size() == 0) {
popup = $('<div></div>').attr('id', 'eventPopup');
$('body').append(popup);
}
var pos = $(this).offset();
popup.html('<p>' + eventText + '</p>').
css('left', pos.left + 5 + 'px').
css('top', (pos.top - popup.height() - 2) + 'px').
bind('mouseenter', function() {
clearTimeout(hideTimeoutID);
hideTimeoutID = null;
}).
bind('mouseleave', function() {
$(this).hide();
}).
show();
}
}(event.text)).
bind('mouseleave', function(eventObject) {
hideTimeoutID = setTimeout(function() {
$('#eventPopup').hide();
}, 200);
});
}
}
}
function getEvent(events, date) {
return events.filter(function(event, index, arr) {
return date - $.datepicker.parseDate('yy-mm-dd', event.date) === 0;
})[0];
}

Related

Passing data to another function without repeating code

I have form with input fields for some service, now I have trouble how to pass data from to function.
This form accept number and this number is multiplied to get total price, but some inputs can be 0.
I declare in globals to get value from the inputs
var cleaning_size;
var bathroom_number;
$( ".needs-validation" ).on( "change", "input", function() {
cleaning_size = $("#cleaning-size").val();
bathroom_number = $("#bathroom-numbers").val();
})
And in the form i have datepicker where you chose date, but if selected sunday the price calculation is different
$("#datepicker").datepicker({
changeMonth: true,
onSelect: function (selectedDate) {
var date = $(this).datepicker('getDate');
var day = date.getUTCDay();
if (day == '6') {
price_cleaning_size = 1.5;
price_bathroom_number = 26;
} else {
price_cleaning_size = 1.2;
price_bathroom_number = 24;
}
}
});
And then i calculate total in different function:
function calculate_total_value(){
var cleaning_size_price = cleaning_size * price_cleaning_size;
var bathromm_number_price = bathroom_number * price_bathroom_number;
var total_price = cleaning_size_price + bathromm_number_price;
$('#total-price strong').text(total_price).val();
}
Now i have issue how to get data from the datepicker if selected day is 6 to get 1.5 or 1.2 to calculate total price.
I can't find any similar example how to do this.
Also i will have timepicker what will be inside function and i will need to get value from there.
So how to pass value the right way please?
Try modifying your function (calculate_total_value()), so it accepts two parameters - these two parameters are the values that you modify based on the selected day.
(And also check for typos like bathromm_number_price - they can take a lot of time to "find" later on.)
jQuery(document).ready(function($) {
var cleaning_size;
var bathroom_number;
$(".needs-validation").on("change", "input", function() {
cleaning_size = $("#cleaning-size").val();
bathroom_number = $("#bathroom-numbers").val();
})
$("#datepicker").datepicker({
changeMonth: true,
onSelect: function(selectedDate) {
var date = $(this).datepicker('getDate');
var day = date.getUTCDay();
if (day == '6') {
price_cleaning_size = 1.5;
price_bathroom_number = 26;
} else {
price_cleaning_size = 1.2;
price_bathroom_number = 24;
}
// call the function here, passing the values as parameters
calculate_total_value(price_cleaning_size, price_bathroom_number)
}
});
// alter your function, so it accepts two parameters (price_cleaning_size, price_bathroom_number)
function calculate_total_value(price_cleaning_size, price_bathroom_number) {
var cleaning_size_price = cleaning_size * price_cleaning_size;
var bathromm_number_price = bathroom_number * price_bathroom_number;
var total_price = cleaning_size_price + bathromm_number_price;
$('#total-price strong').text(total_price).val();
}
})
<link href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<div class="needs-validation">
<label for="cleaning-size">Cleaning size:
<input id="cleaning-size" type="number"></label>
<label for="bathroom-numbers">Bathroom number:
<input id="bathroom-numbers" type="number"></label>
</div>
<h2 id="total-price"><strong>0</strong></h2>
<p>Date: <input type="text" id="datepicker"></p>
price_cleaning_size , price_bathroom_number aren't declared anywhere.
It is recommended to declare the variable.(when you use use strict, it's must). Declare it globally.
No where you are calling the function calculate_total_value().
It's good to call it right at bottom of onSelect call back of datepicker.
$("#datepicker").datepicker({
changeMonth: true,
onSelect: function (selectedDate) {
var date = $(this).datepicker('getDate');
var day = date.getUTCDay();
if (day == '6') {
price_cleaning_size = 1.5;
price_bathroom_number = 26;
} else {
price_cleaning_size = 1.2;
price_bathroom_number = 24;
}
calculate_total_value();
}});
When your variable scope is global, There is no point of passing as parameter to the function. Hope there is reason to declare it globally.
Hope this helps you...

jQuery Calender UI datepicker doesn't work when we click ESC key, calendar not working after 1st click on IE and Safari

When I click first on JQuery calendar it will display the calendar and if i select date it works smoothly. But When I press the Esc after displaying calendar instead of selecting date, it disappears but I cant get click next time onward.
It works fine in Chrome and Firefox but IE and Safari I cant click second time if i click on ESC after click on first time.
Is there anyone faced this problem? or any solution can suggest for this.
I am using jquery-ui-calendar as below details.
/*! jQuery UI - v1.11.4 - 2016-06-30
* http://jqueryui.com
* Includes: core.js, datepicker.js
* Copyright jQuery Foundation and other contributors; Licensed MIT */
Below is my JS code:
/* This Section Custom Calendar*/
$(document).ready(function() {
// jquery date picker
$(function () {
if ($(window).width() < 768) {
$.datepicker.setDefaults({
changeMonth: false,
changeYear: false,
dateFormat: customFormat(),
defaultDate: +0,
minDate: 0,
maxDate: '+364d',
numberOfMonths: 1,
showAnim: 'fadeIn',
showButtonPanel: true
});
}
else {
// Set default datepicker options
$.datepicker.setDefaults({
changeMonth: false,
changeYear: false,
dateFormat: customFormat(),
defaultDate: +0,
minDate: 2,
maxDate: '+364d',
numberOfMonths: 2,
showAnim: 'fadeIn',
showButtonPanel: true
});
}
// Calendar 1
$(function () {
$(function () {
$('#arrivaldate').datepicker({
onSelect: function (dateText, instance) {
var arrivaldateold = CleanDate($("#arrivaldate").val());
var arrdatenew = $.datepicker.parseDate(customFormat(), arrivaldateold);
var arrday = arrdatenew.getDate();
var arrmon = (arrdatenew.getMonth() + 1);
var arrYear = arrdatenew.getFullYear()
if (arrday.toString().length==1){arrday="0"+arrday;}
if (arrmon.toString().length==1){arrmon="0"+arrmon;}
var arrivaldatenew = arrday + "/" + arrmon + "/" + arrYear;
$("#calendararr").val(arrivaldatenew);
// Populate checkout date field
var nextDayDate = $('#arrivaldate').datepicker('getDate', '+3d');
nextDayDate.setDate(nextDayDate.getDate() + 1);
$("#arrivaldate").val(FormatDate(arrivaldatenew));
$('#depaturedate').datepicker('setDate',nextDayDate );
$("#depaturedate").val(ChangeDateFormat(nextDayDate));
},
onClose: function () {
$("#depaturedate").datepicker("show");
}
});
});
// Set checkout datepicker options
$(function () {
$('#depaturedate').datepicker({
// Prevent selecting checkout date before arrival:
beforeShow: customRange
});
});
function customRange(a) {
var deptdateold = CleanDate($("#depaturedate").val());
var deptdatenew = $.datepicker.parseDate(customFormat(), deptdateold);
var dptday = deptdatenew.getDate();
var dptmon = (deptdatenew.getMonth() + 1);
var dptYear = deptdatenew.getFullYear()
if (dptday.toString().length==1){dptday="0"+dptday;}
if (dptmon.toString().length==1){dptmon="0"+dptmon;}
var departuredatenew = dptday + "/" + dptmon + "/" + dptYear;
$("#calendardept").val(departuredatenew);
// changes done by parul starts for 30 days limit
var SelectedDate = CleanDate($("#arrivaldate").val());
var date1 = $.datepicker.parseDate(customFormat(), SelectedDate);
var d = new Date();
var diff = date1 - d;
diff = (diff / (1000 * 3600 * 24));
var maxdiff = parseInt(diff);
maxdiff = maxdiff + 31;
var b = new Date();
var c = new Date(b.getFullYear(), b.getMonth(), b.getDate());
if (a.id == 'depaturedate') {
if ($('#arrivaldate').datepicker('getDate') != null) {
//c = $('#arrivaldate').datepicker('getDate', '+3d');
b = CleanDate($("#arrivaldate").val());
c = $.datepicker.parseDate(customFormat(), b);
c.setDate(c.getDate() + 1);
}
}
return {
minDate: c,
maxDate: maxdiff + "d"
} // changes done by parul ends
}
});
$("#depaturedate").change(function () {
var deptdateold = CleanDate($("#depaturedate").val());
var deptdatenew = $.datepicker.parseDate(customFormat(), deptdateold);
var dptday = deptdatenew.getDate();
var dptmon = (deptdatenew.getMonth() + 1);
var dptYear = deptdatenew.getFullYear()
if (dptday.toString().length==1){dptday="0"+dptday;}
if (dptmon.toString().length==1){dptmon="0"+dptmon;}
var departuredatenew = dptday + "/" + dptmon + "/" + dptYear;
$("#calendardept").val(departuredatenew);
$("#depaturedate").val(ChangeDateFormat(deptdatenew));
});
$( "#c_checkout" ).click(function() {
$("#depaturedate").datepicker("show");
});
$( "#c_checkin" ).click(function() {
$("#arrivaldate").datepicker("show");
});
});
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 2);
var tomorrow = new Date(tomorrow).toLocaleDateString('en-GB',
{
day : 'numeric',month : 'short', year : 'numeric'
}).split(' ').join(' ');
$('#arrivaldate').val(tomorrow);
var tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 3);
var tomorrow = new Date(tomorrow).toLocaleDateString('en-GB',
{
day : 'numeric',month : 'short', year : 'numeric'
}).split(' ').join(' ');
$('#depaturedate').val(tomorrow);
}); //JQuery Document Ready Section Finished Here

jQuery datepicker not selectable anymore

I have a jQuery datepicker that used to be working very well. However, since yesterday, I must have changed something. When I hover over the calendar, nothing happens. When I click on the calendar, nothing works. But, I am able to change the behaviour of the calendar via code. As you can see, I was able to remove the prev and next buttons in the first calendar. Is there anything I forgot to check? Why can I not select any date of the calendar anymore? Any hint is appreciated. Btw, I checked the code on JSFiddle, and there it is working :(
This is my JavaScript:
$(function() {
var startDate;
var endDate;
var selectCurrentWeek = function() {
window.setTimeout(function () {
$('#datepicker').find('.ui-datepicker-current-day tr').addClass('ui-state-hover');
$('#datepicker').find('.ui-datepicker-next').remove();
$('#datepicker').find('.ui-datepicker-prev').remove();
}, 1);
}
$('#datepicker').datepicker( {
showOtherMonths: true,
selectOtherMonths: false,
onSelect: function(dateText, inst) {
var date = $(this).datepicker('getDate');
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay());
endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() + 6);
$('#calendar').weekCalendar('gotoWeek', date);
selectCurrentWeek();
},
beforeShowDay: function(date) {
var cssClass = '';
if(date >= startDate && date <= endDate)
cssClass = 'ui-datepicker-current-day';
return [true, cssClass];
},
onChangeMonthYear: function(year, month, inst) {
selectCurrentWeek();
}
});
$('#datepicker' ).datepicker( "option", $.datepicker.regional[ 'de' ] );
$('#datepicker').find('.ui-datepicker-next').remove();
$('#datepicker').find('.ui-datepicker-prev').remove();
$('#datepicker .ui-datepicker-calendar tr').live('mousemove', function() { $(this).find('td a').addClass('ui-state-hover'); });
$('#datepicker .ui-datepicker-calendar tr').live('mouseleave', function() { $(this).find('td a').removeClass('ui-state-hover'); });
// handling datepicker classes
var startDate;
var endDate;
var selectCurrentWeek_next = function() {
window.setTimeout(function () {
}, 1);
}
$('#datepicker_next_month').datepicker( {
showOtherMonths: true,
selectOtherMonths: true,
onSelect: function(dateText, inst) {
var date = $(this).datepicker('getDate');
$('#calendar').weekCalendar('gotoWeek', date);
selectCurrentWeek_next();
},
beforeShowDay: function(date) {
var cssClass = '';
return [true, cssClass];
},
onChangeMonthYear: function(year, month, inst) {
selectCurrentWeek_next();
}
});
$('#datepicker_next_month' ).datepicker( "option", $.datepicker.regional[ 'de' ] );
$('#datepicker_next_month' ).datepicker().datepicker('setDate','+1m');
$('#datepicker_next_month .ui-datepicker-calendar tr').live('mousemove', function() { $(this).find('td a').addClass('ui-state-hover'); });
$('#datepicker_next_month .ui-datepicker-calendar tr').live('mouseleave', function() { $(this).find('td a').removeClass('ui-state-hover'); });
});
This is the relevant HTML part:
<div id="datepicker"></div>
<div id="datepicker_next_month"></div>
These are the scripts I import:
<script type='text/javascript' src='libs/jquery-1.4.4.min.js'></script>
<script type='text/javascript' src='libs/jquery-ui-1.8.11.custom.min.js'></script>
<script type='text/javascript' src='libs/jquery-ui-i18n.js'></script>
Here is an image of the calendar:
I finally found the problem. I used Google Chroms Element inspector and discovered, that another div was overlaying the datepicker divs. After fixing that problem, everything works again :)

FullCalendar Select doesn't work if using fullcalendar.js instead of fullcalendar.min.js

All,
I'm using the example that is in the fullcalendar download, however I'd like to use the fullcalendar.js instead of the fullcalendar.min.js. When I make this change though the select option doesn't work (I can't select any time range and the pop up doesn't come up).
Any ideas what has to change in the fullcalender.js file to make this work?
EDIT I'm using the following code for my select:
selectable: true,
selectHelper: true,
select: function(start, end, allDay) {
var title = prompt('Event Title:');
calendar.fullCalendar('unselect');
},
EDIT #2 The issue seems to be with the selectHelper. If I comment out that part I can select the time that I want to use but it doesn't have the nice overlay. Here is the code from fullcalendar.js that does this:
function renderSlotSelection(startDate, endDate) {
var helperOption = opt('selectHelper');
coordinateGrid.build();
if (helperOption) {
var col = dayDiff(startDate, t.visStart) * dis + dit;
if (col >= 0 && col < colCnt) { // only works when times are on same day
var rect = coordinateGrid.rect(0, col, 0, col, slotContent); // only for horizontal coords
var top = timePosition(startDate, startDate);
var bottom = timePosition(startDate, endDate);
if (bottom > top) { // protect against selections that are entirely before or after visible range
rect.top = top;
rect.height = bottom - top;
rect.left += 2;
rect.width -= 5;
if ($.isFunction(helperOption)) {
var helperRes = helperOption(startDate, endDate);
if (helperRes) {
rect.position = 'absolute';
rect.zIndex = 8;
selectionHelper = $(helperRes)
.css(rect)
.appendTo(slotContent);
}
}else{
rect.isStart = true; // conside rect a "seg" now
rect.isEnd = true; //
selectionHelper = $(slotSegHtml(
{
title: '',
start: startDate,
end: endDate,
className: ['fc-select-helper'],
editable: false
},
rect
));
selectionHelper.css('opacity', opt('dragOpacity'));
}
if (selectionHelper) {
slotBind(selectionHelper);
slotContent.append(selectionHelper);
setOuterWidth(selectionHelper, rect.width, true); // needs to be after appended
setOuterHeight(selectionHelper, rect.height, true);
}
}
}
}else{
renderSlotOverlay(startDate, endDate);
}
}
I'm not sure why this wouldn't work but it isn't. Any ideas on what to change?
Thanks in advance!
This looks like a bigger issue and the issue revolves around a new issue in how jQuery does things. The issue is caused by a change in the regular expression which is used to normalize 'mouse event properties' in the Event object: https://github.com/jquery/jquery/blob/master/src/event.js#L7
There is a thread going on here to monitor this solution:
http://code.google.com/p/fullcalendar/issues/detail?id=1168
This fix doesn't work in IE however.

Highlight <TR> entire week datepicker

I have a datepicker that is fully functional and is working whereby you can select an entire commencing working week (Mon-Fri). What I am now trying to do is extend it a little further so that when I click on a specific week. It will highlight that entire . I have it paritally working which looks like the following: Calandar preivew. It can be seen that the problem I am having is that the table row to me seems to be doing a odd, even, odd even. As for the first week I highlight the row is highlighted in red and the cells are hihglighted in yellow. Then the week afer that it work fines and then if I was to select the week after that the same would be repeated. I tried checking the jquery-ui-1.8.4.custom.css and the jquery-ui.css, and had no luck. What seems to confuse me is why are the cells being highlighted in yellow? The code follows for my datepicker.
Javascript:
$(function()
{
var startDate;
var endDate;
var selectCurrentWeek = function()
{
window.setTimeout(function () { $('.week-picker').find('.ui-datepicker-current-day a').addClass('ui-state-active')}, 1);
}
function check(d) {
if(d.length() == 2) {
dd = d;
return dd;
} else {
dd = "0" + myDateParts[0];
return dd;
}
}
var selectedWeek;//remember which week the user selected here
$('.week-picker').datepicker( {
beforeShowDay: $.datepicker.noWeekends,
showOtherMonths: true,
selectOtherMonths: true,
onSelect: function(dateText, inst) {
var date = $(this).datepicker('getDate');
startDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() + 1);
endDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() - date.getDay() + 6);
var dateFormat = 'yy-mm-dd'
var newDate = $('#startDate').text($.datepicker.formatDate( dateFormat, startDate, inst.settings ));
var oldDate = document.getElementById('startDate');
var date_textnode = oldDate.firstChild;
var date_text = date_textnode.data;
myDateParts = date_text.split("-");
var dd = myDateParts[2];
var mm = myDateParts[1];
var yy = myDateParts[0];
selectCurrentWeek();
window.location.href = "/timesheet?week_commencing=" + yy + "-" + mm + "-" + dd;
},
beforeShowDay: function(date) {
var cssClass = '';
if(date >= startDate && date <= endDate)
cssClass = 'ui-datepicker-current-day';
return [true, cssClass];
},
onChangeMonthYear: function(year, month, inst) {
selectCurrentWeek();
}
});
$( ".week-picker" ).datepicker().click(function(event) {
// highlight the TR
$(".ui-datepicker-current-day").parent().addClass('highlight');
// highlight the TD > A
$(".ui-datepicker-calendarr-day").siblings().find('a').addClass('white');
});
$('.week-picker .ui-datepicker-calendar tr').live('mousemove', function() { $(this).find('td a').addClass('ui-state-hover'); });
$('.week-picker .ui-datepicker-calendar tr').live('mouseleave', function() { $(this).find('td a').removeClass('ui-state-hover'); });
});
HTML
<div class="datepicker borderbox">
<b><center>Hours for Week commencing: <span id="startDate"></span></center></b>
<div class="week-picker"></div>
</div>
CSS
.highlight {
border: 1px solid red;
}
.white {
background: white !important;
}
I have tried looking at the following stackoverflow question Related stackoverflow. Had no luck with this, as the link was broken and also tried viewing the it in JSfiddle. Further to this the way I have set my datepicker is different.
I am intially trying to get my calendar to work like this But for some reason when I try do this I get the following. Is this something to do with the css
Update2
Calendar & Firebug output
Is this what you want?
http://jsfiddle.net/william/YQ2Zw/2/
There were a couple of things that went wrong:
The ui-datepicker-current-day class was applied to a <td> element, so it only needs to travel one level up to find the <tr>, so I took away one call to parent():
$(".ui-datepicker-current-day").parent().addClass('highlight');
You set multiple days with the ui-datepicker-current-day class. That was why I needed to use the :eq(0) selector to only select the first element:
$(".ui-datepicker-current-day:eq(0)").siblings().find('a').addClass('white');
Also, you were calling the wrong class for the statement above.

Categories

Resources