Das Human Resource Management (HRM) profitiert maßgeblich von Systemen, die Transparenz und Übersichtlichkeit fördern. OrangeHRM, eine beliebte Open-Source-Software zur Personalverwaltung, ist ideal für Unternehmen, die ihre HR-Prozesse optimieren möchten. Mit einer zusätzlichen Kalenderfunktion, basierend auf der FullCalendar-Bibliothek, können Abwesenheiten wie Urlaub und Krankmeldungen effektiv visualisiert werden. Dieser Artikel zeigt, wie man den Kalender für OrangeHRM Starter integriert und nutzt, um die Abwesenheiten der Mitarbeitenden darzustellen.
Warum einen Kalender für OrangeHRM nutzen?
OrangeHRM bietet bereits viele Funktionen zur Verwaltung von Personalinformationen und Abwesenheiten. Ein Kalender ist jedoch eine visuelle Ergänzung, die auf einen Blick die Verfügbarkeit des Teams zeigt. Diese Darstellung hilft Personalabteilungen und Management, Engpässe zu vermeiden und den Workflow zu optimieren.
Die FullCalendar-Bibliothek: Einführung
Die FullCalendar-Bibliothek ist ein vielseitiges JavaScript-Plugin, das sich perfekt für die Implementierung eines interaktiven Kalenders eignet. Sie ist einfach zu integrieren und bietet zahlreiche Anpassungsmöglichkeiten. Durch die Nutzung der Datei https://cdn.jsdelivr.net/npm/fullcalendar/index.global.js
können Nutzer einen flexiblen und anpassbaren Kalender in ihre Webanwendungen einbetten.
Hauptvorteile von FullCalendar
- Einfach zu implementieren: Der Code kann problemlos in bestehende Systeme eingefügt werden.
- Hohe Anpassbarkeit: Verschiedene Ansichten (z.B. Tages-, Wochen- oder Monatsübersicht) sind möglich.
- Interaktivität: Nutzer können Termine hinzufügen, bearbeiten und löschen.
Erstellung der Webseite für den Kalender
Um den Kalender für OrangeHRM Starter zu erstellen, müssen einige grundlegende Schritte befolgt werden. Hier ist ein Beispielcode zur Implementierung:
Beispielcode index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="width=device-width, initial-scale=1.0">
<title>Urlaubskalender</title>
<link href="https://cdn.jsdelivr.net/npm/fullcalendar/main.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/fullcalendar/index.global.js"></script>
<script src="https://code.jquery.com/jquery-3.7.1.min.js" integrity="sha256-/JqT3SQfawRcv/BIHPThkBvs0OEvtFFmqPF/lYI/Cxo=" crossorigin="anonymous"></script>
<style>
/* Ensure body and html take up full window height */
body, html {
margin: 0;
padding: 0;
height: 100%;
width: 100%;
}
/* Ensure the calendar takes up the full window height */
#calendar {
height: 100vh; /* Full viewport height */
width: 100vw; /* Full viewport width */
margin: 0; /* Remove any default margin */
}
</style>
</head>
<body>
<a href="https://domain.tld">domain.tld</a>
<div id="calendar"></div>
<script>
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var colorMap = {};
var colorPalette = [
'#FF5733', '#33FF57', '#3357FF', '#F39C12', '#9B59B6',
'#1ABC9C', '#E74C3C', '#3498DB', '#2ECC71', '#8E44AD',
'#FF33D4', '#33FFF5', '#FF3333', '#33FF88', '#FF8C33',
'#5D33FF', '#33A1FF', '#FFC133', '#AFFF33', '#FF3385'
];
var colorIndex = 0;
function getColorForName(name) {
if (!colorMap[name]) {
colorMap[name] = colorPalette[colorIndex % colorPalette.length];
colorIndex++;
}
return colorMap[name];
}
function formatRecurringDate(dateStr, year) {
let [yearPart, month, day] = dateStr.split('-');
return `${year}-${month}-${day}`;
}
var calendar = new FullCalendar.Calendar(calendarEl, {
initialView: 'dayGridMonth',
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridDay,dayGridWeek,dayGridMonth'
},
height: '100%', // Ensure calendar fills the entire window height
views: {
dayGridDay: { buttonText: 'Day' },
dayGridWeek: { buttonText: 'Week' },
dayGridMonth: { buttonText: 'Month' }
},
events: function(fetchInfo, successCallback, failureCallback) {
$.ajax({
url: 'fetch_events.php',
method: 'GET',
success: function(response) {
let events = [];
let currentYear = new Date().getFullYear();
// Add regular events
for (let i = 0; i < response.events.length; i++) {
let name = response.events[i].firstname + ' ' + response.events[i].lastname;
let eventDate = response.events[i].event_date;
events.push({
title: name,
start: eventDate,
color: getColorForName(name)
});
}
// Add holiday events (including recurring ones)
for (let j = 0; j < response.holidays.length; j++) {
let holidayDate = response.holidays[j].date;
let holidayTitle = response.holidays[j].description;
let isRecurring = response.holidays[j].recurring;
// Add the holiday for multiple future years if recurring
if (isRecurring) {
for (let yearOffset = 0; yearOffset <= 5; yearOffset++) {
let recurringDate = formatRecurringDate(holidayDate, currentYear + yearOffset);
events.push({
title: holidayTitle,
start: recurringDate,
color: 'black'
});
}
} else {
events.push({
title: holidayTitle,
start: holidayDate,
color: 'black'
});
}
}
successCallback(events);
},
error: function() {
alert('Failed to fetch events');
failureCallback();
}
});
}
});
calendar.render();
});
</script>
</body>
</html>
Beispielcode fetch_events.php
<?php
$host = 'localhost';
$db = 'orangehrm';
$user = 'orangehrm';
$pass = '';
try {
$pdo = new PDO("mysql:host=$host;dbname=$db", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Fetch event data (joining employee data)
$stmt = $pdo->query("
SELECT DISTINCT
ohrm_leave.emp_number,
hs_hr_employee.emp_number,
ohrm_leave.date AS event_date,
hs_hr_employee.emp_firstname AS firstname,
hs_hr_employee.emp_lastname AS lastname
FROM ohrm_leave
JOIN hs_hr_employee ON ohrm_leave.emp_number = hs_hr_employee.emp_number
");
$events = $stmt->fetchAll(PDO::FETCH_ASSOC);
// Fetch holiday data
$stmtHolidays = $pdo->query("SELECT description, date, recurring FROM ohrm_holiday");
$holidays = $stmtHolidays->fetchAll(PDO::FETCH_ASSOC);
// Combine event and holiday data
$response = [
'events' => $events,
'holidays' => $holidays
];
header('Content-Type: application/json');
echo json_encode($response);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
?>
Beispielbild des Kalenders
Erklärung des Codes
- HTML-Datei:
- Diese Datei enthält den Grundaufbau der Seite und lädt die FullCalendar-Bibliothek sowie jQuery für eventuelle AJAX-Anfragen.
- Der Kalender wird in einem
div
-Element mit der IDcalendar
dargestellt und lädt seine Events dynamisch aus der fetch_events.php
-Datei.
- PHP-Datei:
- Die
fetch_events.php
-Datei stellt eine Verbindung zu einer MySQL-Datenbank her und führt eine SQL-Abfrage aus, um Abwesenheitsdaten abzurufen. - Die Events werden im JSON-Format zurückgegeben, damit sie von FullCalendar verarbeitet und angezeigt werden können.
- Die
Erweiterungsmöglichkeiten
Die Flexibilität von FullCalendar erlaubt es, zusätzliche Funktionen hinzuzufügen, wie z.B.:
- Filter für Abteilung oder Team: Zeigt Abwesenheiten für spezifische Gruppen an.
- Dynamische Datenbankanbindung: Events können direkt aus der OrangeHRM-Datenbank geladen werden.
- Anpassbare Event-Labels: Zeigt Details wie den Grund der Abwesenheit an.
Tipps zur Optimierung des Kalenders
- Responsive Design: Stellen Sie sicher, dass der Kalender auf mobilen Geräten gut angezeigt wird.
- Farbcodierung: Nutzen Sie verschiedene Farben für unterschiedliche Abwesenheitstypen (z.B. Urlaub, Krankheit).
FAQs
Kann der Kalender an mein Corporate Design angepasst werden?
Ja, mit der CSS-Unterstützung von FullCalendar kann der Kalender farblich und stilistisch angepasst werden.
Ist die Nutzung von FullCalendar kostenpflichtig?
Nein, FullCalendar ist in der Basisversion kostenlos nutzbar und bietet eine Pro-Version mit erweiterten Funktionen.
Unterstützt FullCalendar verschiedene Sprachen?
Ja, die Bibliothek kann mehrsprachig angepasst werden, was sie ideal für internationale Teams macht.
Fazit
Ein Kalender für OrangeHRM Starter erweitert die Funktionalitäten der Software und verbessert die Planung durch visuelle Transparenz der Abwesenheiten. Die Implementierung mit FullCalendar ist effizient und bietet umfangreiche Anpassungsoptionen, die das Nutzererlebnis optimieren.