Erstellen eines benutzerdefinierten Elements

Um ein benutzerdefiniertes Steuerelement für das Lightbox zu erstellen, müssen Sie ein neues Objekt wie folgt definieren:

gantt.form_blocks["my_editor"] = {
    render: function(sns) { // sns ist das Konfigurationsobjekt des Abschnitts
        return "HTML-Code des Editors hier";
    },
    set_value: function(node, value, task, section) {
        // node ist das HTML-Element, das mit dem obigen Code verknüpft ist
        // value stammt aus der map_to-Eigenschaft
        // task ist das Aufgabenobjekt
        // section ist das Konfigurationsobjekt des Abschnitts
        ... Code zum Setzen des Wertes für das Element ...
    },
    get_value: function(node, task, section) {
        // node ist das HTML-Element, das mit dem obigen Code verknüpft ist
        // task ist das Aufgabenobjekt
        // section ist das Konfigurationsobjekt des Abschnitts
        return "aktueller Wert aus dem Editor";
    },
    focus: function(node) {
        // node ist das HTML-Element, das mit dem obigen Code verknüpft ist
        ... Code, um den Fokus auf das Element zu setzen ...
    }
}

Es ist wichtig, die kurze Schließsyntax für Tags im HTML, das von der render-Funktion zurückgegeben wird, zu vermeiden. Dies kann zu Parsing-Problemen im Browser führen:

// Vermeiden Sie dies
render: function() {
    return "<div id='box'/>";
}
 
// Verwenden Sie stattdessen dies
render: function() {
    return "<div id='box'></div>"; // empfohlen
}

Related sample:  Custom control in the lightbox

Lightbox-Steuerelemente umfassen die folgenden Typen:

  • render (sns): string - Erzeugt einen String, der das HTML für den Abschnitt enthält.
    • sns - (LightboxSection) - Konfigurationsdetails für den Abschnitt.
  • set_value (node, value, task, section): any - Weist einen Wert aus dem Task-Objekt dem Abschnitt zu.
    • node - (HTMLElement) - Das HTML-Element, das mit dem Abschnitt verknüpft ist.
    • value - (any) - Der durch die map_to-Eigenschaft definierte Wert.
    • task - (Task) - Das Aufgabenobjekt.
    • section - (LightboxSection) - Konfigurationsdetails für den Abschnitt.
  • get_value (node, task, section): any - Ruft den Wert aus dem Abschnitt ab und speichert ihn im Task-Objekt.
    • node - (HTMLElement) - Das HTML-Element, das mit dem Abschnitt verknüpft ist.
    • task - (Task) - Das Aufgabenobjekt.
    • section - (LightboxSection) - Konfigurationsdetails für den Abschnitt.
  • focus (node): void - Setzt den Fokus auf den Abschnitt.
    • node - (HTMLElement) - Das HTML-Element, das mit dem Abschnitt verknüpft ist.

Benutzerdefinierter Editor mit zwei Eingabefeldern

Hier ist ein Beispiel, wie man einen benutzerdefinierten Editor mit zwei Eingabefeldern erstellt:

gantt.form_blocks["my_editor"] = {
    render: function (sns) {
        return "<div class='dhx_cal_ltext' style='height:60px;'>"+
            "Text&nbsp;<input class='editor_description' type='text'>"+
            "<br/>Holders&nbsp;<input class='editor_holders' type='text'>"+
            "</div>";
    },
    set_value: function (node, value, task) {
        node.querySelector(".editor_description").value = value || "";
        node.querySelector(".editor_holders").value = task.users || "";
    },
    get_value: function (node, task) {
        task.users = node.querySelector(".editor_holders").value;
        return node.querySelector(".editor_description").value;
    },
    focus: function (node) {
        var a = node.querySelector(".editor_description");
        a.select();
        a.focus();
    }
};
gantt.config.lightbox.sections = [
    { name:"description", height:200, map_to:"text", type:"my_editor", focus:true},
    { name:"time", height:72, type:"duration", map_to:"auto"}
];

Related sample:  Custom control in the lightbox

Benutzerdefinierter Drittanbieter-Editor

Sie können ein Multiselect-Steuerelement hinzufügen, um die Auswahl mehrerer Werte zu ermöglichen. Beispielsweise kann ein auf dem jQuery Chosen plugin basierendes Steuerelement verwendet werden, um mehreren Ressourcen einer Aufgabe zuzuweisen. Dies unterscheidet sich von dem standardmäßigen Gantt- Ressourcensteuerung, da es keine Ressourcenkontingente behandelt. Es ist eine einfachere Option für bestimmte Anwendungsfälle.

