Mini-Kalender (Datumsauswahl)

Der Mini-Kalender (Date Picker) ist eine praktische Erweiterung, mit der Sie eine kompakte Monatsansicht in einem HTML-Container auf Ihrer Seite anzeigen können.

Related sample:  Mini calendar without the scheduler

Um den Mini-Kalender in Ihrer App zu verwenden, stellen Sie sicher, dass Sie die minical-Erweiterung auf der Seite einbinden.

Im Header

Um den Mini-Kalender (Date Picker) im Header des Schedulers anzuzeigen (wie im Bild unten), gehen Sie wie folgt vor:

  1. Binden Sie die Erweiterungsdatei auf Ihrer Seite ein:
    scheduler.plugins({
        minical: true
    });
  2. Definieren Sie den Container für den Mini-Kalender und fügen Sie ihn in das Scheduler-Markup ein:
    <div class="dhx_cal_navline">
        ...
        <div class="dhx_cal_date"></div>
        <div class="dhx_minical_icon" id="dhx_minical_icon" 
        onclick="show_minical()">&nbsp;</div>
    </div>
  3. Implementieren Sie die Logik, um den Mini-Kalender zu initialisieren (mit der Methode renderCalendar) und zu zerstören (mit der Methode destroyCalendar):
    function show_minical(){
        if (scheduler.isCalendarVisible()){
            scheduler.destroyCalendar();
        } else {
            scheduler.renderCalendar({
                position:"dhx_minical_icon",
                date:scheduler._date,
                navigation:true,
                handler:function(date,calendar){
                    scheduler.setCurrentView(date);
                    scheduler.destroyCalendar()
                }
            });
        }
    }

Related sample:  Mini calendar in the scheduler header

Im Header (Drittanbieter-Datumsauswahl)

In diesem Abschnitt wird gezeigt, wie Sie einen Mini-Kalender (Date Picker) eines Drittanbieters in den Header des Schedulers integrieren.

Related sample:  3rd party Mini Calendar in the header

Unser Beispiel verwendet jQuery und Bootstrap Datepicker, um den Mini-Kalender hinzuzufügen. Wenn Sie mit anderen Bibliotheken arbeiten, müssen Sie den Code entsprechend anpassen, aber das grundlegende Vorgehen bleibt ähnlich:

1. Datumsauswahl beim Klick auf den Kalender-Header anzeigen

Definieren Sie zunächst einen DIV-Container für den Mini-Kalender (oder ein anderes Steuerelement) im Scheduler-Header. Mit dem Markup-Initialisierungsansatz sieht das so aus:

<div id="scheduler_here" class="dhx_cal_container" style="width:100%; height:100%;">
  <div class="dhx_cal_navline">
    <div class="dhx_cal_prev_button">&nbsp;</div>
    <div class="dhx_cal_next_button">&nbsp;</div>
    <div class="dhx_cal_today_button"></div>
    <div class="dhx_cal_date"></div>
    <!--- HERE -->
    <div class="input-group date" style="display: none;">
      <input type="text" class="form-control">
      <div class="dhx_minical_icon input-group-addon" id="dhx_minical_icon">&nbsp;</div>
    </div>
    <!--- end HERE -->

Wenn Sie die header config verwenden, fügen Sie ein benutzerdefiniertes Element wie folgt hinzu:

scheduler.config.header = [
  "day",
  "week",
  "month",
  {html:'<div class="input-group date" style="display: none;">'+
    '<input type="text" class="form-control">'+
    '<div class="dhx_minical_icon input-group-addon" id="dhx_minical_icon">&nbsp;</div>'+
    '</div>'},
  "date",
  "prev",
  "today",
  "next"
];
scheduler.init("scheduler_here");

Um den Date Picker beim Klick auf das Datum im Navigationsbereich des Schedulers anzuzeigen, richten Sie das Click-Event ein, sobald der Scheduler bereit ist:

scheduler.attachEvent("onSchedulerReady", function(){
 
    const $node = $('#scheduler_here .input-group.date').datepicker({
        autoclose: true,
        todayHighlight: true,
        todayBtn: "linked",
    });
 
    $("#scheduler_here").delegate(".dhx_cal_date", "click", function () {
        $node.datepicker("show");
    });
 
    $node.datepicker().on("show", function () {
        $node.datepicker("update", scheduler.getState().date);
 
        // Popup unterhalb des Datumslabels zentrieren
        centerDatepicker($(".dhx_cal_date"));
    });
    ...
 
});

