翻译|使用教程|编辑:杨鹏连|2021-03-30 13:14:00.447|阅读 411 次
概述:内联编辑使您可以直接在网格中进行任何更改:创建和更新任务,设置任务之间的连接,定义开始和结束日期或修改持续时间-所有这些都通过内置编辑器进行。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
相关链接:
dhtmlxGantt是用于跨浏览器和跨平台应用程序的功能齐全的Gantt图表。可满足项目管理应用程序的所有需求,是最完善的甘特图图表库。它允许你创建动态甘特图,并以一个方便的图形化方式可视化项目进度。有了dhtmlxGantt,你可以显示活动之间的依赖关系,显示具有完成百分比阴影的当前任务状态以及组织活动到树结构。
dhtmlxGantt提供了两个用于编辑内容的选项:
要启用内联编辑,您需要:
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} ];您可以看一下视频指南,该指南显示了如何在网格中实现内联编辑。
编辑类型
内联编辑器存储在editor_types配置对象中。
有几种预定义的内联编辑器:
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"} };日期编辑器中的日期限制
从v6.3开始,日期内联编辑器的最小和最大输入值没有默认限制。
如果希望时间刻度上显示的日期限制日期内联编辑器的最小值和最大值(除非提供了自定义的最小值/最大值),则可以指定动态最小值/最大值:
const dateEditor = {type: "date", map_to: "start_date", min: function(taskId){ return gantt.getState().min_date }, max: function( taskId ){ return gantt.getState().max_date } };结束日期的编辑器
如果将格式用于任务的包含结束日期,并希望通过网格中的内联编辑使其正确运行,则必须创建一个特殊的编辑器来编辑任务的包含结束日期,如下所示:
// inclusive editor for end dates // use the default editor, but override the set_value/get_value methods 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: "Duration", 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: "Finish", width:140, align: "center", editor: endDateEditor, resize: true} ]; // change lightbox and grid templates to display dates of tasks in an inclusive format 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); } }格式化前置编辑器的值
从v6.3开始,Gantt允许直接从内联编辑器中指定链接的类型以及滞后/超前值。
为此,您需要使用链接格式化程序模块,并将LinksFormatter的一个实例提供到先前的编辑器中:
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: "Predecessors",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"} ];自定义内联编辑器
您还可以指定自定义内联编辑器。为此,您需要通过以下方式创建一个新的编辑器对象:
gantt.config.editor_types.custom_editor = { show: function (id, column, config, placeholder) { // called when input is displayed, put html markup of the editor into placeholder // and initialize your editor if needed: var html = "<div><input type='text' name='" + column.name + "'></div>"; placeholder.innerHTML = html; }, hide: function () { // called when input is hidden // destroy any complex editors or detach event listeners from here }, set_value: function (value, id, column, node) { // set input value }, get_value: function (id, column, node) { // return input value }, is_changed: function (value, id, column, node) { //called before save/close. Return true if new value differs from the original one //returning true will trigger saving changes, returning false will skip saving }, is_valid: function (value, id, column, node) { // validate, changes will be discarded if the method returns false return true/false; }, save: function (id, column, node) { // only for inputs with map_to:auto. complex save behavior goes here }, focus: function (node) { } }为了实现可重用的编辑器,需要记住一些关键点:
var getInput = function(node){ return node.querySelector("input"); }; gantt.config.editor_types.simpleNumber = { show: function (id, column, config, placeholder) { var min = config.min || 0, max = config.max || 100; var html = "<div><input type='number' min='" + min + "' max='" + max + "' name='" + column.name + "'></div>"; placeholder.innerHTML = html; }, hide: function () { // can be empty since we don't have anything to clean up after the editor // is detached }, set_value: function (value, id, column, node) { getInput(node).value = value; }, get_value: function (id, column, node) { return getInput(node).value || 0; }, is_changed: function (value, id, column, node) { var currentValue = this.get_value(id, column, node); return Number(value) !== Number(currentValue); }, is_valid: function (value, id, column, node) { return !isNaN(parseInt(value, 10)); }, focus: function (node) { var input = getInput(node); if (!input) { return; } if (input.focus) { input.focus(); } if (input.select) { input.select(); } } };之后,您可以使用与内置编辑器相同的方式来使用编辑器:
var numberEditor = {type: "simpleNumber", map_to: "quantity", min:0, max: 50}; gantt.config.columns = [ ... {name: "quantity", label: "Quantity", width: 80, editor: numberEditor, resize: true}, ... ];请注意,hide在这种情况下,我们不需要实现该方法,因为甘特图会自动分离编辑器的DOM元素,并且在关闭编辑器后无需清理其他内容。
编辑器
hide如果您在内联编辑器中使用复杂的小部件,则可能需要添加逻辑。
例如,让我们考虑以下使用jQuery的DatePicker输入的实现。在这种情况下,我们需要在将日期选择器小部件与DOM分离后销毁它。
先决条件:
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.12.4.js"></script> <script src="//code.jquery.com/ui/1.12.1/jquery-ui.js"></script>编辑:
gantt.config.editor_types.custom_datepicker_editor = { show: function (id, column, config, placeholder) { placeholder.innerHTML = "<div><input type='text' id='datepicker' name='" + column.name + "'></div>"; $("#datepicker").datepicker({ dateFormat: "yy-mm-dd", onSelect: function(dateStr){ gantt.ext.inlineEditors.save() } }); }, hide: function (node) { $("#datepicker").datepicker( "destroy" ); }, set_value: function (value, id, column, node) { $("#datepicker").datepicker("setDate", value); }, get_value: function (id, column, node) { return $("#datepicker").datepicker( "getDate" ); }, is_changed: function (value, id, column, node) { return (+$("#datepicker").datepicker( "getDate" ) !== +value); }, is_valid: function (value, id, column, node) { return !(isNaN(+$("#datepicker").datepicker( "getDate" ))) }, save: function (id, column, node) { }, focus: function (node) { } }; let dateEditor = { type: "custom_datepicker_editor", map_to: "start_date" }; gantt.config.columns = [ {name: "text", tree: true, width: '*', resize: true}, {name: "start_date", align: "center", resize: true, editor: dateEditor}, {name: "duration", align: "center"}, {name: "add", width: 44} ];editor.save
save仅当您的编辑器需要一次修改任务的多个属性,或者希望它修改不同于任务的对象时,才需要使用该功能。
在这种情况下,您可以保留适当的实现以get_value进行内置验证,但是gantt本身不会尝试将编辑器的值应用于任务,save而是将调用该函数。
之后save被调用时,你需要解释的输入值,并应用变为带有自定义代码甘特。方法完成后,Gantt将调用onSave事件save,但不会为修改后的行调用gantt.updateTask。
笔记!save仅当您map_to:"auto"在编辑器的配置中指定时,才会调用该方法:
var editors = { ... predecessors: {type: "predecessor", map_to: "auto"} };内置的前身编辑器就是此类控件的一个很好的例子。您可以在相关示例中找到其简化的实现。
关产品推荐:
VARCHART XGantt:支持ActiveX、.Net等平台的C#甘特图控件
AnyGantt:构建复杂且内容丰富的甘特图的理想工具
jQuery Gantt Package:基于HTML5 / jQuery的跨平台jQuery Gantt包
phGantt Time Package:对任务和时间的分配管理的甘特图
APS帮助提升企业生产效率,真正实现生产排程可视化呈现与控制,快速有效响应不同场景的生产计划,提高准时交货能力,提高产能和资源利用率
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@cahobeh.cn
文章转载自: