diff options
Diffstat (limited to 'library/fullcalendar/demos')
21 files changed, 2298 insertions, 0 deletions
diff --git a/library/fullcalendar/demos/background-events.html b/library/fullcalendar/demos/background-events.html new file mode 100644 index 000000000..a36fede8d --- /dev/null +++ b/library/fullcalendar/demos/background-events.html @@ -0,0 +1,109 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ], + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth' + }, + defaultDate: '2019-04-12', + navLinks: true, // can click day/week names to navigate views + businessHours: true, // display business hours + editable: true, + events: [ + { + title: 'Business Lunch', + start: '2019-04-03T13:00:00', + constraint: 'businessHours' + }, + { + title: 'Meeting', + start: '2019-04-13T11:00:00', + constraint: 'availableForMeeting', // defined below + color: '#257e4a' + }, + { + title: 'Conference', + start: '2019-04-18', + end: '2019-04-20' + }, + { + title: 'Party', + start: '2019-04-29T20:00:00' + }, + + // areas where "Meeting" must be dropped + { + groupId: 'availableForMeeting', + start: '2019-04-11T10:00:00', + end: '2019-04-11T16:00:00', + rendering: 'background' + }, + { + groupId: 'availableForMeeting', + start: '2019-04-13T10:00:00', + end: '2019-04-13T16:00:00', + rendering: 'background' + }, + + // red areas where no events can be dropped + { + start: '2019-04-24', + end: '2019-04-28', + overlap: false, + rendering: 'background', + color: '#ff9f89' + }, + { + start: '2019-04-06', + end: '2019-04-08', + overlap: false, + rendering: 'background', + color: '#ff9f89' + } + ] + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 40px 10px; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #calendar { + max-width: 900px; + margin: 0 auto; + } + +</style> +</head> +<body> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/daygrid-views.html b/library/fullcalendar/demos/daygrid-views.html new file mode 100644 index 000000000..96220fb3e --- /dev/null +++ b/library/fullcalendar/demos/daygrid-views.html @@ -0,0 +1,109 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid' ], + header: { + left: 'prevYear,prev,next,nextYear today', + center: 'title', + right: 'dayGridMonth,dayGridWeek,dayGridDay' + }, + defaultDate: '2019-04-12', + navLinks: true, // can click day/week names to navigate views + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2019-04-01' + }, + { + title: 'Long Event', + start: '2019-04-07', + end: '2019-04-10' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-09T16:00:00' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-16T16:00:00' + }, + { + title: 'Conference', + start: '2019-04-11', + end: '2019-04-13' + }, + { + title: 'Meeting', + start: '2019-04-12T10:30:00', + end: '2019-04-12T12:30:00' + }, + { + title: 'Lunch', + start: '2019-04-12T12:00:00' + }, + { + title: 'Meeting', + start: '2019-04-12T14:30:00' + }, + { + title: 'Happy Hour', + start: '2019-04-12T17:30:00' + }, + { + title: 'Dinner', + start: '2019-04-12T20:00:00' + }, + { + title: 'Birthday Party', + start: '2019-04-13T07:00:00' + }, + { + title: 'Click for Google', + url: 'http://google.com/', + start: '2019-04-28' + } + ] + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 40px 10px; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #calendar { + max-width: 900px; + margin: 0 auto; + } + +</style> +</head> +<body> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/default.html b/library/fullcalendar/demos/default.html new file mode 100644 index 000000000..a2b3849c8 --- /dev/null +++ b/library/fullcalendar/demos/default.html @@ -0,0 +1,103 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid' ], + defaultDate: '2019-04-12', + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2019-04-01' + }, + { + title: 'Long Event', + start: '2019-04-07', + end: '2019-04-10' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-09T16:00:00' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-16T16:00:00' + }, + { + title: 'Conference', + start: '2019-04-11', + end: '2019-04-13' + }, + { + title: 'Meeting', + start: '2019-04-12T10:30:00', + end: '2019-04-12T12:30:00' + }, + { + title: 'Lunch', + start: '2019-04-12T12:00:00' + }, + { + title: 'Meeting', + start: '2019-04-12T14:30:00' + }, + { + title: 'Happy Hour', + start: '2019-04-12T17:30:00' + }, + { + title: 'Dinner', + start: '2019-04-12T20:00:00' + }, + { + title: 'Birthday Party', + start: '2019-04-13T07:00:00' + }, + { + title: 'Click for Google', + url: 'http://google.com/', + start: '2019-04-28' + } + ] + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 40px 10px; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #calendar { + max-width: 900px; + margin: 0 auto; + } + +</style> +</head> +<body> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/external-dragging-2cals.html b/library/fullcalendar/demos/external-dragging-2cals.html new file mode 100644 index 000000000..bf4f08470 --- /dev/null +++ b/library/fullcalendar/demos/external-dragging-2cals.html @@ -0,0 +1,75 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var srcCalendarEl = document.getElementById('source-calendar'); + var destCalendarEl = document.getElementById('destination-calendar'); + + var srcCalendar = new FullCalendar.Calendar(srcCalendarEl, { + plugins: [ 'interaction', 'dayGrid' ], + editable: true, + defaultDate: '2019-04-12', + events: [ + { + title: 'event1', + start: '2019-04-11T10:00:00', + end: '2019-04-11T16:00:00' + }, + { + title: 'event2', + start: '2019-04-13T10:00:00', + end: '2019-04-13T16:00:00' + } + ], + eventLeave: function(info) { + console.log('event left!', info.event); + } + }); + + var destCalendar = new FullCalendar.Calendar(destCalendarEl, { + plugins: [ 'interaction', 'dayGrid' ], + defaultDate: '2019-04-12', + editable: true, + droppable: true, // will let it receive events! + eventReceive: function(info) { + console.log('event received!', info.event); + } + }); + + srcCalendar.render(); + destCalendar.render(); + }); + +</script> +<style> + + body { + margin: 20px 0 0 20px; + font-size: 14px; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + } + + #source-calendar, + #destination-calendar { + float: left; + width: 600px; + margin: 0 20px 20px 0; + } + +</style> +</head> +<body> + + <div id='source-calendar'></div> + <div id='destination-calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/external-dragging-builtin.html b/library/fullcalendar/demos/external-dragging-builtin.html new file mode 100644 index 000000000..f9471b0ef --- /dev/null +++ b/library/fullcalendar/demos/external-dragging-builtin.html @@ -0,0 +1,149 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var Calendar = FullCalendar.Calendar; + var Draggable = FullCalendarInteraction.Draggable + + /* initialize the external events + -----------------------------------------------------------------*/ + + var containerEl = document.getElementById('external-events-list'); + new Draggable(containerEl, { + itemSelector: '.fc-event', + eventData: function(eventEl) { + return { + title: eventEl.innerText.trim() + } + } + }); + + //// the individual way to do it + // var containerEl = document.getElementById('external-events-list'); + // var eventEls = Array.prototype.slice.call( + // containerEl.querySelectorAll('.fc-event') + // ); + // eventEls.forEach(function(eventEl) { + // new Draggable(eventEl, { + // eventData: { + // title: eventEl.innerText.trim(), + // } + // }); + // }); + + /* initialize the calendar + -----------------------------------------------------------------*/ + + var calendarEl = document.getElementById('calendar'); + var calendar = new Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ], + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' + }, + editable: true, + droppable: true, // this allows things to be dropped onto the calendar + drop: function(arg) { + // is the "remove after drop" checkbox checked? + if (document.getElementById('drop-remove').checked) { + // if so, remove the element from the "Draggable Events" list + arg.draggedEl.parentNode.removeChild(arg.draggedEl); + } + } + }); + calendar.render(); + + }); + +</script> +<style> + + body { + margin-top: 40px; + font-size: 14px; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + } + + #wrap { + width: 1100px; + margin: 0 auto; + } + + #external-events { + float: left; + width: 150px; + padding: 0 10px; + border: 1px solid #ccc; + background: #eee; + text-align: left; + } + + #external-events h4 { + font-size: 16px; + margin-top: 0; + padding-top: 1em; + } + + #external-events .fc-event { + margin: 10px 0; + cursor: pointer; + } + + #external-events p { + margin: 1.5em 0; + font-size: 11px; + color: #666; + } + + #external-events p input { + margin: 0; + vertical-align: middle; + } + + #calendar { + float: right; + width: 900px; + } + +</style> +</head> +<body> + <div id='wrap'> + + <div id='external-events'> + <h4>Draggable Events</h4> + + <div id='external-events-list'> + <div class='fc-event'>My Event 1</div> + <div class='fc-event'>My Event 2</div> + <div class='fc-event'>My Event 3</div> + <div class='fc-event'>My Event 4</div> + <div class='fc-event'>My Event 5</div> + </div> + + <p> + <input type='checkbox' id='drop-remove' /> + <label for='drop-remove'>remove after drop</label> + </p> + </div> + + <div id='calendar'></div> + + <div style='clear:both'></div> + + </div> +</body> +</html> diff --git a/library/fullcalendar/demos/full-height.html b/library/fullcalendar/demos/full-height.html new file mode 100644 index 000000000..799622eab --- /dev/null +++ b/library/fullcalendar/demos/full-height.html @@ -0,0 +1,129 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ], + height: 'parent', + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' + }, + defaultView: 'dayGridMonth', + defaultDate: '2019-04-12', + navLinks: true, // can click day/week names to navigate views + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2019-04-01', + }, + { + title: 'Long Event', + start: '2019-04-07', + end: '2019-04-10' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-09T16:00:00' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-16T16:00:00' + }, + { + title: 'Conference', + start: '2019-04-11', + end: '2019-04-13' + }, + { + title: 'Meeting', + start: '2019-04-12T10:30:00', + end: '2019-04-12T12:30:00' + }, + { + title: 'Lunch', + start: '2019-04-12T12:00:00' + }, + { + title: 'Meeting', + start: '2019-04-12T14:30:00' + }, + { + title: 'Happy Hour', + start: '2019-04-12T17:30:00' + }, + { + title: 'Dinner', + start: '2019-04-12T20:00:00' + }, + { + title: 'Birthday Party', + start: '2019-04-13T07:00:00' + }, + { + title: 'Click for Google', + url: 'http://google.com/', + start: '2019-04-28' + } + ] + }); + + calendar.render(); + }); + +</script> +<style> + + html, body { + overflow: hidden; /* don't do scrollbars */ + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #calendar-container { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + } + + .fc-header-toolbar { + /* + the calendar will be butting up against the edges, + but let's scoot in the header's buttons + */ + padding-top: 1em; + padding-left: 1em; + padding-right: 1em; + } + +</style> +</head> +<body> + + <div id='calendar-container'> + <div id='calendar'></div> + </div> + +</body> +</html> diff --git a/library/fullcalendar/demos/google-calendar.html b/library/fullcalendar/demos/google-calendar.html new file mode 100644 index 000000000..96194ac62 --- /dev/null +++ b/library/fullcalendar/demos/google-calendar.html @@ -0,0 +1,86 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script src='../packages/google-calendar/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + + plugins: [ 'interaction', 'dayGrid', 'list', 'googleCalendar' ], + + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,listYear' + }, + + displayEventTime: false, // don't show the time column in list view + + // THIS KEY WON'T WORK IN PRODUCTION!!! + // To make your own Google API key, follow the directions here: + // http://fullcalendar.io/docs/google_calendar/ + googleCalendarApiKey: 'AIzaSyDcnW6WejpTOCffshGDDb4neIrXVUA1EAE', + + // US Holidays + events: 'en.usa#holiday@group.v.calendar.google.com', + + eventClick: function(arg) { + // opens events in a popup window + window.open(arg.event.url, 'google-calendar-event', 'width=700,height=600'); + + arg.jsEvent.preventDefault() // don't navigate in main tab + }, + + loading: function(bool) { + document.getElementById('loading').style.display = + bool ? 'block' : 'none'; + } + + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 40px 10px; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #loading { + display: none; + position: absolute; + top: 10px; + right: 10px; + } + + #calendar { + max-width: 900px; + margin: 0 auto; + } + +</style> +</head> +<body> + + <div id='loading'>loading...</div> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/js/theme-chooser.js b/library/fullcalendar/demos/js/theme-chooser.js new file mode 100644 index 000000000..92a7c4753 --- /dev/null +++ b/library/fullcalendar/demos/js/theme-chooser.js @@ -0,0 +1,141 @@ + +function initThemeChooser(settings) { + var isInitialized = false; + var currentThemeSystem; // don't set this directly. use setThemeSystem + var currentStylesheetEl; + var loadingEl = document.getElementById('loading'); + var systemSelectEl = document.querySelector('#theme-system-selector select'); + var themeSelectWrapEls = Array.prototype.slice.call( // convert to real array + document.querySelectorAll('.selector[data-theme-system]') + ); + + systemSelectEl.addEventListener('change', function() { + setThemeSystem(this.value); + }); + + setThemeSystem(systemSelectEl.value); + + themeSelectWrapEls.forEach(function(themeSelectWrapEl) { + var themeSelectEl = themeSelectWrapEl.querySelector('select'); + + themeSelectWrapEl.addEventListener('change', function() { + setTheme( + currentThemeSystem, + themeSelectEl.options[themeSelectEl.selectedIndex].value + ); + }); + }); + + + function setThemeSystem(themeSystem) { + var selectedTheme; + + currentThemeSystem = themeSystem; + + themeSelectWrapEls.forEach(function(themeSelectWrapEl) { + var themeSelectEl = themeSelectWrapEl.querySelector('select'); + + if (themeSelectWrapEl.getAttribute('data-theme-system') === themeSystem) { + selectedTheme = themeSelectEl.options[themeSelectEl.selectedIndex].value; + themeSelectWrapEl.style.display = 'inline-block'; + } else { + themeSelectWrapEl.style.display = 'none'; + } + }); + + setTheme(themeSystem, selectedTheme); + } + + + function setTheme(themeSystem, themeName) { + var stylesheetUrl = generateStylesheetUrl(themeSystem, themeName); + var stylesheetEl; + + function done() { + if (!isInitialized) { + isInitialized = true; + settings.init(themeSystem); + } + else { + settings.change(themeSystem); + } + + showCredits(themeSystem, themeName); + } + + if (stylesheetUrl) { + stylesheetEl = document.createElement('link'); + stylesheetEl.setAttribute('rel', 'stylesheet'); + stylesheetEl.setAttribute('href', stylesheetUrl); + document.querySelector('head').appendChild(stylesheetEl); + + loadingEl.style.display = 'inline'; + + whenStylesheetLoaded(stylesheetEl, function() { + if (currentStylesheetEl) { + currentStylesheetEl.parentNode.removeChild(currentStylesheetEl); + } + currentStylesheetEl = stylesheetEl; + loadingEl.style.display = 'none'; + done(); + }); + } else { + if (currentStylesheetEl) { + currentStylesheetEl.parentNode.removeChild(currentStylesheetEl); + currentStylesheetEl = null + } + done(); + } + } + + + function generateStylesheetUrl(themeSystem, themeName) { + if (themeSystem === 'bootstrap') { + if (themeName) { + return 'https://bootswatch.com/4/' + themeName + '/bootstrap.min.css'; + } + else { // the default bootstrap theme + return 'https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css'; + } + } + } + + + function showCredits(themeSystem, themeName) { + var creditId; + + if (themeSystem.match('bootstrap')) { + if (themeName) { + creditId = 'bootstrap-custom'; + } + else { + creditId = 'bootstrap-standard'; + } + } + + Array.prototype.slice.call( // convert to real array + document.querySelectorAll('.credits') + ).forEach(function(creditEl) { + if (creditEl.getAttribute('data-credit-id') === creditId) { + creditEl.style.display = 'block'; + } else { + creditEl.style.display = 'none'; + } + }) + } + + + function whenStylesheetLoaded(linkNode, callback) { + var isReady = false; + + function ready() { + if (!isReady) { // avoid double-call + isReady = true; + callback(); + } + } + + linkNode.onload = ready; // does not work cross-browser + setTimeout(ready, 2000); // max wait. also handles browsers that don't support onload + } +} diff --git a/library/fullcalendar/demos/json.html b/library/fullcalendar/demos/json.html new file mode 100644 index 000000000..a107361b0 --- /dev/null +++ b/library/fullcalendar/demos/json.html @@ -0,0 +1,93 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ], + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' + }, + defaultDate: '2019-04-12', + editable: true, + navLinks: true, // can click day/week names to navigate views + eventLimit: true, // allow "more" link when too many events + events: { + url: 'php/get-events.php', + failure: function() { + document.getElementById('script-warning').style.display = 'block' + } + }, + loading: function(bool) { + document.getElementById('loading').style.display = + bool ? 'block' : 'none'; + } + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 0; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #script-warning { + display: none; + background: #eee; + border-bottom: 1px solid #ddd; + padding: 0 10px; + line-height: 40px; + text-align: center; + font-weight: bold; + font-size: 12px; + color: red; + } + + #loading { + display: none; + position: absolute; + top: 10px; + right: 10px; + } + + #calendar { + max-width: 900px; + margin: 40px auto; + padding: 0 10px; + } + +</style> +</head> +<body> + + <div id='script-warning'> + <code>php/get-events.php</code> must be running. + </div> + + <div id='loading'>loading...</div> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/json/events.json b/library/fullcalendar/demos/json/events.json new file mode 100644 index 000000000..466f837ed --- /dev/null +++ b/library/fullcalendar/demos/json/events.json @@ -0,0 +1,56 @@ +[ + { + "title": "All Day Event", + "start": "2019-04-01" + }, + { + "title": "Long Event", + "start": "2019-04-07", + "end": "2019-04-10" + }, + { + "id": "999", + "title": "Repeating Event", + "start": "2019-04-09T16:00:00-05:00" + }, + { + "id": "999", + "title": "Repeating Event", + "start": "2019-04-16T16:00:00-05:00" + }, + { + "title": "Conference", + "start": "2019-04-11", + "end": "2019-04-13" + }, + { + "title": "Meeting", + "start": "2019-04-12T10:30:00-05:00", + "end": "2019-04-12T12:30:00-05:00" + }, + { + "title": "Lunch", + "start": "2019-04-12T12:00:00-05:00" + }, + { + "title": "Meeting", + "start": "2019-04-12T14:30:00-05:00" + }, + { + "title": "Happy Hour", + "start": "2019-04-12T17:30:00-05:00" + }, + { + "title": "Dinner", + "start": "2019-04-12T20:00:00" + }, + { + "title": "Birthday Party", + "start": "2019-04-13T07:00:00-05:00" + }, + { + "title": "Click for Google", + "url": "http://google.com/", + "start": "2019-04-28" + } +] diff --git a/library/fullcalendar/demos/list-views.html b/library/fullcalendar/demos/list-views.html new file mode 100644 index 000000000..744c08494 --- /dev/null +++ b/library/fullcalendar/demos/list-views.html @@ -0,0 +1,118 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/list/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'list' ], + + header: { + left: 'prev,next today', + center: 'title', + right: 'listDay,listWeek,dayGridMonth' + }, + + // customize the button names, + // otherwise they'd all just say "list" + views: { + listDay: { buttonText: 'list day' }, + listWeek: { buttonText: 'list week' } + }, + + defaultView: 'listWeek', + defaultDate: '2019-04-12', + navLinks: true, // can click day/week names to navigate views + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2019-04-01' + }, + { + title: 'Long Event', + start: '2019-04-07', + end: '2019-04-10' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-09T16:00:00' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-16T16:00:00' + }, + { + title: 'Conference', + start: '2019-04-11', + end: '2019-04-13' + }, + { + title: 'Meeting', + start: '2019-04-12T10:30:00', + end: '2019-04-12T12:30:00' + }, + { + title: 'Lunch', + start: '2019-04-12T12:00:00' + }, + { + title: 'Meeting', + start: '2019-04-12T14:30:00' + }, + { + title: 'Happy Hour', + start: '2019-04-12T17:30:00' + }, + { + title: 'Dinner', + start: '2019-04-12T20:00:00' + }, + { + title: 'Birthday Party', + start: '2019-04-13T07:00:00' + }, + { + title: 'Click for Google', + url: 'http://google.com/', + start: '2019-04-28' + } + ] + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 40px 10px; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #calendar { + max-width: 900px; + margin: 0 auto; + } + +</style> +</head> +<body> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/locales.html b/library/fullcalendar/demos/locales.html new file mode 100644 index 000000000..9e94b4b62 --- /dev/null +++ b/library/fullcalendar/demos/locales.html @@ -0,0 +1,152 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/core/locales-all.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var initialLocaleCode = 'en'; + var localeSelectorEl = document.getElementById('locale-selector'); + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ], + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth' + }, + defaultDate: '2019-04-12', + locale: initialLocaleCode, + buttonIcons: false, // show the prev/next text + weekNumbers: true, + navLinks: true, // can click day/week names to navigate views + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2019-04-01' + }, + { + title: 'Long Event', + start: '2019-04-07', + end: '2019-04-10' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-09T16:00:00' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-16T16:00:00' + }, + { + title: 'Conference', + start: '2019-04-11', + end: '2019-04-13' + }, + { + title: 'Meeting', + start: '2019-04-12T10:30:00', + end: '2019-04-12T12:30:00' + }, + { + title: 'Lunch', + start: '2019-04-12T12:00:00' + }, + { + title: 'Meeting', + start: '2019-04-12T14:30:00' + }, + { + title: 'Happy Hour', + start: '2019-04-12T17:30:00' + }, + { + title: 'Dinner', + start: '2019-04-12T20:00:00' + }, + { + title: 'Birthday Party', + start: '2019-04-13T07:00:00' + }, + { + title: 'Click for Google', + url: 'http://google.com/', + start: '2019-04-28' + } + ] + }); + + calendar.render(); + + // build the locale selector's options + calendar.getAvailableLocaleCodes().forEach(function(localeCode) { + var optionEl = document.createElement('option'); + optionEl.value = localeCode; + optionEl.selected = localeCode == initialLocaleCode; + optionEl.innerText = localeCode; + localeSelectorEl.appendChild(optionEl); + }); + + // when the selected option changes, dynamically change the calendar option + localeSelectorEl.addEventListener('change', function() { + if (this.value) { + calendar.setOption('locale', this.value); + } + }); + + }); + +</script> +<style> + + body { + margin: 0; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #top { + background: #eee; + border-bottom: 1px solid #ddd; + padding: 0 10px; + line-height: 40px; + font-size: 12px; + } + + #calendar { + max-width: 900px; + margin: 40px auto; + padding: 0 10px; + } + +</style> +</head> +<body> + + <div id='top'> + + Locales: + <select id='locale-selector'></select> + + </div> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/php/get-events.php b/library/fullcalendar/demos/php/get-events.php new file mode 100644 index 000000000..888201557 --- /dev/null +++ b/library/fullcalendar/demos/php/get-events.php @@ -0,0 +1,50 @@ +<?php + +//-------------------------------------------------------------------------------------------------- +// This script reads event data from a JSON file and outputs those events which are within the range +// supplied by the "start" and "end" GET parameters. +// +// An optional "timeZone" GET parameter will force all ISO8601 date stings to a given timeZone. +// +// Requires PHP 5.2.0 or higher. +//-------------------------------------------------------------------------------------------------- + +// Require our Event class and datetime utilities +require dirname(__FILE__) . '/utils.php'; + +// Short-circuit if the client did not give us a date range. +if (!isset($_GET['start']) || !isset($_GET['end'])) { + die("Please provide a date range."); +} + +// Parse the start/end parameters. +// These are assumed to be ISO8601 strings with no time nor timeZone, like "2013-12-29". +// Since no timeZone will be present, they will parsed as UTC. +$range_start = parseDateTime($_GET['start']); +$range_end = parseDateTime($_GET['end']); + +// Parse the timeZone parameter if it is present. +$timeZone = null; +if (isset($_GET['timeZone'])) { + $timeZone = new DateTimeZone($_GET['timeZone']); +} + +// Read and parse our events JSON file into an array of event data arrays. +$json = file_get_contents(dirname(__FILE__) . '/../json/events.json'); +$input_arrays = json_decode($json, true); + +// Accumulate an output array of event data arrays. +$output_arrays = array(); +foreach ($input_arrays as $array) { + + // Convert the input array into a useful Event object + $event = new Event($array, $timeZone); + + // If the event is in-bounds, add it to the output + if ($event->isWithinDayRange($range_start, $range_end)) { + $output_arrays[] = $event->toArray(); + } +} + +// Send JSON to the client. +echo json_encode($output_arrays); diff --git a/library/fullcalendar/demos/php/get-time-zones.php b/library/fullcalendar/demos/php/get-time-zones.php new file mode 100644 index 000000000..241e1bd18 --- /dev/null +++ b/library/fullcalendar/demos/php/get-time-zones.php @@ -0,0 +1,9 @@ +<?php + +//-------------------------------------------------------------------------------------------------- +// This script outputs a JSON array of all timezones (like "America/Chicago") that PHP supports. +// +// Requires PHP 5.2.0 or higher. +//-------------------------------------------------------------------------------------------------- + +echo json_encode(DateTimeZone::listIdentifiers());
\ No newline at end of file diff --git a/library/fullcalendar/demos/php/utils.php b/library/fullcalendar/demos/php/utils.php new file mode 100644 index 000000000..aa67cda75 --- /dev/null +++ b/library/fullcalendar/demos/php/utils.php @@ -0,0 +1,130 @@ +<?php + +//-------------------------------------------------------------------------------------------------- +// Utilities for our event-fetching scripts. +// +// Requires PHP 5.2.0 or higher. +//-------------------------------------------------------------------------------------------------- + +// PHP will fatal error if we attempt to use the DateTime class without this being set. +date_default_timezone_set('UTC'); + + +class Event { + + // Tests whether the given ISO8601 string has a time-of-day or not + const ALL_DAY_REGEX = '/^\d{4}-\d\d-\d\d$/'; // matches strings like "2013-12-29" + + public $title; + public $allDay; // a boolean + public $start; // a DateTime + public $end; // a DateTime, or null + public $properties = array(); // an array of other misc properties + + + // Constructs an Event object from the given array of key=>values. + // You can optionally force the timeZone of the parsed dates. + public function __construct($array, $timeZone=null) { + + $this->title = $array['title']; + + if (isset($array['allDay'])) { + // allDay has been explicitly specified + $this->allDay = (bool)$array['allDay']; + } + else { + // Guess allDay based off of ISO8601 date strings + $this->allDay = preg_match(self::ALL_DAY_REGEX, $array['start']) && + (!isset($array['end']) || preg_match(self::ALL_DAY_REGEX, $array['end'])); + } + + if ($this->allDay) { + // If dates are allDay, we want to parse them in UTC to avoid DST issues. + $timeZone = null; + } + + // Parse dates + $this->start = parseDateTime($array['start'], $timeZone); + $this->end = isset($array['end']) ? parseDateTime($array['end'], $timeZone) : null; + + // Record misc properties + foreach ($array as $name => $value) { + if (!in_array($name, array('title', 'allDay', 'start', 'end'))) { + $this->properties[$name] = $value; + } + } + } + + + // Returns whether the date range of our event intersects with the given all-day range. + // $rangeStart and $rangeEnd are assumed to be dates in UTC with 00:00:00 time. + public function isWithinDayRange($rangeStart, $rangeEnd) { + + // Normalize our event's dates for comparison with the all-day range. + $eventStart = stripTime($this->start); + + if (isset($this->end)) { + $eventEnd = stripTime($this->end); // normalize + } + else { + $eventEnd = $eventStart; // consider this a zero-duration event + } + + // Check if the two whole-day ranges intersect. + return $eventStart < $rangeEnd && $eventEnd >= $rangeStart; + } + + + // Converts this Event object back to a plain data array, to be used for generating JSON + public function toArray() { + + // Start with the misc properties (don't worry, PHP won't affect the original array) + $array = $this->properties; + + $array['title'] = $this->title; + + // Figure out the date format. This essentially encodes allDay into the date string. + if ($this->allDay) { + $format = 'Y-m-d'; // output like "2013-12-29" + } + else { + $format = 'c'; // full ISO8601 output, like "2013-12-29T09:00:00+08:00" + } + + // Serialize dates into strings + $array['start'] = $this->start->format($format); + if (isset($this->end)) { + $array['end'] = $this->end->format($format); + } + + return $array; + } + +} + + +// Date Utilities +//---------------------------------------------------------------------------------------------- + + +// Parses a string into a DateTime object, optionally forced into the given timeZone. +function parseDateTime($string, $timeZone=null) { + $date = new DateTime( + $string, + $timeZone ? $timeZone : new DateTimeZone('UTC') + // Used only when the string is ambiguous. + // Ignored if string has a timeZone offset in it. + ); + if ($timeZone) { + // If our timeZone was ignored above, force it. + $date->setTimezone($timeZone); + } + return $date; +} + + +// Takes the year/month/date values of the given DateTime and converts them to a new DateTime, +// but in UTC. +function stripTime($datetime) { + return new DateTime($datetime->format('Y-m-d')); +} diff --git a/library/fullcalendar/demos/rrule.html b/library/fullcalendar/demos/rrule.html new file mode 100644 index 000000000..d98234242 --- /dev/null +++ b/library/fullcalendar/demos/rrule.html @@ -0,0 +1,73 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../vendor/rrule.js'></script> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script src='../packages/rrule/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list', 'rrule' ], + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth' + }, + defaultDate: '2019-04-12', + editable: true, + events: [ + { + title: 'rrule event', + rrule: { + dtstart: '2019-04-09T13:00:00', + // until: '2019-04-01', + freq: 'weekly' + }, + duration: '02:00' + } + ], + eventClick: function(arg) { + if (confirm('delete event?')) { + arg.event.remove() + } + } + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 40px 10px; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #calendar { + max-width: 900px; + margin: 0 auto; + } + +</style> +</head> +<body> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/selectable.html b/library/fullcalendar/demos/selectable.html new file mode 100644 index 000000000..3b0f84871 --- /dev/null +++ b/library/fullcalendar/demos/selectable.html @@ -0,0 +1,125 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid', 'timeGrid' ], + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay' + }, + defaultDate: '2019-04-12', + navLinks: true, // can click day/week names to navigate views + selectable: true, + selectMirror: true, + select: function(arg) { + var title = prompt('Event Title:'); + if (title) { + calendar.addEvent({ + title: title, + start: arg.start, + end: arg.end, + allDay: arg.allDay + }) + } + calendar.unselect() + }, + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2019-04-01' + }, + { + title: 'Long Event', + start: '2019-04-07', + end: '2019-04-10' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-09T16:00:00' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-16T16:00:00' + }, + { + title: 'Conference', + start: '2019-04-11', + end: '2019-04-13' + }, + { + title: 'Meeting', + start: '2019-04-12T10:30:00', + end: '2019-04-12T12:30:00' + }, + { + title: 'Lunch', + start: '2019-04-12T12:00:00' + }, + { + title: 'Meeting', + start: '2019-04-12T14:30:00' + }, + { + title: 'Happy Hour', + start: '2019-04-12T17:30:00' + }, + { + title: 'Dinner', + start: '2019-04-12T20:00:00' + }, + { + title: 'Birthday Party', + start: '2019-04-13T07:00:00' + }, + { + title: 'Click for Google', + url: 'http://google.com/', + start: '2019-04-28' + } + ] + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 40px 10px; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #calendar { + max-width: 900px; + margin: 0 auto; + } + +</style> +</head> +<body> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/themes.html b/library/fullcalendar/demos/themes.html new file mode 100644 index 000000000..0f34ad04b --- /dev/null +++ b/library/fullcalendar/demos/themes.html @@ -0,0 +1,215 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='https://use.fontawesome.com/releases/v5.0.6/css/all.css' rel='stylesheet'> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/bootstrap/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/bootstrap/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script src='js/theme-chooser.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + var calendar; + + initThemeChooser({ + + init: function(themeSystem) { + calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'bootstrap', 'interaction', 'dayGrid', 'timeGrid', 'list' ], + themeSystem: themeSystem, + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth' + }, + defaultDate: '2019-04-12', + weekNumbers: true, + navLinks: true, // can click day/week names to navigate views + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2019-04-01' + }, + { + title: 'Long Event', + start: '2019-04-07', + end: '2019-04-10' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-09T16:00:00' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-16T16:00:00' + }, + { + title: 'Conference', + start: '2019-04-11', + end: '2019-04-13' + }, + { + title: 'Meeting', + start: '2019-04-12T10:30:00', + end: '2019-04-12T12:30:00' + }, + { + title: 'Lunch', + start: '2019-04-12T12:00:00' + }, + { + title: 'Meeting', + start: '2019-04-12T14:30:00' + }, + { + title: 'Happy Hour', + start: '2019-04-12T17:30:00' + }, + { + title: 'Dinner', + start: '2019-04-12T20:00:00' + }, + { + title: 'Birthday Party', + start: '2019-04-13T07:00:00' + }, + { + title: 'Click for Google', + url: 'http://google.com/', + start: '2019-04-28' + } + ] + }); + calendar.render(); + }, + + change: function(themeSystem) { + calendar.setOption('themeSystem', themeSystem); + } + + }); + + }); + +</script> +<style> + + body { + margin: 0; + padding: 0; + font-size: 14px; + } + + #top, + #calendar.fc-unthemed { + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + } + + #top { + background: #eee; + border-bottom: 1px solid #ddd; + padding: 0 10px; + line-height: 40px; + font-size: 12px; + color: #000; + } + + #top .selector { + display: inline-block; + margin-right: 10px; + } + + #top select { + font: inherit; /* mock what Boostrap does, don't compete */ + } + + .left { float: left } + .right { float: right } + .clear { clear: both } + + #calendar { + max-width: 900px; + margin: 40px auto; + padding: 0 10px; + } + +</style> +</head> +<body> + + <div id='top'> + + <div class='left'> + + <div id='theme-system-selector' class='selector'> + Theme System: + + <select> + <option value='bootstrap' selected>Bootstrap 4</option> + <option value='standard'>unthemed</option> + </select> + </div> + + <div data-theme-system="bootstrap" class='selector' style='display:none'> + Theme Name: + + <select> + <option value='' selected>Default</option> + <option value='cerulean'>Cerulean</option> + <option value='cosmo'>Cosmo</option> + <option value='cyborg'>Cyborg</option> + <option value='darkly'>Darkly</option> + <option value='flatly'>Flatly</option> + <option value='journal'>Journal</option> + <option value='litera'>Litera</option> + <option value='lumen'>Lumen</option> + <option value='lux'>Lux</option> + <option value='materia'>Materia</option> + <option value='minty'>Minty</option> + <option value='pulse'>Pulse</option> + <option value='sandstone'>Sandstone</option> + <option value='simplex'>Simplex</option> + <option value='sketchy'>Sketchy</option> + <option value='slate'>Slate</option> + <option value='solar'>Solar</option> + <option value='spacelab'>Spacelab</option> + <option value='superhero'>Superhero</option> + <option value='united'>United</option> + <option value='yeti'>Yeti</option> + </select> + </div> + + <span id='loading' style='display:none'>loading theme...</span> + + </div> + + <div class='right'> + <span class='credits' data-credit-id='bootstrap-standard' style='display:none'> + <a href='https://getbootstrap.com/docs/3.3/' target='_blank'>Theme by Bootstrap</a> + </span> + <span class='credits' data-credit-id='bootstrap-custom' style='display:none'> + <a href='https://bootswatch.com/' target='_blank'>Theme by Bootswatch</a> + </span> + </div> + + <div class='clear'></div> + </div> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/time-zones.html b/library/fullcalendar/demos/time-zones.html new file mode 100644 index 000000000..5330fea9b --- /dev/null +++ b/library/fullcalendar/demos/time-zones.html @@ -0,0 +1,145 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var initialTimeZone = 'local'; + var timeZoneSelectorEl = document.getElementById('time-zone-selector'); + var loadingEl = document.getElementById('loading'); + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ], + timeZone: initialTimeZone, + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' + }, + defaultDate: '2019-04-12', + navLinks: true, // can click day/week names to navigate views + editable: true, + selectable: true, + eventLimit: true, // allow "more" link when too many events + events: { + url: 'php/get-events.php', + failure: function() { + document.getElementById('script-warning').style.display = 'inline'; // show + } + }, + loading: function(bool) { + if (bool) { + loadingEl.style.display = 'inline'; // show + } else { + loadingEl.style.display = 'none'; // hide + } + }, + + eventTimeFormat: { hour: 'numeric', minute: '2-digit', timeZoneName: 'short' }, + + dateClick: function(arg) { + console.log('dateClick', calendar.formatIso(arg.date)); + }, + select: function(arg) { + console.log('select', calendar.formatIso(arg.start), calendar.formatIso(arg.end)); + } + }); + + calendar.render(); + + // load the list of available timezones, build the <select> options + // it's HIGHLY recommended to use a different library for network requests, not this internal util func + FullCalendar.requestJson('GET', 'php/get-time-zones.php', {}, function(timeZones) { + + timeZones.forEach(function(timeZone) { + var optionEl; + + if (timeZone !== 'UTC') { // UTC is already in the list + optionEl = document.createElement('option'); + optionEl.value = timeZone; + optionEl.innerText = timeZone; + timeZoneSelectorEl.appendChild(optionEl); + } + }); + }, function() { + // TODO: handle error + }); + + // when the timezone selector changes, dynamically change the calendar option + timeZoneSelectorEl.addEventListener('change', function() { + calendar.setOption('timeZone', this.value); + }); + }); + +</script> +<style> + + body { + margin: 0; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #top { + background: #eee; + border-bottom: 1px solid #ddd; + padding: 0 10px; + line-height: 40px; + font-size: 12px; + } + .left { float: left } + .right { float: right } + .clear { clear: both } + + #script-warning, #loading { display: none } + #script-warning { font-weight: bold; color: red } + + #calendar { + max-width: 900px; + margin: 40px auto; + padding: 0 10px; + } + + .tzo { + color: #000; + } + +</style> +</head> +<body> + + <div id='top'> + + <div class='left'> + Timezone: + <select id='time-zone-selector'> + <option value='local' selected>local</option> + <option value='UTC'>UTC</option> + </select> + </div> + + <div class='right'> + <span id='loading'>loading...</span> + <span id='script-warning'><code>php/get-events.php</code> must be running.</span> + </div> + + <div class='clear'></div> + + </div> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/timegrid-views.html b/library/fullcalendar/demos/timegrid-views.html new file mode 100644 index 000000000..584991043 --- /dev/null +++ b/library/fullcalendar/demos/timegrid-views.html @@ -0,0 +1,113 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'dayGrid', 'timeGrid', 'list', 'interaction' ], + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' + }, + defaultDate: '2019-04-12', + navLinks: true, // can click day/week names to navigate views + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2019-04-01', + }, + { + title: 'Long Event', + start: '2019-04-07', + end: '2019-04-10' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-09T16:00:00' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-16T16:00:00' + }, + { + title: 'Conference', + start: '2019-04-11', + end: '2019-04-13' + }, + { + title: 'Meeting', + start: '2019-04-12T10:30:00', + end: '2019-04-12T12:30:00' + }, + { + title: 'Lunch', + start: '2019-04-12T12:00:00' + }, + { + title: 'Meeting', + start: '2019-04-12T14:30:00' + }, + { + title: 'Happy Hour', + start: '2019-04-12T17:30:00' + }, + { + title: 'Dinner', + start: '2019-04-12T20:00:00' + }, + { + title: 'Birthday Party', + start: '2019-04-13T07:00:00' + }, + { + title: 'Click for Google', + url: 'http://google.com/', + start: '2019-04-28' + } + ] + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 40px 10px; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #calendar { + max-width: 900px; + margin: 0 auto; + } + +</style> +</head> +<body> + + <div id='calendar'></div> + +</body> +</html> diff --git a/library/fullcalendar/demos/week-numbers.html b/library/fullcalendar/demos/week-numbers.html new file mode 100644 index 000000000..5ad5c4b1e --- /dev/null +++ b/library/fullcalendar/demos/week-numbers.html @@ -0,0 +1,118 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset='utf-8' /> +<link href='../packages/core/main.css' rel='stylesheet' /> +<link href='../packages/daygrid/main.css' rel='stylesheet' /> +<link href='../packages/timegrid/main.css' rel='stylesheet' /> +<link href='../packages/list/main.css' rel='stylesheet' /> +<script src='../packages/core/main.js'></script> +<script src='../packages/interaction/main.js'></script> +<script src='../packages/daygrid/main.js'></script> +<script src='../packages/timegrid/main.js'></script> +<script src='../packages/list/main.js'></script> +<script> + + document.addEventListener('DOMContentLoaded', function() { + var calendarEl = document.getElementById('calendar'); + + var calendar = new FullCalendar.Calendar(calendarEl, { + plugins: [ 'interaction', 'dayGrid', 'timeGrid', 'list' ], + header: { + left: 'prev,next today', + center: 'title', + right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek' + }, + defaultDate: '2019-04-12', + navLinks: true, // can click day/week names to navigate views + + weekNumbers: true, + weekNumbersWithinDays: true, + weekNumberCalculation: 'ISO', + + editable: true, + eventLimit: true, // allow "more" link when too many events + events: [ + { + title: 'All Day Event', + start: '2019-04-01' + }, + { + title: 'Long Event', + start: '2019-04-07', + end: '2019-04-10' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-09T16:00:00' + }, + { + groupId: 999, + title: 'Repeating Event', + start: '2019-04-16T16:00:00' + }, + { + title: 'Conference', + start: '2019-04-11', + end: '2019-04-13' + }, + { + title: 'Meeting', + start: '2019-04-12T10:30:00', + end: '2019-04-12T12:30:00' + }, + { + title: 'Lunch', + start: '2019-04-12T12:00:00' + }, + { + title: 'Meeting', + start: '2019-04-12T14:30:00' + }, + { + title: 'Happy Hour', + start: '2019-04-12T17:30:00' + }, + { + title: 'Dinner', + start: '2019-04-12T20:00:00' + }, + { + title: 'Birthday Party', + start: '2019-04-13T07:00:00' + }, + { + title: 'Click for Google', + url: 'http://google.com/', + start: '2019-04-28' + } + ] + }); + + calendar.render(); + }); + +</script> +<style> + + body { + margin: 40px 10px; + padding: 0; + font-family: Arial, Helvetica Neue, Helvetica, sans-serif; + font-size: 14px; + } + + #calendar { + max-width: 900px; + margin: 0 auto; + } + +</style> +</head> +<body> + + <div id='calendar'></div> + +</body> +</html> |