Die Funktion centerDatepicker hilft dabei, den Dropdown-Date Picker korrekt zu positionieren:

    ...
    function centerDatepicker(referenceElement) {
 
        if (!$('.datepicker-dropdown').is(':visible')) {
            return;
        }
        // Popup unterhalb des Datumslabels zentrieren
        var offset = $(".dhx_cal_date").offset();
        var width = $(".dhx_cal_date").width();
        var popupWidth = $(".datepicker-dropdown").width();
        $(".datepicker-dropdown").css({
            top: offset.bottom + "px",
            left: (width - popupWidth) / 2 + "px"
        });
    }

2. Aktuelles Scheduler-Datum bei Auswahl im Date Picker aktualisieren

Nachdem der Date Picker angezeigt wurde, aktualisieren Sie das Scheduler-Datum, wenn ein Tag ausgewählt wird:

    $node.datepicker().on("changeDate", function () {
        scheduler.setCurrentView($node.datepicker("getDate"));
    });

3. Aktuelle Daten im Date Picker hervorheben

Um die aktuell im Scheduler angezeigten Daten hervorzuheben, wenden Sie eine einfache CSS-Klasse an:

.datepicker table .scheduler-date{
    background-color: #fff3e4;
}

Alle im Scheduler sichtbaren Date-Picker-Zellen erhalten diese Klasse:

    function fillDatepicker(scheduler) {
        // Hervorgehobene Ereignisse und aktive Daten zurücksetzen
        ...
        $(".datepicker-dropdown").find("[data-date]").removeClass("scheduler-date");
 
        // Scheduler-Datum hervorheben
        var visibleDates = getVisibleDates(scheduler);
        visibleDates.forEach(function (date) {
            $(".datepicker-dropdown").find(
                "[data-date='" + date + "']"
            ).addClass("scheduler-date");
        });
        ...
    }

Um die aktuell sichtbaren Daten zu erhalten, verwenden Sie scheduler.getState:

    function getVisibleDates(scheduler) {
        var minVisible = scheduler.getState().min_date;
        var maxVisible = scheduler.getState().max_date;
 
        var current = minVisible;
        var result = [];
        while (current.valueOf() < maxVisible.valueOf()) {
            var currentUTC = Date.UTC(
                current.getFullYear(),current.getMonth(),current.getDate()
            );
            result.push(currentUTC.valueOf());
 
            current = scheduler.date.add(current, 1, "day");
        }
        return result;
    }

4. Tage mit Ereignissen im Date Picker markieren

Um Daten mit Ereignissen im Scheduler hervorzuheben, fügen Sie eine weitere CSS-Klasse hinzu:

.datepicker table .has-event::after {
    content: " ";
    width: 6px;
    height: 6px;
    position: absolute;
    background-color: #6b96f7;
    border-radius: 4px;
}

Dadurch werden die Mini-Kalender-Daten mit Ereignissen hervorgehoben.

Um beim Überfahren eines Datums einen Tooltip mit der Anzahl der Ereignisse anzuzeigen, holen Sie die Ereignisse für den aktuell im Date Picker angezeigten Monat:

    function getVisibleEvents(calendarDate, scheduler) {
        var min = scheduler.date.month_start(new Date(calendarDate));
        var max = scheduler.date.add(calendarDate, 1, "month");
        min = scheduler.date.week_start(min);
        if(scheduler.date.week_start(new Date(max)) < max){
            max = scheduler.date.week_start(new Date(max));
            max = scheduler.date.add(max, 1, "week");
        }
        var events = scheduler.getEvents(min, max);
        var days = {};
 
        events.forEach(function (event) {
            var eventDate = event.start_date;
            while(eventDate < event.end_date){
                var day = Date.UTC(
                    eventDate.getFullYear(),
                    eventDate.getMonth(),
                    eventDate.getDate()
                );
 
            if (!days[day.valueOf()]) {
                    days[day.valueOf()] = 0;
                }
                days[day.valueOf()]++;  
                eventDate = scheduler.date.add(eventDate, 1, "day");
                eventDate = scheduler.date.day_start(eventDate);
            }
        });
 
        var result = [];
        for (var i in days) {
            result.push({ timestamp: i, count: days[i] });
        }
        return result;
    }

