I have Dates like:
Start Date : 2013-12-04
End Date : 2013-12-06
Now I want to put a restriction that Smaller Date should not be Dragged after Bigger Date and Bigger Date should not be dragged before smaller Date.
Is this possible to implement ?
Here is my code so far:
$(document).ready(function() {
$('#calendar').fullCalendar({
editable: true,
events: "json-data.php",
eventDrop: function(event, delta) {
alert(event.title + ' was moved ' + delta + ' days\n' +
'(Dragged)');
},
loading: function(bool) {
if (bool) $('#loading').show();
else $('#loading').hide();
}
});
});
As shown in the documentation on eventDrop : the eventDrop callback receives among its arguments a revertFunc function, which, when called, reverts the event back to its original position.
Here is an outline of how you can write your eventDrop callback :
eventDrop : function(event,dayDelta,minuteDelta,allDay,revertFunc) {
var smaller = /* get date of (moved) smaller event */,
bigger = /* get date of (moved) bigger event */;
if ( smaller > bigger ) {
alert('smaller should stay before bigger');
revertFunc();
}
}
You can use 'revertFunc' (documentation here)
Put something like this in eventDrop
if (initialDate.getTime()>finalDate.getTime()) {revertFunc();}
getTime is to get the number of milliseconds passed since 1970(this is used for comparing two dates)
And by initialDate and finalDate I'm referring to the initial(drag start) and final(drag end) Date instances. In this case you can probably replace that init/final check by
if (dayDelta<0)
dayDelta is predefined in fullcalendar
Related
I'm having a little issue with FullCalendar v5, I configured it with the dayGridMonth View and I would like to listen when the user changes the current month ...
For example, if he is seeing February and click on next he'll see march, so I was expected for a handler like onChange or onMonthChange but I didn't find anything in the documentation to do something like this ...
I figured how to get around the problem by making my own prev / next buttons and triggering my custom handler on the click ... But I would like to know if there is a vanilla way to do it?
Thanks for your answers.
As mentionned by #Devsi Odedra, the answer was datesSet
The doc : https://fullcalendar.io/docs/datesSet
This is my actual code if it can help someone :
new Calendar(document.getElementById("calendar"), {
plugins: [ dayGridPlugin, interactionPlugin ],
datesSet: event => {
// As the calendar starts from prev month and end in next month I take the day between the range
var midDate = new Date((event.start.getTime() + event.end.getTime()) / 2).getMonth()
var month = `0${ midDate.getMonth() + 1 }`.splice(0, -1)
doSomethingOnThisMonth(month, midDate.getFullYear())
}
});
function doSomethingOnThisMonth(month, year) {
fetch(`myApi.com/something?month=${ month }&year=${ year }`)
.then((result) => {
// Do something
})
}
I want the time will be selected when clicking on timeslot of a day in fullclendar. i.e, if i click on 9.00am - 9.30am slot, i want both time. this is my code:-
$('#calendar').fullCalendar({
allDayDefault: false,
dayClick: function(date, allDay, jsEvent, view){
popupopen = 1;
var clickedTime = 'Clicked on: ' + date.format();
});
Now, if i click 10.00 am,this gives:- Clicked on: 2016-07-19T10:00:00. But, i only want,10.00. How to get that? And also when i click on 10.00 -10.30 slot, how to get both time?
For your first question: date is a moment.js object, so just use moment.js methods.
var clickedTime = date.format("h:mm a");
As for getting the second date, I can only think of setting it manually using slotDuration and then since you will know this value, you can add it to the start date.
E.g. in my calendar the slotDuration is 1 hour, so I would do date.add(1, 'hours');
I am using FullCalendar jQuery plugin and I need to modify it. My goal is to automatically display hour in every single cell, in every single day as event. I am creating an online registration system for my application and I need this functionality. After user clicks any hour and confirms it, I want to disable clicks for that chosen hour.
You can see on the picture on Monday example what I want to achive(but for all days):
No need to alter the plugin itself. Just make good use of all of the options available.
If you are just trying to change the content of any event that is displayed on the calendar, pass a function to the eventRender callback that returns a new DOM element. Use the momentjs library to display a formatted string for the start property of the event. For example:
var calendarOptions = {
// ...other options
eventRender: function(event, element) {
$(element).html(moment(event.start).format('h:mm'));
return element;
}
}
When you are done with calendarOptions, you'll obviously need to pass it to fullCalendar:
$(calElement).fullCalendar(calendarOptions);
If you want to display an event in every single cell, then first make an array of events for every cell increment... something like this:
var myEvents = [];
var timeCursor = moment(startTime);
while (+timeCursor < +moment(endTime)) {
var start = +timeCursor;
timeCursor = timeCursor.add(timeIncrement,'minutes');
var end = +timeCursor;
myEvents.push({
start: start,
end: end
});
}
(where you've previously set startTime, endTime, and timeIncrement!)
Then the events property of the calendar options to this array before passing to fullCalendar:
calendarOptions.events = myEvents;
Finally, to handle clicks on an event, pass a function to the eventClick callback option that does whatever you want. For example, if you are keeping track of which events have been clicked, you might want to push their start times to an array:
var clickedEvents = [];
calendarOptions.eventClick: function(calEvent, jsEvent) {
if (clickedEvents.indexOf(calEvent.start) < 0) {
clickedEvents.push(calEvent.start);
} else {
return false;
}
}
Then of course you might want to modify your eventRender callback again to have your event display reflect this status by changing the style of the element, adding a line like this before returning the altered element:
if (clickedEvents.indexOf(calEvent.start) < 0) {
$(element).addClass('already-clicked');
}
(Be sure to set the style for .already-clicked in your CSS with something like cursor: not-allowed and opacity: 0.5.)
fullCalendar rocks!
I am trying to use #georgedyer code, but I have some issues :/
Firstly i will show You how it looks like in my MVC 4 application:
Here is my View(html) for display fullCallendar. The point of this is only to display events for every single cell:
//path to installed moment.js
<script src="~/Scripts/moment.js"></script>
<script>
$(document).ready(function () {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,agendaDay'
},
defaultView: 'agendaWeek',
editable: true,
allDaySlot: false,
selectable: true,
slotMinutes: 15,
events: myEvents,
eventRender: function(event, element) {
$(element).html(moment(event.start).format('h:mm'));
return element;
},
eventClick: function (calEvent, jsEvent, view) {
alert('You clicked on event id: ' + calEvent.start
+ "\nSpecial ID: " + calEvent.someKey
+ "\nAnd the title is: " + calEvent.title);
},
(...)
});
//HERE IS YOUR CODE ABOUT CREATING ARRAY
var myEvents = [];
var timeCursor = moment('2015-09-08');
while (+timeCursor < +moment('2015-10-01'))
{
myEvents.push { start: timeCursor }
timeCursor = timeCursor.add('15', 'minutes');
}
</script>
<div class="container">
<div id='calendar' style="width:65%"></div>
</div>
I have question about one line of code because VisualStudio display warning here about semicolon: myEvents.push { start: timeCursor }.
I tried to change it to this: myEvents.push ({ start: timeCursor }), error disappear, but still doesn't work :/
I don't know what is wrong in this. After run this code It just display empty FullCalendar. I know this code is a little different than your but I think this should work the same way. Please for some help here.
Edit: I think that eventRender: function works just fine because if I creating an event by myself,It displays hour like it should. So problem is only in creating events. I think in my code my myEvents array is in wrong place and when I invoke it in events: myEvents array has zero items.
Im using Fullcalendar v2.1.1. I want to make action:
Jump to agenda day from month view after picking the date.
When Iam on agendaDate view and i click on event I get modal.
Here are my tries:
dayClick: function(date, jsEvent, view) {
self.showEditDateModal(jsEvent.start);
}
this.showEditDateModal = function(startdate) {
self.calendarAvailable.fullCalendar('changeView', 'agendaDay');
self.calendarAvailable.fullCalendar('gotoDate', startdate);
}
And here is modal that I want to appear when you click from agendaDay view:
$('#reservationDateModal').modal('show');
I found this:StackLink
but when I use it that way:
self.calendarAvailable.fullCalendar('gotoDate', 2010, 5);
I get date: 1 January 1970
I also try (from documentation) to pass there date object but nothing help FullCallendar docs
I made it finally:
To use 'gotoDate' you need to pass there string like this:
self.calendarAvailable.fullCalendar('gotoDate', '2015-04-24');
and to make it automatically:
this.changeViewtoAgendaDay = function(startdate) {
var goto = startdate.format('YYYY-MM-DD');
self.calendarAvailable.fullCalendar('changeView', 'agendaDay');
self.calendarAvailable.fullCalendar('gotoDate', goto);
}
Answer for second point is simple if made for view:
if(view.name=='agendaDay'){ self.showEditDateModal(); }else{
self.changeViewtoAgendaDay(calEvent.start); }
Where:
this.showEditDateModal = function() {
$('#reservationDateModal').modal('show');
}
I am using eternicode bootstrap-datepicker;
I would like to know how to configure Bootstrap Datepicker to restrict available dates to be selected. My point is, when some data is ready in a particular date. That date can be selected by user.
At the current point, I am restricting by 7 days from now. However, Saturday and Sundays are days which never have some data;
In this way, I can just show a range of dates, but no "holes" between those ranges. So, I would like to know how to configure Bootstrap Datepicker to restrict available dates to be selected from user.
Bootstrap itself does not have a built in datepicker last i checked. If however you are talking about the bootstrap-datepicker third party library that eternicode wrote.. I believe it supports the same events as the jquery datepicker.. so:
beforeShowDay
Function(Date). Default: $.noop
A function that takes a date as a parameter and returns one of the following values:
undefined to have no effect
A Boolean, indicating whether or not this date is selectable
A String representing additional CSS classes to apply to the date’s cell
An object with the following properties:
enabled: same as the Boolean value above
classes: same as the String value above
tooltip: a tooltip to apply to this date, via the title HTML attribute
usage something like this (below example only allows weekends and the two dates in the custom array below to be selected):
// use this to allow certain dates only
var availableDates = ["15-1-2014","16-1-2014"];
$(function()
{
$('#txtDate').datepicker({
beforeShowDay:
function(dt)
{
// use dt.getDay() to restrict to certain days of the week
// or a custom function like "available" below to do more complex things
return [dt.getDay() == 0 || dt.getDay() == 6 || available(dt), "" ];
}
});
});
function available(date) {
dmy = date.getDate() + "-" + (date.getMonth()+1) + "-" + date.getFullYear();
if ($.inArray(dmy, availableDates) != -1) {
return true;
} else {
return false;
}
}
Lastly, a working FIDDLE to show above in action.. using jquery datepicker, but same difference...
Make as following:
var available_Dates = ["23/03/2014","21/03/2014"];
$('.datepicker').datepicker({
language: "pt-BR",
autoclose: true,
format: "dd/mm/yyyy",
default: 'dd/mm/yyyy',
beforeShowDay: function(date){
var formattedDate = $.fn.datepicker.DPGlobal.formatDate(date, 'dd/mm/yyyy', 'pt-BR');
if ($.inArray(formattedDate.toString(), available_Dates) == -1){
return {
enabled : false
};
}
return;
}
});