Zum Hauptinhalt springen

Erstellen eines benutzerdefinierten Elements

Um ein benutzerdefiniertes Steuerelement zum Lightbox-Dialog hinzuzufügen, definieren Sie ein neues Objekt wie folgt:

gantt.form_blocks["my_editor"]={
render:function(sns){ //sns - das Konfigurationsobjekt des Abschnitts
return "html code of the editor here";
},
set_value:function(node,value,task,section){
//node - ein HTML-Element, das mit dem oben definierten HTML verbunden ist
//value - ein Wert, der durch die Eigenschaft map_to definiert ist
//task - das Aufgabenobjekt
//section- das Konfigurationsobjekt des Abschnitts
... code to set value to the element ...
},
get_value:function(node,task,section){
//node - ein HTML-Element, das mit dem oben definierten HTML verbunden ist
//task - das Aufgabenobjekt
//section - das Konfigurationsobjekt des Abschnitts
return "current value from editor";
},
focus:function(node){
//node - ein HTML-Element, das mit dem oben definierten HTML verbunden ist
...code to set focus to the element...
}
}

Beachten Sie, dass Sie keine selbstschließenden Tags im HTML-Code verwenden sollten, der von der "render"-Funktion zurückgegeben wird, da dies in einigen Browsern zu Parsing-Problemen führen kann:

//DAS IST FALSCH
render:function(){
return "<div id='box'/>";
}

//Stattdessen Öffnungs- und Schließ-Tags verwenden:
render:function(){
return "<div id='box'></div>"; // empfohlen
}

Custom control in the lightbox

Das Lightbox-Steuerelement besteht aus folgenden Methoden:

  • render (sns): string - gibt einen String mit den HTML-Elementen für den Abschnitt zurück
    • sns - (LightboxSection) - das Konfigurationsobjekt des Abschnitts
  • set_value (node, value, task, section): any - übernimmt den Wert aus dem Task-Objekt und wendet ihn auf den Abschnitt an
    • node - (HTMLElement) - ein HTML-Element, das mit dem HTML des Abschnitts verbunden ist
    • value - (any) - ein Wert, der durch die Eigenschaft map_to definiert ist
    • task - (Task) - das Aufgabenobjekt
    • section - (LightboxSection) - das Konfigurationsobjekt des Abschnitts
  • get_value (node, task, section): any - liest den Wert aus dem Abschnitt aus und speichert ihn zurück im Task-Objekt
    • node - (HTMLElement) - ein HTML-Element, das mit dem HTML des Abschnitts verbunden ist
    • task - (Task) - das Aufgabenobjekt
    • section - (LightboxSection) - das Konfigurationsobjekt des Abschnitts
  • focus (node): void - setzt den Fokus auf den Abschnitt
    • node - (HTMLElement) - ein HTML-Element, das mit dem HTML des Abschnitts verbunden ist

Benutzerdefinierter Editor mit zwei Eingabefeldern

Hier ein Beispiel für die Erstellung eines benutzerdefinierten Editors mit zwei Eingabefeldern:

custom_lightbox_editor

