I'm using jQuery fullCalendar. A client wants to see only their bussiness opening hours in the calendar. Is that possible? How?
Example: a bussiness opens from 9am to 1pm and from 3pm to 10pm
The minTime and maxTime options will let you set the first and last hour. I don't think you can have a calendar with a break in the middel though.
Maybe you could create a recurring event called lunch and color it differently to your actual events
On current fullcallendar version (5.x), maxTime and minTime options where renamed to slotMaxTime and slotMinTime.
To hide most business time - i.e., night and/or non-working days:
Calculate some values right from your businessHours specification
const workSpec = [
{
daysOfWeek: [1, 2, 3, 4],
startTime: '08:00',
endTime: '18:00'
}
{
daysOfWeek: [5],
startTime: '09:00',
endTime: '14:00'
}
]
/*
* calculate the following:
* - minimum "opening time"
* - maximum "opening time"
* - working days
* - non-working days
*/
const workMin = workSpec.map(item => item.startTime).sort().shift()
const workMax = workSpec.map(item => item.endTime).sort().pop()
const workDays = [...new Set(workSpec.flatMap(item => item.daysOfWeek))]
const hideDays = [...Array(7).keys()].filter(day => !workDays.includes(day))
Use calculated values on the related properties - i.e. for #fullcalendar/react:
<FullCalendar
//...
businessHours={workSpec}
slotMinTime={workMin}
slotMaxTime={workMax}
hiddenDays={hideDays}
//...
/>
Disclaimer: this was a quick-n-dirty go. There may be refactors to improve performance
there has been an update on fullcalendar that allows you to apply business hours
http://fullcalendar.io/docs/display/businessHours/
however, i don't think it ll allow you to impement a break within the day..
over here
Apply different timeslots and ranges for each day on Fullcalendar
you ll find my approach on a similar issue that i used Javascript to prevent selection of specific period and also with css i highlighted the areas that i didn't want to be able to be selected..
To completely hide the desired row (NON business/break hour) you have to modify the following method inside fullcalendar.js:
// Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
renderSlatRowHtml: function() {...}
and then avoid entering the while clause that adds the html code:
while (slotTime < this.maxTime) {...}
you can add an if clause up inside that while, or even more work out to enter a config param to check inside that while iteration.
hiding the break period is still not possibleas far as i know,
but version 2 has now to peoperties minTime and maxTime which you can use to hide non-business hours.
Documentation here: http://fullcalendar.io/docs/agenda/minTime/
Use selectConstraint and eventConstraint options to prevent click event in non business hours (from full calendar 2.2version). in my case i used selectConstraint: "businessHours" https://fullcalendar.io/docs/selection/selectConstraint/ https://fullcalendar.io/docs/event_ui/eventConstraint/
For anyone trying this.
This one is to remove the non business
<style>
.fc .fc-non-business {
background: var(--fc-non-business-color);
display: none;
}
</style>
This one is for the business hours to remove those time that you want to disable
selectConstraint: 'businessHours',
businessHours: {
daysOfWeek: [ 1, 2, 3, 4,5,6], // Monday - Thursday
startTime: '07:00', // a start time (10am in this example)
endTime: '20:00', // an end time (6pm in this example)
}
Use Content height to adjust the calendar height
contentHeight: 680,
This is the whole configuration for the calendar
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'timeGridWeek',
hiddenDays: [0],
allDaySlot: false,
selectOverlap:false,
selectable: true,
selectConstraint: 'businessHours',
businessHours: {
daysOfWeek: [ 1, 2, 3, 4,5,6], // Monday - Thursday
startTime: '07:00', // a start time (10am in this example)
endTime: '20:00', // an end time (6pm in this example)
},
select: function(data) {
var start = formatDateToTime(data.start);
var end = formatDateToTime(data.end);
var date = data.startStr.substring(0, 10);
var uid = "add";
$.ajax({
type: "POST",
url: "{{ url('event/getModal')}}",
data: {
uid: uid,
start: start,
end: end,
date: date
},
success: function(response) {
$("#modal-view").modal('toggle');
$("#modal-view").find(".modal-title").text("Add Event");
$("#modal-view").find("#modal-display").html(response);
}
});
},
headerToolbar:{
start: '', // will normally be on the left. if RTL, will be on the right
center: '',
end: '' // will normally be on the right. if RTL, will be on the left
},
dayHeaderFormat:{ weekday: 'long' },
editable: true,
events: <?php echo $Events?>,
contentHeight: 680,
eventClick: function(calEvent, jsEvent, view) {
console.log(calEvent);
},
viewDidMount: function(event, element) {
$('td[data-time]').each(function() {
var time = $(this).attr("data-time");
if(time < "07:00:00"){
$(this).parent().remove();
}
if(time > "19:30:00"){
$(this).parent().remove();
}
console.log($(this).parent());
});
},
eventDidMount: function(event, element) {
// To append if is assessment
if(event.event.extendedProps.description != '' && typeof event.event.extendedProps.description !== "undefined")
{
$(event.el).find(".fc-event-title").append("<br/><b>"+event.event.extendedProps.description+"</b>");
$(event.el).find(".fc-event-title").append("<br/><b>"+event.event.extendedProps.prof+"</b>");
}
}
});
calendar.render();
Sample Output
Check this
Related
I'm trying to change the background color of an event (in Day View) of fullcalendar v4. I've spent hours trying to implement eventRender, to no avail. This has led me to find other workarounds, but now, I'm striking out!
I'm trying to figure out the solution explained here: [Fullcalendar - change event color based on value ..
But, every time the search for the word 'yes' is TRUE, I get an error in chrome console saying 'Failure parsing JSON'. If I change the search query to something that will create 'false', I do not get this error. To me, this means that the search is working, but the event render function is failing somehow.
my code:
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
plugins: [ 'interaction', 'resourceDayGrid', 'resourceTimeGrid' ],
defaultView: 'resourceTimeGridDay',
defaultDate: '<?php echo $startdate?>',
validRange: {
start: '<?php echo $startdate?>',
end: '<?php echo $maxdaycal?>'
},
height: 700,
...
...
eventSources: [
{
url: 'getevents2.php?festid=<?php echo $festid?>&room=<?php echo $roomabv?>',
cache: false,
},
{
url: 'getbreaks2.php?festid=<?php echo $festid?>&room=<?php echo $roomabv?>',
cache: false,
color: 'grey',
editable: false,
}
],
eventRender: function(info) {
if(info.event.extendedProps.desc == "yes") {
element.style.css('background-color', '#000');
}
},
....
});
calendar.render();
});
My goal: Search for the word "Accomp" in the title of the element (probably in info.event.title) .. and have the background change to a different color .. like red .. or something.
I've also tried to show an Icon in this field if the word Accomp is present, but -- I had to show it in a modal, because I couldnt get eventrender to show html.
I think this is because of the differences in FC v4 .. but I'm not sure.
I've also tried: [Is it possible to assign the background colour of a FullCalendar event based on its title? .. but I couldn't get that sorted out either.
UPDATE: The search function is working, as I can see it in the console log, but whenever I try to set the css, the calendar does not render.
eventRender: function(info) {
console.log(info.event.title);
if(-1 != info.event.title.indexOf("Accomp")) {
console.log(info.event.title);
fc-title.css('background-color', '#000');
}
},
This is based on some other answers that areavailable, but it appears that there are differences in FC4... This works for me!
eventRender: function(info) {
if(-1 != info.event.title.indexOf("Accomp")) {
info.el.style.backgroundColor = "red";
}
},
I am facing an issue with fullcalendar, I am trying to change the color of complete column of specific dates. I have tried this, but it's changing on only day cell color, I want to change complete column color of that specific date
dayRender: function (date, cell) {
var today = moment('2018-12-28T00:00Z');
if (date.isSame(today, "day")) {
cell.css("background", "#EEEEEE");
//cell.addClass('fc-selectable-false');
}
}
By rendering property for event object to "background",
something like this,
$('#calendar').fullCalendar({
defaultDate: '2018-11-10',
defaultView: 'agendaWeek',
events: [
{
start: '2018-12-10T10:00:00',
end: '2018-12-10T16:00:00',
rendering: 'background'
}
]
});
for more information please see fullcalendar documentation: https://fullcalendar.io/docs/background-events
I'm using Fullcalendar and I need to show all the current year plus the next two month of the next year using a timeline view.
If I use the visibleRange option in this way:
visibleRange: function (currentDate) {
return {
start: currentDate.year()+'-01-01',
end: currentDate.year()+1 + '-02-28',
};}
The calendar show the correct period but the navigation button 'next' stop working.
I also tried to use the duration option instead but I don't know how to set the "start" period.... the calendar start always at current date.
I think there is a solution that not require the writing of a full custom view to do so.
The solution to this involves setting the dateIncrement value - this tells the next/prev buttons how far to increase/decrease the visible dates by when you customise the view range like this.
Here's an example. N.B. I've used momentJS's built-in functions, rather than string concatenation, to provide a more robust and neater way of setting the visible range. It's probably also a good idea to set the slotDuration to something that won't produce a massive long calendar. I've used a 1 month duration as an example, but obviously you can configure it to whatever you need.
$('#calendar').fullCalendar({
schedulerLicenseKey: 'GPL-My-Project-Is-Open-Source',
defaultView: 'timeline',
header: {
left: 'prev,next today',
center: 'title',
right: 'timeline'
},
slotDuration: { months: 1 },
dateIncrement: { years: 1 },
visibleRange: function (currentDate) {
return {
start: currentDate.clone().startOf('year'),
end: currentDate.clone().startOf('year').add({ years: 1, months: 2}),
};
},
//...etc
});
The dateIncrement setting is documented here: https://fullcalendar.io/docs/current_date/dateIncrement/
I'm using Fullcalendar with a Google Calendar so I can't apply a class to an event as far as I'm aware.
What I want to do should be quite simple and I'm sure the answer will involve eventRender but I just can't get it working.
Simply: change the entire background color of the cell that contains any event (all events are "all day" within the Google Calendar).
What I'm trying to achieve is an "availability" state; any event is "unavailable" i.e. background color red.
Yes, you can do it with eventRender. You'll have to find the td that contains that event. If you inspect the fullCalendar, you'll note the tds have a data-date attribute for that particular day. That is how we will find the td that has an event in it so we can change the background color to red, specifically using:
eventRender: function (event, element) {
var dataToFind = moment(event.start).format('YYYY-MM-DD');
$("td[data-date='"+dataToFind+"']").addClass('activeDay');
}
In this example, the first line in eventRender uses moment to format the event start date into the format needed to match the data-date attribute value. The second line finds a td with the data-date attribute having a value of dataToFind and then adds a class we make up called activeDay, assuming you add something like this to your head/stylesheet:
<style>
.activeDay {background-color:#ff0000 !important;}
</style>
$('#fullCal').fullCalendar({
events: [{
title: 'Main Event 1',
start: new Date(),
end: new Date(),
allDay: false
}, {
title: 'Main Event 2',
start: '2014-10-03 19:00',
end: '2014-10-03 19:30',
allDay: false
}, {
title: 'Main Event 3',
start: '2014-10-15 17:00',
end: '2014-10-15 18:00',
allDay: false
}, {
title: 'Main Event 4',
start: '2014-11-30 7:00',
end: '2014-11-30 18:00',
allDay: false
}, ],
header: {
left: '',
center: 'prev title next',
right: ''
},
eventRender: function(event, element) {
var dataToFind = moment(event.start).format('YYYY-MM-DD');
$("td[data-date='" + dataToFind + "']").addClass('activeDay');
}
});
.activeDay {
background-color: #ff0000 !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.8.3/moment.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.1.1/fullcalendar.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.1.1/fullcalendar.min.js"></script>
<p>Example:</p>
<div id="fullCal"></div>
The answer of #MikeSmithDev does not work if you have events on multiple days.
If you have multiple days use this javascript:
eventRender: function (event, element) {
var start = moment(event.start);
var end = moment(event.end);
while( start.format('YYYY-MM-DD') != end.format('YYYY-MM-DD') ){
var dataToFind = start.format('YYYY-MM-DD');
$("td[data-date='"+dataToFind+"']").addClass('dayWithEvent');
start.add(1, 'd');
}
}
It uses the same principle as MikeSmithDev's, so you must use the same css.
I am facing problem while adding two agendaWeekView in a single calendar. Please have a look the calendar config.
header:{
left: 'prev,next',
center: 'title',
right: 'agendaWeek agendaWeek'
},
here I am calling agendaWeek two times, It appears two tab in the calendar called "Week" but when I clicked anyone of them both views are activated and I am also not able to change the text of the week tabs. So please give some suggestion for it.
From the looks of it, you are not closing the right header variable with a quotation.
Maybe this will work.
header:{
left: 'prev,next',
center: 'title',
right: 'agendaWeek agendaWeek'
},
Not sure though. If you could post a plunker of fiddle then we could diagnose with ease.
Now we can duplicate views or create own custom views in the single calenndar. Here is the solution.
We need to change in the fullcalendar.js file.
Firstly add your custom view name, according to my question I wanted to duplicate agendaView so that's why my view name will be "duplicateAgendaWeek". Set the name into defaults.
buttonText: {
prev: "<span class='fc-text-arrow'>‹</span>",
next: "<span class='fc-text-arrow'>›</span>",
prevYear: "<span class='fc-text-arrow'>«</span>",
nextYear: "<span class='fc-text-arrow'>»</span>",
today: 'today',
month: 'month',
week: 'Weekly',
day: 'Daily',
duplicateAgendaWeek: 'Duplicate Week' // here is the name of my view.
},
Now duplicate the existing agendaWeek function with your view name.
fcViews.duplicateAgendaWeek= DuplicateAgendaWeekView;
function DuplicateAgendaWeekView(element, calendar) {
var t = this;
// exports
t.render = render;
// imports
AgendaView.call(t, element, calendar, 'duplicateAgendaWeek');
var opt = t.opt;
var renderAgenda = t.renderAgenda;
var formatDates = calendar.formatDates;
function render(date, delta) {
if (delta) {
addDays(date, delta * 7);
}
var start = addDays(cloneDate(date), -((date.getDay() - opt('firstDay') + 7) % 7));
var end = addDays(cloneDate(start), 7);
var visStart = cloneDate(start);
var visEnd = cloneDate(end);
var weekends = opt('weekends');
if (!weekends) {
skipWeekend(visStart);
skipWeekend(visEnd, -1, true);
}
t.title = formatDates(
visStart,
addDays(cloneDate(visEnd), -1),
opt('titleFormat')
);
t.start = start;
t.end = end;
t.visStart = visStart;
t.visEnd = visEnd;
renderAgenda(weekends ? 7 : 5);
}
}
;;
Now the last one need to set formats for our custom views.
// time formats
titleFormat: {
month: 'MMMM yyyy',
week: "MMM d[ yyyy]{ '—'[ MMM] d yyyy}",
duplicateAgendaWeek: "MMM d[ yyyy]{ '—'[ MMM] d yyyy}", // set your view format here
day: 'dddd, MMM d, yyyy'
},
columnFormat: {
month: 'ddd',
week: 'ddd M/d',
duplicateAgendaWeek: 'ddd M/d',// set your view format here
day: 'dddd M/d'
},
Now just call the view name from your controller.
header:{
left: 'prev,next',
center: 'title',
right: 'agendaDay agendaWeek duplicateAgendaWeek',
},