BlogProgramming

Fullcalendar v5: Implementation Example

This is an example of an implementation of Fullcalendar v5 using the simplest way to get started, with Fullcalendar’s pre-built bundles and script tags. Will try to comment the code as much as I can. Nevertheless, most of the elements are available in the documentation.

This example is based on two PHP files, one for a form filter plus the calendar itself, and the second one for the getting the data for the calendar.

Note that I will be using in this example:

Main PHP file with the calendar.

<link rel='stylesheet' type='text/css' href='/route_to/fullcalendar.5.10.0/main.css'/>
<script src="/route_to/fullcalendar.5.10.0/main.min.js" type="text/javascript"></script>
<script src="/route_to/fullcalendar.5.10.0/locales/pt.js" type="text/javascript"></script>
	
<form class="form" name='form_calendario' id='form_calendario'>
<!-- form elements, no need to exemplify this part -->
</form>

<!-- div placeholder for the calendar -->
<div id='calendario'></div>

The javascript part:

<script type='text/javascript'>
	// some variables iniciation
	var $form_filter   = $("#form_calendario");
	var $filtros       = "form_calendariov2";
	var $filter_cookie = Cookies.get($filtros);
	var $formIDs       = [];
	var $locBase       = "<?=LOC_BASE?>";
	var elFiltro        = $("#filtro");
	var elDepartamentos = $("#id_departamento");
	var elUtilizadores  = $("#id_utilizador");

	// check if that Cookies are set or not for the filter form inputs
	// if they are set, fill out the fields with the data stored
	if (!($filter_cookie === 'null' || $filter_cookie === undefined || $filter_cookie === null)) {
		var fields = JSON.parse($filter_cookie);

		for (var i = 0; i < fields.length; i++) {
			var controlName  = fields[i].name;
			var controlValue = fields[i].value;
			var tipo         = $("#" + controlName).prop("type");

			if (tipo === 'select-multiple') {
				$("#" + controlName + " option[value=" + controlValue + "]").attr('selected', true);
			}
			else {
				$("#" + controlName).val(controlValue);
			}
		}

		filtro        = elFiltro.val();
		departamentos = elDepartamentos.val();
		utilizadores  = elUtilizadores.val();
	}

	// calendar initiation
	document.addEventListener('DOMContentLoaded', function () {
		var calendarEl    = document.getElementById('calendario');
		filtro        = elFiltro.val();
		departamentos = elDepartamentos.val();
		utilizadores  = elUtilizadores.val();

		var calendar = new FullCalendar.Calendar(calendarEl, {
			headerToolbar: {
				left  : 'prev,next today',
				center: 'title',
				right : 'dayGridMonth,timeGridWeek,timeGridDay,listWeek,myRefresh'
			},
			navLinks     : true, // can click day/week names to navigate views
			nowIndicator : true,

			initialView          : 'timeGridWeek',
			weekNumbers          : true,
			weekNumberCalculation: 'ISO',

			locale      : 'pt',
			editable    : true,
			selectable  : true,
			dayMaxEvents: true, // allow "more" link when too many events

			slotMinTime: '07:00:00',
			slotMaxTime: '22:00:00',

			businessHours: [
				{
					// days of week. an array of zero-based day of week integers (0=Sunday)
					daysOfWeek: [1, 2, 3, 4, 5], // Monday - Friday

					startTime: '09:00', // a start time (10am in this example)
					endTime  : '13:00', // an end time (6pm in this example)
				},
				{
					daysOfWeek: [1, 2, 3, 4, 5],

					startTime: '14:30',
					endTime  : '18:30',
				},
				{
					daysOfWeek: [6],

					startTime: '10:00',
					endTime  : '13:00',
				},

			],

			aspectRatio: 2.25,
			expandRows: true,

			events: {
				
				// events will be loaded from a file with queries
				// data returned das JSON
				url        : $locBase + "estatisticas/calendario_carrega_eventos.php",
				
				// extra parameters that will be sent with the file requested above
				// extra parameters are needed to be able to filter out results
				// using the form information imputed above
				extraParams: function () {
					var filtro        = elFiltro.val();
					var departamentos = elDepartamentos.val();
					var utilizadores  = elUtilizadores.val();

					return {
						filtro       : filtro,
						departamentos: departamentos,
						utilizadores : utilizadores
					}
				},
				failure    : function () {
					document.getElementById('script-warning').style.display = 'block'
				}
			},

			// eventDidMount - called right after the element has been added to the DOM.
			// will need this since we want to add an icon after the time lables
			eventDidMount: function (event) {
				let $reagendamento = event.event.extendedProps.reagendamento;
				let $tipoAccao     = event.event.extendedProps.tipo_accao;
				let $icon          = event.event.extendedProps.icon;
				let $start         = event.event.extendedProps.startTime;
				let $end           = event.event.extendedProps.endTime;
				let $title         = event.event._def.title;
				let $timeText      = event.timeText;
				let $viewType      = event.view.type;
				let $html          = "";

				if ($icon) {
					if ($viewType === 'timeGridWeek') {
						let elemento = $(event.el).find('.fc-event-time');
						// console.log("elemento", elemento);

						$html = " <i class='" + $icon + "'></i> ";
						elemento.append($html);
					}

					if ($viewType === 'listWeek') {
						let elemento = $(event.el).find('.fc-list-event-time');
						// console.log("elemento", elemento);

						$html = " <i class='" + $icon + "'></i> ";
						elemento.append($html);
						
					}
				}

			},

			// This is triggered when the user clicks an event.
			eventClick: function (info) {
				// don't let the browser navigate just yet
				info.jsEvent.preventDefault();

				let $URL = info.event.url;
				// info.el.style.borderColor = 'yellow';

				if (info.event.url) {
					window.open($URL, '_blank');
				}

			},

			// This is triggered when the user clicks on a date or a time.
			dateClick: function (info) {
				window.open("?mostra=crm_actividades", '_blank');
			},

			// This is triggered when dragging stops and the event has moved to a different day/time.
			eventDrop: function (info) {
				let StartDate     = moment(info.event.start).format('YYYY-MM-DD')
				let StartTime     = moment(info.event.start).format('HH:mm');
				let EndDate       = moment(info.event.end).format('YYYY-MM-DD')
				let EndTime       = moment(info.event.end).format('HH:mm');
				let TodoDia       = info.event.allDay;
				let RecordID      = info.event.id;
				let Reagendamento = info.event.extendedProps.reagendamento;
				let OrigemLnk     = info.event.extendedProps.origem_lnk;

				if (Reagendamento === 'nao_permite_reagendamento') {
					info.revert();
				}

				// save changes made to the event made by dragging
				$.ajax({
					url     : $locBase + 'estatisticas/calendario_grava_eventos.php',
					dataType: 'json',
					data    : {
						StartDate    : StartDate,
						StartTime    : StartTime,
						EndDate      : EndDate,
						EndTime      : EndTime,
						TodoDia      : TodoDia,
						RecordID     : RecordID,
						Origem       : OrigemLnk,
						Reagendamento: Reagendamento,
						Task         : 'drag'
					},
					success : function () {
					}
				});
			},

			// This will be triggered when resizing stops and the event has changed in duration.
			eventResize: function (info) {
				let StartDate     = moment(info.event.start).format('YYYY-MM-DD')
				let StartTime     = moment(info.event.start).format('HH:mm');
				let EndDate       = moment(info.event.end).format('YYYY-MM-DD')
				let EndTime       = moment(info.event.end).format('HH:mm');
				let TodoDia       = info.event.allDay;
				let RecordID      = info.event.id;
				let Reagendamento = info.event.extendedProps.reagendamento;
				let OrigemLnk     = info.event.extendedProps.origem_lnk;

				if (Reagendamento === 'nao_permite_reagendamento') {
					info.revert();
				}

				// save changes made to the event made by resizing
				$.ajax({
					url     : $locBase + 'estatisticas/calendario_grava_eventos.php',
					dataType: 'json',
					data    : {
						StartDate    : StartDate,
						StartTime    : StartTime,
						EndDate      : EndDate,
						EndTime      : EndTime,
						TodoDia      : TodoDia,
						RecordID     : RecordID,
						Origem       : OrigemLnk,
						Reagendamento: Reagendamento,
						Task         : 'size'
					},
					success : function () {
					}
				});
			},

			// A custom button to force refresh the calendar, since calendar events
			// are beeing added/changed all the time by other team members
			customButtons: {
				myRefresh: {
					text: 'Refresh',
					click: function() {
						calendar.refetchEvents();
					}
				}
			},

		});
		calendar.render();

		elFiltro.change(function (e) {
			guardaCookie();
			calendar.refetchEvents();
		});

		elDepartamentos.select2().change(function () {
			guardaCookie();
			calendar.refetchEvents();
		});

		elUtilizadores.select2().change(function () {
			guardaCookie();
			calendar.refetchEvents();
		});

	});

	function guardaCookie() {
		if (elUtilizadores.length <= 0) {
			elUtilizadores.val('0');
		}
		Cookies.set($filtros, JSON.stringify($form_filter.serializeArray()), {
			path   : '/',
			expires: 1
		});
	}

	function getFormData() { // GET ALL SELECT IDS //
		$form_filter.find("input, select").each(function () { $formIDs.push(this.id); });
		$form_data = {};

		$.each($formIDs, function (index, value) {
			$form_data[value] = $("#" + value, $form_filter).val();
		});
		// console.log($formIDs, $form_data);
		return $form_data
	}

</script>

Any questions? Please leave them in the comments.

Artigos Relacionados

Deixe um comentário

O seu endereço de email não será publicado. Campos obrigatórios marcados com *

Este site utiliza o Akismet para reduzir spam. Fica a saber como são processados os dados dos comentários.

Botão Voltar ao Topo
João Clérigo - Photography
Fechar

AdBlocker Detetado
AdBlocker Detected

Por favor ajude este website permitindo a visualização de alguns anúncios. Obrigado. Please help this website allowing the view of some advertising. Thank you!