gantt.form_blocks["my_editor"] = {
render: function (sns) {
return "<div className='dhx_cal_ltext' style='height:60px;'>"+
"Text&nbsp;<input className='editor_description' type='text'/>"+
"

Holders&nbsp;<input className='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"}
];

Custom control in the lightbox

Benutzerdefiniertes Drittanbieter-Editorfeld

Es ist möglich, ein benutzerdefiniertes Multiselect-Steuerelement zu erstellen, um mehrere Werte auszuwählen.

Zum Beispiel kann ein Steuerelement auf Basis des jQuery Chosen Plugins verwendet werden, um mehreren Ressourcen eine Aufgabe zuzuweisen. Im Gegensatz zum Standard-Gantt-Ressourcen-Steuerelement weist dieses Steuerelement nur Ressourcen zu, ohne Mengen anzugeben. Es ist eine einfache Option, wenn ein unkompliziertes Steuerelement bevorzugt wird.

Custom resources control

3rd party multiselect control

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

  • Binden Sie die benötigten Quell-Dateien auf Ihrer Seite ein
<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 die Logik des Steuerelements
gantt.form_blocks["multiselect"] = {
render: function (sns) {
var height = (sns.height || "23") + "px";
var html = "<div className='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();
}
};
  • Fügen Sie das Steuerelement als Lightbox-Abschnitt mit type:"multiselect" hinzu
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 zur Auswahl stehen sollen. Setzen Sie diese auf die ID der Ressource, die ausgeschlossen werden soll. Im obigen Beispiel wird die Ressource mit id="5" nicht im Steuerelement angezeigt.

Benutzerdefinierter Drittanbieter-Datepicker

Es ist ebenfalls möglich, ein benutzerdefiniertes Datepicker-Steuerelement zur Lightbox hinzuzufügen, um die Aufgabendauer durch Angabe von Start- und Enddatum festzulegen.

jQuery Datepicker in der Lightbox

Ein Datepicker-Steuerelement kann beispielsweise mit jQuery UI Datepicker erstellt werden.

Custom Datepicker control

Related example: 3rd party Datepicker control

Um ein jQuery Datepicker-Steuerelement im Gantt-Diagramm zu verwenden:

  • Binden Sie die jQuery-Bibliotheken auf Ihrer Seite ein:
<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">
  • Implementieren Sie die Logik für das Steuerelement:
(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 - das Konfigurationsobjekt des Abschnitts
return "<div className='gantt-lb-datepicker'>"+
"<input type='text' name='start'/>"+
"<input type='text' name='end'/>"+
"</div>";;
},
set_value: function (node, value, task, section) {
//node - ein HTML-Element, das mit dem oben definierten HTML verbunden ist
//value - ein Wert, der durch die Eigenschaft map_to definiert ist
//task - das Aufgabenobjekt
//section- 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 dann als Lightbox-Abschnitt mit type:"datepicker":
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 im Lightbox

Das Hinzufügen eines Bootstrap Datepickers innerhalb des Lightbox funktioniert ähnlich wie die Integration des jQuery Datepickers.

Bootstrap Datepicker control

Related example: Bootstrap Datepicker control

So integrieren Sie ein Bootstrap Datepicker Control in das Gantt Chart:

  • Binden Sie die Quell-Dateien der Bootstrap-Bibliothek auf der Seite ein;

  • 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 className='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) => {
}
}
})();
  • Verwenden Sie dieses Steuerelement dann als Lightbox-Abschnitt, indem Sie type:"datepicker" angeben:
gantt.config.lightbox.sections = [
{ name: "description", height: 70, map_to: "text", type: "textarea", focus: true },
{ name: "time", height: 45, map_to: "auto", type: "datepicker" }
];

Benutzerdefiniertes Drittanbieter-Dauer-Steuerelement

Es ist auch möglich, ein benutzerdefiniertes Dauer-Steuerelement zur Lightbox hinzuzufügen, mit dem das Startdatum der Aufgabe zusammen mit der Dauer in Tagen festgelegt werden kann.

Custom Duration control

Related example: 3rd party Duration control

So fügen Sie ein benutzerdefiniertes Dauer-Steuerelement auf Basis von jQuery hinzu:

  • Binden Sie zunächst die Quell-Dateien der jQuery-Bibliothek auf der Seite ein:
<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 dann die Logik für das Steuerelement:
(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 - the section's configuration object
return "<div className='gantt-lb-datepicker'>"+
"<label>Start:<input type='text' name='start'/></label>"+
"<label>Duration: <input type='text' name='duration'/></label>"+
"<span className='gantt-lb-datepicker-label'></span>"
"</div>";
},
set_value: function (node, value, task, section) {
//node - an html object related to the html defined above
//value - a value defined by the map_to property
//task - the task object
//section- the section's configuration object

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) {

}
}
})();
  • Verwenden Sie dieses Steuerelement abschließend als Lightbox-Abschnitt mit type:"datepicker_duration":
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" }
];