Mit dieser Methode werden Ereignisdaten aus dem Scheduler geholt, sodass nur aktuell geladene Ereignisse hervorgehoben werden. Wenn Ihre App dynamisches Laden verwendet, werden möglicherweise nicht alle Ereignisse angezeigt, da nur ein Teil geladen ist.
Alternativ können Sie Ereignisdaten vom Server anfordern.

Sobald Sie die Ereignis-Timestamps und -Zahlen haben, können Sie den Date Picker wie folgt aktualisieren:

    function fillDatepicker(scheduler) {
        // Hervorgehobene Ereignisse und aktive Daten zurücksetzen
        $(".datepicker-dropdown").find("[data-date]").removeClass("has-event");
        $(".datepicker-dropdown").find("[data-date]").removeAttr("title");
        ...
 
        // Ereignisse hervorheben
        const eventCells = getVisibleEvents($node.datepicker("getDate"), scheduler);
        eventCells.forEach(function (cellEvents) {
            $(".datepicker-dropdown").find(
                "[data-date='" + cellEvents.timestamp + "']"
            ).addClass("has-event");
            $(".datepicker-dropdown").find(
                "[data-date='" + cellEvents.timestamp + "']"
            ).attr("title", cellEvents.count + " events");
        });
    }

5. Das angezeigte Datums-Label mit dem aktiven Scheduler-Datum synchronisieren

Schließlich zentrieren Sie den Date Picker neu, wenn sich die Fenstergröße ändert, und aktualisieren Sie die Hervorhebungen, wenn der Benutzer das Datum im Picker ändert:

    $(window).on('resize', function () {
        setTimeout(function(){
            centerDatepicker($(".dhx_cal_date"));
        }, 10);
    });
    $node.datepicker().on("changeDate", function () {
        scheduler.setCurrentView($node.datepicker("getDate"));
    });
    $node.datepicker().on("changeMonth", function () {
        refreshDatepicker(scheduler);
    });
    $node.datepicker().on("changeYear", function () {
        refreshDatepicker(scheduler);
    });
    $node.datepicker().on("changeDecade", function () {
        refreshDatepicker(scheduler);
    });
    $node.datepicker().on("changeCentury", function () {
        refreshDatepicker(scheduler);
    });
    function refreshDatepicker(scheduler) {
        // Aus Timeout heraus aufrufen, damit der Code nach dem Aktualisieren des Datepicker-Popups ausgeführt wird
        setTimeout(function () {
            fillDatepicker(scheduler);
        });
    }

Wenn Sie ein separates Element verwenden, um das aktive Datum des Schedulers anzuzeigen, hören Sie auf das onViewChange-Event und aktualisieren dort das Label:

scheduler.attachEvent("onViewChange", function (newMode , newDate){
    const state = scheduler.getState();
    const minDate = state.min_date;
    const maxDate = state.max_date;
    const dateToStr = scheduler.date.str_to_date("%d-%m-%Y");
 
    $(dateHeader).html(dateToStr(minDate) + " - " + dateToStr(minDate));
});

Beachten Sie, dass dieser Handler im Beispielcode nicht verwendet wird, da das integrierte Datums-Header automatisch aktualisiert wird. Verwenden Sie dies nur, wenn Sie das Standard-Datums-Header ausblenden oder das aktive Datum an mehreren Stellen anzeigen möchten.

Im Lightbox

Der Mini-Kalender (Date Picker) kann auch innerhalb des Lightbox zur Auswahl von "Start"- und "Ende"-Daten genutzt werden.

Um den Mini-Kalender im Lightbox hinzuzufügen, gehen Sie wie folgt vor:

  1. Aktivieren Sie die Erweiterung auf der Seite:
    scheduler.plugins({
        minical: true
    });
  2. Ändern Sie den type des time-Abschnitts zu calendar_time anstelle von time:
    // Standard-Lightbox-Definition
    scheduler.config.lightbox.sections=[
      {name:"description", height:200, map_to:"text", type:"textarea", focus:true},
      {name:"time", height:72, type:"time", map_to:"auto"}
    ];
    // type:"time" -> type:"calendar_time" ändern
    scheduler.config.lightbox.sections = [
      {name:"description", height:200, map_to:"text", type:"textarea", focus:true},
      {name:"time", height:72, type:"calendar_time", map_to:"auto" }
    ];