Benutzerdefinierte Ressourcensteuerung

Related sample:  3rd party multiselect control

Um ein auf jQuery Chosen basierendes Steuerelement in das Gantt-Diagramm zu integrieren:

  • Fügen Sie seine Quelldateien Ihrer Seite hinzu:
<script
    src="https://code.jquery.com/jquery-3.3.1.min.js?v=5.2.4"
    integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8="
    crossorigin="anonymous"></script>
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.jquery.js?v=5.2.4"></script>
<link rel="stylesheet" type="text/css" 
    href="https://cdnjs.cloudflare.com/ajax/libs/chosen/1.8.7/chosen.css?v=5.2.4">
  • Definieren Sie das Verhalten des Steuerelements:
gantt.form_blocks["multiselect"] = {
 render: function (sns) {
  var height = (sns.height || "23") + "px";
  var html = "<div class='gantt_cal_ltext gantt_cal_chosen gantt_cal_multiselect'"+
     "style='height:"+ height + ";'><select data-placeholder='...'"+
        "class='chosen-select' multiple>";
  if (sns.options) {
   for (var i = 0; i < sns.options.length; i++) {
    if(sns.unassigned_value !== undefined && sns.options[i].key==sns.unassigned_value){
        continue;
    }
    html+="<option value='" +sns.options[i].key+ "'>"+sns.options[i].label+"</option>";
  }
}
  html += "</select></div>";
  return html;
},
 
set_value: function (node, value, ev, sns) {
    node.style.overflow = "visible";
    node.parentNode.style.overflow = "visible";
    node.style.display = "inline-block";
    var select = $(node.firstChild);
 
    if (value) {
        value = (value + "").split(",");
        select.val(value);
    }
    else {
        select.val([]);
    }
 
    select.chosen();
    if(sns.onchange){
        select.change(function(){
            sns.onchange.call(this);
        })
    }
    select.trigger('chosen:updated');
    select.trigger("change");
},
 
get_value: function (node, ev) {
    var value = $(node.firstChild).val();
    //value = value ? value.join(",") : null
    return value;
},
 
focus: function (node) {
    $(node.firstChild).focus();
 }
};
  • Verwenden Sie das Steuerelement als Lightbox-Abschnitt, indem Sie type:"multiselect" festlegen:
gantt.config.lightbox.sections = [
    {name:"description",height:38,map_to:"text",type:"textarea",focus: true},
    {name:"owner",height:60, type:"multiselect", options:gantt.serverList("people"), 
        map_to:"owner_id", unassigned_value:5 },
    {name: "time", type: "duration", map_to: "auto"}
];

Die unassigned_value-Eigenschaft blendet Ressourcen aus, die nicht auswählbar sein sollen. Setzen Sie die ID der Ressource als Wert dieser Eigenschaft. Im obigen Beispiel wird die Ressource mit id=5 nicht als Option angezeigt.

Benutzerdefinierter Drittanbieter-Datumswähler

Sie können einen benutzerdefinierten Datumswähler in die Lightbox aufnehmen, um Aufgabendauern durch Auswahl von Start- und Enddaten festzulegen.

jQuery Datepicker in der Lightbox

Hier ist ein Beispiel für die Erstellung eines Datepicker-Steuerelements mit jQuery UI Datepicker.

Benutzerdefinierte Datepicker-Steuerung

Related sample:  3rd party Datepicker control

Um ein jQuery Datepicker-Steuerelement in das Gantt-Diagramm zu integrieren:

  • Fügen Sie die jQuery-Bibliotheksdateien Ihrer Seite hinzu:
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link  rel="stylesheet" type="text/css" 
    href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  • Definieren Sie das Verhalten des Steuerelements:
(function () {
    function startDatepicker(node){
        return $(node).find("input[name='start']");
    }
    function endDateInput(node){
        return $(node).find("input[name='end']");
    }
 
    gantt.form_blocks["datepicker"] = {
        render: function (sns) { // sns ist das Konfigurationsobjekt des Abschnitts
            return "<div class='gantt-lb-datepicker'>"+
                "<input type='text' name='start'>"+
                "<input type='text' name='end'>"+
                "</div>";;
        },
        set_value: function (node, value, task, section) {
            // node ist das HTML-Element, das mit dem obigen Code verknüpft ist
            // value stammt aus der map_to-Eigenschaft
            // task ist das Aufgabenobjekt
            // section ist das Konfigurationsobjekt des Abschnitts
 
            startDatepicker(node).datepicker({
                dateFormat: "yy-mm-dd",
                onSelect: function (dateStr) {
                    var endValue = endDateInput(node).datepicker('getDate');
                    var startValue = startDatepicker(node).datepicker('getDate');
 
                    if(startValue && endValue){
                        if(endValue.valueOf() <= startValue.valueOf()){
                            endDateInput(node).datepicker("setDate", 
                                gantt.calculateEndDate({
                                    start_date: startValue, duration: 1, task:task
                                })
                            );
                        }
                    }
                }
            });
 
            startDatepicker(node).datepicker("setDate", task.start_date);
 
            endDateInput(node).datepicker({
                dateFormat: "yy-mm-dd",
                onSelect: function (dateStr) {
                    //  gantt.ext.inlineEditors.save()
                }
            });
            endDateInput(node).datepicker("setDate", task.end_date);
        },
        get_value: function (node, task, section) {
 
            if(task.start_date && task.end_date) {
                var start = startDatepicker(node).datepicker('getDate');
                var end =  endDateInput(node).datepicker('getDate');
 
                if(end.valueOf() <= start.valueOf()){
                    end = gantt.calculateEndDate({
                        start_date: start, duration: 1, task:task
                    });
                }
                task.start_date = start;
                task.end_date = end;                 
            }
 
            task.duration = gantt.calculateDuration(task);
        },
        focus: function (node) {
 
        }
    }
})();
  • Verwenden Sie das Steuerelement als Lightbox-Abschnitt, indem Sie type:"datepicker" festlegen:
gantt.config.lightbox.sections = [
  { name: "description", height: 70, map_to: "text", type: "textarea", focus: true },
  { name: "time", height: 72, map_to: "auto", type: "datepicker" }
];

Bootstrap Datepicker in der Lightbox

Sie können einen Bootstrap Datepicker in die Lightbox integrieren, ähnlich wie Sie einen jQuery Datepicker verwenden würden.

Bootstrap Datepicker-Steuerung

Related sample:  Bootstrap Datepicker control

Um einen Bootstrap Datepicker in das Gantt-Diagramm einzubinden:

  • Stellen Sie sicher, dass Sie die Quelldateien der Bootstrap-Bibliothek Ihrer Seite hinzufügen.

  • Definieren Sie die Logik für das Steuerelement:

(function () {
    const startDatepicker = (node) => $(node).find("input[name='start']");
    const endDateInput = (node) => $(node).find("input[name='end']");
 
    gantt.form_blocks["datepicker"] = {
        render: (sns) => {
          const height = sns.height || 45;
            return "<div class='gantt-lb-datepicker' style='height:" + height + "px;'>"+
                        "<input type='text' name='start'> - "+
                        "<input type='text' name='end'>"+
                    "</div>";;
        },
        set_value: (node, value, task, section) => {
            const datepickerConfig = { 
                format: 'yyyy-mm-dd',
                autoclose: true,
                container: gantt.$container
            };
            startDatepicker(node).datepicker(datepickerConfig);
            startDatepicker(node).datepicker('setDate', 
                value ? value.start_date : task.start_date
            );
 
            endDateInput(node).datepicker(datepickerConfig);
            endDateInput(node).datepicker('setDate', 
                value ? value.end_date : task.end_date
            );
 
            startDatepicker(node).datepicker().on('changeDate', function(e) {
                const endValue = endDateInput(node).datepicker('getDate');
                const startValue = startDatepicker(node).datepicker('getDate');
 
                if (startValue && endValue) {
                    if (endValue.valueOf() <= startValue.valueOf()) {
                        endDateInput(node).datepicker('setDate', 
                            gantt.calculateEndDate({
                                start_date: startValue, duration: 1, task:task
                            })
                        );
                    }
                }
            });
        },
        get_value: (node, task, section) => {
            const start = startDatepicker(node).datepicker('getDate');
            let end =  endDateInput(node).datepicker('getDate');
 
            if (end.valueOf() <= start.valueOf()) {
                end = gantt.calculateEndDate({
                    start_date: start,
                    duration: 1,
                    task:task
                });
            }
            if (task.start_date && task.end_date) {
                task.start_date = start;
                task.end_date = end;                 
            }
 
            task.duration = gantt.calculateDuration(task);
 
            return {
                start_date: start,
                end_date: end,
                duration: task.duration
            };
        },
        focus: (node) => {
        }
    }
})();
  • Fügen Sie das Steuerelement als Lightbox-Abschnitt hinzu, indem Sie type:"datepicker" verwenden:
