Die dhtmlxGantt-Bibliothek bietet zwei Hauptmethoden zur Bearbeitung von Inhalten:
Die Inline-Bearbeitung ermöglicht es Ihnen, Änderungen direkt im Raster vorzunehmen. Sie können Aufgaben erstellen und aktualisieren, Verbindungen herstellen, Start- und Enddaten festlegen oder Dauern mit integrierten Editoren anpassen.
Um die Inline-Bearbeitung zu aktivieren, müssen Sie:
var textEditor = {type: "text", map_to: "text"};
var dateEditor = {type: "date", map_to: "start_date", min: new Date(2018, 0, 1),
max: new Date(2019, 0, 1)};
var durationEditor = {type: "number", map_to: "duration", min:0, max: 100};
gantt.config.columns = [
{name: "text", tree: true, width: '*', resize: true, editor: textEditor},
{name: "start_date", align: "center", resize: true, editor: dateEditor},
{name: "duration", align: "center", editor: durationEditor},
{name: "add", width: 44}
];
Related sample: Inline editing
Weitere Details zur inlineEditors Objekt-API finden Sie im Artikel Inline-Editor-Erweiterung.
Für eine praktische Demonstration sehen Sie sich den Video-Leitfaden zur Implementierung der Inline-Bearbeitung im Raster an.
Inline-Editoren sind im editor_types
Konfigurationsobjekt definiert. Die Bibliothek bietet mehrere vorkonfigurierte Editoren:
{ type: "duration", map_to: "duration", formatter: formatter }
Dieser Editor ist nützlich, wenn Sie Dauern angeben müssen, die sowohl einen numerischen Wert als auch eine Dauereinheit enthalten, wie 5 Tage
. Er verwendet standardmäßig den Duration Formatter, aber Sie können seine Einstellungen ändern oder einen benutzerdefinierten Formatter verwenden.
var editors = {
text: {type: "text", map_to: "text"},
start_date: {type: "date", map_to: "start_date", min: new Date(2018, 0, 1),
max: new Date(2019, 0, 1)},
end_date: {type: "date", map_to: "end_date", min: new Date(2018, 0, 1),
max: new Date(2019, 0, 1)},
duration: {type: "number", map_to: "duration", min:0, max: 100},
priority: {type:"select", map_to:"priority", options:gantt.serverList("priority")},
predecessors: {type: "predecessor", map_to: "auto"}
};
Ab Version 6.3 gibt es keine Standardgrenzen mehr für die minimalen und maximalen Eingabewerte in date Inline-Editoren. Wenn Sie möchten, dass die sichtbaren Daten auf der Zeitskala den Eingabebereich begrenzen, können Sie dynamische min/max Werte festlegen:
const dateEditor = {type: "date", map_to: "start_date",
min: function(taskId){
return gantt.getState().min_date
},
max: function(taskId){
return gantt.getState().max_date
}
};
Für Aufgaben, die das inklusive Enddatumsformat verwenden, können Sie einen spezifischen Editor erstellen, um dieses Format korrekt zu handhaben:
// inklusiver Editor für Enddaten
var dateEditor = gantt.config.editor_types.date;
gantt.config.editor_types.end_date = gantt.mixin({
set_value: function(value, id, column, node){
var correctedValue = gantt.date.add(value, -1, "day");
return dateEditor.set_value.apply(this, [correctedValue, id, column, node]);
},
get_value: function(id, column, node) {
var selectedValue = dateEditor.get_value.apply(this, [id, column, node]);
return gantt.date.add(selectedValue, 1, "day");
},
}, dateEditor);
var textEditor = {type: "text", map_to: "text"};
var startDateEditor = {type: "date", map_to: "start_date"};
var endDateEditor = {type: "end_date", map_to: "end_date"};
var durationEditor = {type: "number", map_to: "duration", min:0, max: 100};
gantt.config.columns = [
{name: "text", label: "Name", tree: true, width: 200, editor: textEditor,
resize: true},
{name: "duration", label: "Dauer", width:80, align: "center",
editor: durationEditor, resize: true},
{name: "start_date", label: "Start", width:140, align: "center",
editor: startDateEditor, resize: true},
{name: "end_date", label: "Ende", width:140, align: "center",
editor: endDateEditor, resize: true}
];
// Vorlagen anpassen, um Daten im inklusiven Format anzuzeigen
gantt.templates.task_end_date = function(date){
return gantt.templates.task_date(new Date(date.valueOf() - 1));
};
var gridDateToStr = gantt.date.date_to_str("%Y-%m-%d");
gantt.templates.grid_date_format = function(date, column){
if(column === "end_date"){
return gridDateToStr(new Date(date.valueOf() - 1));
}else{
return gridDateToStr(date);
}
}
Related sample: Inklusiver Enddatum-Editor
Für weitere Details, sehen Sie sich den Artikel Task end date display & Inclusive end dates an.
Diese Funktion ist nur in der PRO-Edition verfügbar.
Seit Version 6.3 unterstützt Gantt die Spezifikation von Verbindungstypen und Verzögerungs-/Vorlaufwerten direkt über den Inline-Editor. Um dies zu aktivieren, verwenden Sie das Link Formatter Modul und übergeben Sie eine LinksFormatter Instanz an den predecessor Editor:
var formatter = gantt.ext.formatters.durationFormatter({
enter: "day",
store: "day",
format: "auto"
});
var linksFormatter = gantt.ext.formatters.linkFormatter({durationFormatter: formatter});
var editors = {
text: {type: "text", map_to: "text"},
start_date: {type: "date", map_to: "start_date",
min: new Date(2018, 0, 1), max: new Date(2019, 0, 1)},
end_date: {type: "date", map_to: "end_date",
min: new Date(2018, 0, 1), max: new Date(2019, 0, 1)},
duration: {type: "duration", map_to: "duration",
min:0, max: 100, formatter: formatter},
priority: {type: "select", map_to: "priority",
options:gantt.serverList("priority")},
predecessors: {type: "predecessor", map_to: "auto", formatter: linksFormatter} };
gantt.config.columns = [
{name: "wbs", label: "#", width: 60, align: "center", template: gantt.getWBSCode},
{name: "text", label: "Name", tree: true, width: 200, editor: editors.text,
resize: true},
{name: "start_date", label: "Start", width:80, align: "center",
editor: editors.start_date, resize: true},
{name: "predecessors", label: "Vorgänger",width:80, align: "left",
editor: editors.predecessors, resize: true, template: function(task){
var links = task.$target;
var labels = [];
for(var i = 0; i < links.length; i++){
var link = gantt.getLink(links[i]);
labels.push(linksFormatter.format(link)); }
return labels.join(", ")
}},
{name:"add"}
];
Related sample: Inline editing - keyboard navigation mode
Bei Bedarf können Sie einen benutzerdefinierten Inline-Editor erstellen. Beginnen Sie mit der Definition eines neuen Editor-Objekts:
gantt.config.editor_types.custom_editor = {
show: function (id, column, config, placeholder) {
var html = "<div><input type='text' name='" + column.name + "'></div>";
placeholder.innerHTML = html;
},
hide: function () {},
set_value: function (value, id, column, node) {},
get_value: function (id, column, node) {},
is_changed: function (value, id, column, node) {},
is_valid: function (value, id, column, node) { return true; },
save: function (id, column, node) {},
focus: function (node) {}
}
Diese Struktur ermöglicht es Ihnen zu definieren, wie der Editor angezeigt, verborgen wird oder wenn Werte gesetzt, validiert oder gespeichert werden.
Die save
Funktion ist hilfreich, wenn Sie mehrere Eigenschaften einer Aufgabe gleichzeitig aktualisieren oder Objekte ändern möchten, die keine Aufgaben sind. In solchen Fällen können Sie weiterhin die get_value
Funktion für integrierte Validierungszwecke verwenden, aber das Gantt-Diagramm selbst wird den Wert des Editors nicht auf die Aufgabe anwenden. Stattdessen wird die save
Funktion aufgerufen.
Sobald save
ausgelöst wird, müssen Sie die Eingabewerte bearbeiten und die notwendigen Änderungen am Gantt-Diagramm mit benutzerdefiniertem Code vornehmen. Nach Abschluss der save
Funktion wird das onSave Ereignis ausgelöst. Das Gantt-Diagramm wird jedoch nicht automatisch gantt.updateTask für die aktualisierte Zeile aufrufen.
Wichtig: Die save
Funktion wird nur ausgeführt, wenn Sie map_to:"auto"
in der Editor-Konfiguration festgelegt haben:
var editors = {
...
predecessors: {type: "predecessor", map_to: "auto"}
};
Ein gutes Beispiel dafür ist der eingebaute Vorgänger-Editor. Eine vereinfachte Version seiner Implementierung finden Sie im folgenden Beispiel:
Related sample: Eingebauter Vorgänger-Editor
In diesem Modus können Sie Zellen durch Klicken mit der Maus bearbeiten und mit Hotkeys durch Zellen navigieren:
Related sample: Inline editing
In diesem Modus können Sie die Tastatur sowohl zum Navigieren als auch zum Bearbeiten von Rasterzellen verwenden. Vordefinierte Tasten oder Tastenkombinationen helfen dabei:
Um die Tastaturnavigation zur Bearbeitung zu aktivieren, folgen Sie diesen Schritten:
gantt.plugins({
keyboard_navigation: true
});
gantt.config.keyboard_navigation = true;
gantt.config.keyboard_navigation_cells = true;
Sie können auch eine Platzhalterzeile aktivieren, die eine leere Zeile am Ende der Aufgabenliste ist, um neue Aufgaben hinzuzufügen:
gantt.config.placeholder_task = true;
Um automatisch den Fokus auf die Platzhalteraufgabe zu setzen, nachdem eine neue hinzugefügt wurde, verwenden Sie diese Konfiguration:
gantt.config.placeholder_task = {
focusOnCreate: true
};
Zusätzlich können Sie die automatische Aufgabentyp-Erkennung aktivieren:
gantt.config.auto_types = true;
Related sample: Inline editing - keyboard navigation mode
Sie können die Tastaturbelegung anpassen, um zu definieren, wie Editoren geöffnet werden, wie editorbezogene Ereignisse (wie Öffnen und Schließen) gehandhabt werden und wie die Bearbeitungslogik verwaltet wird. Dies geschieht durch Erstellen eines benutzerdefinierten Konfigurationsobjekts und Übergeben an eine bestimmte Methode:
var mapping = {
init: function(inlineEditors){
// InlineEditor Modulinitialisierung
// Globale Listener für Bearbeitungsereignisse hinzufügen
},
onShow: function(inlineEditors, node){
// Aktionen, die ausgeführt werden, wenn der Editor angezeigt wird
},
onHide: function(inlineEditors, node){
// Bereinigungsaktionen, wenn der Editor verborgen wird
}
};
gantt.ext.inlineEditors.setMapping(mapping);
Related sample: Inline editing - Custom keyboard mapping
Stellen Sie sich zwei Szenarien vor, während Sie die Tastaturnavigation, Inline-Editoren und eine Platzhalteraufgabe verwenden:
Szenario 1: Nachdem Sie einen Namen für eine neue Platzhalteraufgabe eingegeben und die Tabulatortaste gedrückt haben, erwarten Sie, dass die nächste Zelle der Aufgabe geöffnet wird. Stattdessen wird der Fokus auf die neue Platzhalteraufgabe darunter verschoben, ohne den Editor zu öffnen.
Szenario 2: Wenn Sie einen Namen für eine neue Platzhalteraufgabe eingeben und auf die nächste Zelle klicken, wird der Fokus auf die Platzhalteraufgabe statt auf die angeklickte Zelle gesetzt.
Sie können diese Probleme lösen, indem Sie benutzerdefinierte Logik für die Handhabung von Maus- und Tastaturinteraktionen mit dem Inline-Editor definieren. Hier ist ein Beispiel:
Related sample: Gantt. Benutzerdefinierte Zuordnung für Platzhalteraufgabe
Beim Bearbeiten einer Zelle im Raster können Fehler auftreten. Um das Speichern ungültiger Werte zu verhindern, sollten Sie Eingaben vor dem Schließen des Editors validieren. Dies kann auf zwei Arten erfolgen:
So verhält sich der Editor mit aktivierter Validierung:
Weitere Details zur clientseitigen oder serverseitigen Validierung finden Sie im Artikel Validierung.
Standardmäßig setzt Gantt ungültige Eingabewerte zurück und schließt den Editor, wenn die Validierung fehlschlägt. Um zu vermeiden, dass der Editor wiederholt geöffnet wird, können Sie ein Warnfeld verwenden, um Benutzern zu ermöglichen, falsche Werte zu korrigieren. Dies erfordert eine benutzerdefinierte Tastaturbelegung, wie im Folgenden gezeigt:
function editAnotherCell(inlineEditors){
var value = inlineEditors.getValue();
if(confirm(`does '${value}' look ok to you?`)){
inlineEditors.save();
}
}
var mapping = {
init: function(inlineEditors){
gantt.attachEvent("onTaskClick", function (id, e) {
var cell = inlineEditors.locateCell(e.target);
if (cell && inlineEditors.getEditorConfig(cell.columnName)) {
if (inlineEditors.isVisible()) editAnotherCell(inlineEditors)
else inlineEditors.startEdit(cell.id, cell.columnName);
return false;
}
return true;
});
gantt.attachEvent("onEmptyClick", function () {
inlineEditors.hide();
return true;
});
},
onShow: function(inlineEditors, node){
node.onkeydown = function (e) {
e = e || window.event;
if(e.defaultPrevented){
return;
}
var keyboard = gantt.constants.KEY_CODES;
var shouldPrevent = true;
switch (e.keyCode) {
case gantt.keys.edit_save:
var value = inlineEditors.getValue();
if(confirm(`does '${value}' look ok to you?`)){
inlineEditors.save();
}
break;
case gantt.keys.edit_cancel:
inlineEditors.hide();
break;
case keyboard.TAB:
if(e.shiftKey){
if (inlineEditors.isVisible()) editAnotherCell(inlineEditors)
else inlineEditors.editPrevCell(true);
}else{
if (inlineEditors.isVisible()) editAnotherCell(inlineEditors)
else inlineEditors.editNextCell(true);
}
break;
default:
shouldPrevent = false;
break;
}
if(shouldPrevent){
e.preventDefault();
}
};
},
onHide: function(inlineEditors, node){}
};
gantt.ext.inlineEditors.setMapping(mapping);
gantt.init("gantt_here");
Related sample: Benutzerdefinierte Tastaturbelegung
Im Einzelmodus öffnet ein Klick auf eine Aufgabe den Inline-Editor.
Im Mehrfachauswahlmodus wird beim Klicken auf eine nicht ausgewählte Aufgabe diese zuerst ausgewählt, und der Editor öffnet sich erst beim zweiten Klick. Um den Editor im Mehrfachauswahlmodus beim ersten Klick zu aktivieren, verwenden Sie die Konfiguration inline_editors_multiselect_open:
gantt.plugins({
multiselect: true
});
...
gantt.config.inline_editors_multiselect_open = true;
Zurück nach oben