Related sample:  Mini calendar in the lightbox

Außerhalb des Schedulers

Der Mini-Kalender (Date Picker) kann an beliebiger Stelle auf der Seite platziert werden.

Um den Mini-Kalender in einem HTML-Container außerhalb des Schedulers hinzuzufügen, gehen Sie wie folgt vor:

  1. Aktivieren Sie die Erweiterung auf der Seite:
    scheduler.plugins({
        minical: true
    });
  2. Definieren Sie den Container für den Mini-Kalender auf Ihrer Seite:
    <div id="scheduler_here" class="dhx_cal_container" ...>
    ...
    </div>
     
    <div style='float: left; padding:10px;'>
            <div id="cal_here" style='width:250px;'></div>
    </div>
  3. Rufen Sie die Methode renderCalendar auf, um den Mini-Kalender zu rendern:
    const calendar = scheduler.renderCalendar({
        container:"cal_here", 
        navigation:true,
        handler:function(date){
            scheduler.setCurrentView(date, scheduler._mode);
        }
    });

Related sample:  Mini calendar outside the scheduler

Templates und Styles

Templates

Sie können das Anzeigeformat von Daten im Mini-Kalender (Datumsauswahl) einfach anpassen, indem Sie verschiedene in dem Artikel Mini-Kalender-Vorlagen beschriebene Templates verwenden.

scheduler.templates.calendar_month = scheduler.date.date_to_str("%M, %Y");
scheduler.init('scheduler_here',new Date(2019,2,1),"day");
...
const calendar = scheduler.renderCalendar({..});

CSS-Klassen

Um das Erscheinungsbild der Tage im Mini-Kalender (Datumsauswahl) anzupassen, können Sie die folgenden CSS-Klassen überschreiben:

CSS-Klasse Angewendet auf
.dhx_cal_container.dhx_mini_calendar .dhx_month_head eine Tageszelle
.dhx_cal_container.dhx_mini_calendar .dhx_month_head.dhx_year_event eine Tageszelle mit zugewiesenem/n Ereignis(sen)
.dhx_cal_container.dhx_mini_calendar .dhx_now .dhx_month_head eine Tageszelle mit dem aktuellen Datum
.dhx_cal_container.dhx_mini_calendar .dhx_calendar_click eine Tageszelle mit dem aktuell aktiven Datum
<style>
.dhx_cal_container.dhx_mini_calendar .dhx_calendar_click{
    color:red;
}
</style>
<script>
    const calendar = scheduler.renderCalendar({...});
</script>

Markieren von Tagen mit der Methode markCalendar()

Um einem Tag eine bestimmte CSS-Klasse zuzuweisen, können Sie die Methode markCalendar verwenden:

<style>
.my_style{
    background: red !important;
}
</style>
<script>
    const calendar = scheduler.renderCalendar({...});
    ...
    scheduler.markCalendar(calendar, new Date(2019,3,1), "my_style");
</script>

API

Event-Handling

Der Mini-Kalender unterstützt Callbacks für typische Benutzerinteraktionen wie das Wechseln des sichtbaren Monats, das Überfahren von Daten mit der Maus sowie das Klicken auf Daten. Diese können in der events-Eigenschaft des Konfigurationsobjekts gesetzt werden:

const dateToStr = (date) => date ? scheduler.templates.format_date(date) : null;
const calendar = scheduler.renderCalendar({
    container: "cal_here",
    navigation: true,
    events: {
        onBeforeMonthChange: function(oldDate, newDate) {
            scheduler.message(`Before change from ${dateToStr(oldDate)} 
                to ${dateToStr(newDate)}`);
            return true;
        },
        onMonthChange: function(oldDate, newDate) {
            scheduler.message(`Changed from ${dateToStr(oldDate)} 
                to ${dateToStr(newDate)}`);
        },
        onDateClick: function(date, e) {
            scheduler.setCurrentView(date);
            scheduler.message(`Selected date ${dateToStr(date)}`);
        },
        onDateMouseOver: function(date, e){
            scheduler.message(`Mouse over ${dateToStr(date)}`)
 
        }
    }
});
Nach oben