gantt.config.lightbox.sections = [
  { name: "description", height: 70, map_to: "text", type: "textarea", focus: true },
  { name: "time", height: 45, map_to: "auto", type: "datepicker" }
];

Benutzerdefinierte Drittanbieter-Dauersteuerung

Sie möchten möglicherweise auch eine benutzerdefinierte Dauersteuerung zur Lightbox hinzufügen. Diese Steuerung ermöglicht es Ihnen, das Startdatum einer Aufgabe festzulegen und deren Dauer in Tagen anzugeben.

Benutzerdefinierte Dauersteuerung

Related sample:  3rd party Duration control

Um eine benutzerdefinierte Dauersteuerung mit jQuery zu erstellen:

  • Fügen Sie die erforderlichen jQuery-Bibliotheksdateien auf Ihrer Seite hinzu:
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<link  rel="stylesheet" type="text/css" 
    href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
  • Definieren Sie die Logik des Steuerelements:
(function () {
    function startDatepicker(node){
        return $(node).find("input[name='start']");
    }
    function durationInput(node){
        return $(node).find("input[name='duration']");
    }
    function endDateLabel(node){
        return $(node).find("span.gantt-lb-datepicker-label");
    }
 
    var formatter = gantt.ext.formatters.durationFormatter({
        enter: "day",
        store: "day",
        format: "auto"
    });
 
    gantt.form_blocks["datepicker_duration"] = {
        render: function (sns) { //sns - das Konfigurationsobjekt des Abschnitts
            return "<div class='gantt-lb-datepicker'>"+
                "<label>Start:<input type='text' name='start'></label>"+
                "<label>Duration: <input type='text' name='duration'></label>"+
                "<span class='gantt-lb-datepicker-label'></span>"
                "</div>";
        },
        set_value: function (node, value, task, section) {
            //node - ein HTML-Objekt, das mit dem oben definierten HTML verknüpft ist
            //value - ein Wert, der durch die map_to-Eigenschaft definiert ist
            //task - das Aufgabenobjekt
            //section- das Konfigurationsobjekt des Abschnitts
 
            startDatepicker(node).datepicker({
                dateFormat: "yy-mm-dd",
                onSelect: function (dateStr) {
                    var endValue = durationInput(node).datepicker('getDate');
                    var startValue = startDatepicker(node).datepicker('getDate');
 
                    if(startValue && endValue){
                        if(endValue.valueOf() <= startValue.valueOf()){
                            durationInput(node).datepicker("setDate",
                                gantt.calculateEndDate({
                                    start_date: startValue, duration: 1, task:task
                                })
                            );
                        }
                    }
                }
            });
 
            startDatepicker(node).datepicker("setDate", task.start_date);
 
            durationInput(node).val(formatter.format(task.duration));
            endDateLabel(node).text(
                "Ends: " + gantt.templates.task_date(task.end_date)
            );
        },
        get_value: function (node, task, section) {
 
            if(task.start_date && task.end_date) {
                var start = startDatepicker(node).datepicker('getDate');
                var end = task.end_date;
                var duration = formatter.parse(durationInput(node).val());
 
                if(duration && !isNaN(Number(duration))){
                    end = gantt.calculateEndDate({
                        start_date: start, duration: duration, task:task
                    });
                }
                task.start_date = start;
                task.duration = duration;
                task.end_date = end;
            }
 
            task.duration = gantt.calculateDuration(task);
            return {
                start_date: task.start_date,
                end_date: task.end_date,
                duration: task.duration
            }
        },
        focus: function (node) {
 
        }
    }
})();
  • Fügen Sie das Steuerelement als Lightbox-Abschnitt hinzu, indem Sie type:"datepicker_duration" verwenden:
gantt.config.lightbox.sections = [
  { name: "description", height: 70, map_to: "text", type: "textarea", focus: true },
  { name: "time", height: 72, map_to: "auto", type: "datepicker_duration" }
];
Zurück nach oben