TaskEditor

Provides a UI to edit tasks in a popup dialog. It is implemented as a Tab Panel with several preconfigured built-in tabs. Although the default configuration may be adequate in many cases, the Task Editor is easily configurable.

This demo shows how to use TaskEditor as a standalone widget:

Task editor
//<code-header>
fiddle.title = 'Task editor';
//</code-header>
const project = new ProjectModel({
    startDate : new Date(2020, 0, 1),

    events : [
        {
            id       : 1,
            name     : 'Write docs',
            expanded : true,
            children : [
                { id : 2, name : 'Proof-read docs', startDate : '2020-01-02', endDate : '2020-01-05', effort : 0 },
                { id : 3, name : 'Release docs', startDate : '2020-01-09', endDate : '2020-01-10', effort : 0 }
            ]
        }
    ],

    dependencies : [
        { id : 1, fromEvent : 2, toEvent : 3 }
    ]
});

const taskEditor = new TaskEditor({
    rootElement : document.body,
    listeners   : {
        save : () => taskEditor.hide()
    }
});

const button = new Button({
    appendTo : targetElement,
    text     : 'Show TaskEditor',
    onClick  : () => {
        taskEditor.loadEvent(project.eventStore.getById(2));

        taskEditor.showBy({
            target : button.element,
            align  : 'l-r',
            offset : 5
        });
    }
});

To hide built-in tabs or to add custom tabs, or to append widgets to any of the built-in tabs use the items config.

The Task editor contains tabs by default. Each tab is a container with built-in widgets: text fields, grids, etc.

Tab ref Text Weight Description
generalTab General 100 Name, start/end dates, duration, percent done, effort
predecessorsTab Predecessors 200 Grid with incoming dependencies
successorsTab Successors 300 Grid with outgoing dependencies
resourcesTab Resources 400 Grid with assigned resources
advancedTab Advanced 500 Assigned calendar, scheduling mode, constraints, etc
notesTab Notes 600 Text area to add notes to the selected task

Task editor customization example

This example shows a custom Task Editor configuration. The built-in "Notes" tab is hidden, a custom "Files" tab is added, the "General" tab is renamed to "Common" and "Custom" field is appended to it. Double-click on a task bar to start editing:

Custom task edit
//<code-header>
fiddle.title = 'Custom task edit';
//</code-header>
const project = new ProjectModel({
    startDate : new Date(2017, 0, 1),

    tasks : [
        {
            id       : 1,
            name     : 'Write docs',
            expanded : true,
            custom   : 'Parent custom field value',
            children : [
                // 'custom' field is auto exposed to Task model, then its name is used in TaskEditor to get/set values
                {
                    id        : 2,
                    name      : 'Proof-read docs',
                    startDate : '2017-01-02',
                    endDate   : '2017-01-05',
                    custom    : 'Proof-read custom value'
                },
                {
                    id        : 3,
                    name      : 'Release docs',
                    startDate : '2017-01-09',
                    endDate   : '2017-01-10',
                    custom    : 'Release custom value'
                }
            ]
        }
    ],

    dependencies : [
        { id : 1, fromTask : 2, toTask : 3 }
    ]
});

// May be registered in case this example is run again
if (!Widget.factoryable.registry.custom_filestab) {
    // Custom FilesTab class (the last item of tabsConfig)
    class FilesTab extends Grid {

        // Factoryable type name
        static get type() {
            return 'custom_filestab';
        }

        static configurable = {
            title    : 'Files',
            defaults : {
                labelWidth : 200
            },
            columns : [{
                text     : 'Files attached to task',
                field    : 'name',
                type     : 'template',
                template : data => `<i class="fa fa-fw fa-${data.record.data.icon}"></i>${data.record.data.name}`
            }]
        };

        loadEvent(eventRecord) {
            let files = [];

            // prepare dummy files data
            switch (eventRecord.data.id) {
                case 1:
                    files = [
                        { id : 1, name : 'Image1.png', icon : 'image' },
                        { id : 2, name : 'Chart2.pdf', icon : 'chart-pie' },
                        { id : 3, name : 'Spreadsheet3.pdf', icon : 'file-excel' },
                        { id : 4, name : 'Document4.pdf', icon : 'file-word' },
                        { id : 5, name : 'Report5.pdf', icon : 'user-chart' }
                    ];
                    break;
                case 2:
                    files = [
                        { id : 1, name : 'Chart11.pdf', icon : 'chart-pie' },
                        { id : 2, name : 'Spreadsheet13.pdf', icon : 'file-excel' },
                        { id : 3, name : 'Document14.pdf', icon : 'file-word' }
                    ];
                    break;
                case 3:
                    files = [
                        { id : 1, name : 'Image21.png', icon : 'image' },
                        { id : 2, name : 'Spreadsheet23.pdf', icon : 'file-excel' },
                        { id : 3, name : 'Document24.pdf', icon : 'file-word' },
                        { id : 4, name : 'Report25.pdf', icon : 'user-chart' }
                    ];
                    break;
            } // eo switch

            this.store.data = files;
        } // eo function loadEvent
    } // eo class FilesTab

    // register 'filestab' type with its Factory
    FilesTab.initClass();
}

const gantt = new Gantt({
    appendTo : targetElement,
    flex     : '1 0 100%',
    height   : 200,

    project, // Gantt needs project to get schedule data from
    startDate : new Date(2016, 11, 31),
    endDate   : new Date(2017, 0, 11),

    columns : [
        { type : 'name', field : 'name', text : 'Name' }
    ],

    features : {
        taskEdit : {
            items : {
                generalTab : {
                    // Change title of General tab
                    title : 'Common',
                    items : {
                        // Add new field
                        newCustomField : {
                            type   : 'textfield',
                            weight : 710,
                            label  : 'Custom (New Field)',
                            name   : 'custom' // Name of the field matches data field name, so value is loaded/saved automatically
                        }
                    }
                },
                // Remove Notes tab
                notesTab : false,
                // Add custom Files tab to the second position
                filesTab : {
                    type   : 'custom_filestab',
                    weight : 110
                }
            },
            editorConfig : {
                // Custom height of the Task Editor
                height : '35em'
            }
        } // eo taskEdit
    } // eo features
});

Custom fields in the Task Editor work only if the field is explicitly defined in the Task model. When defined, the field can be added, updated, and stored in the TaskStore, even if it is not present in the initial task data. Bryntum extracts fields only from the first task record when no definitions are provided, which can lead to inconsistent behavior. Always define custom fields in the Task model to ensure predictable and reliable functionality.

export default class CustomTaskModel extends TaskModel {
 static fields = [
     { name: 'custom', type: 'string' }
 ];
}

const project = new ProjectModel({
 taskModelClass : CustomTaskModel,
})

Configs

124

Common

listenersEvents

Accessibility

ariaLabelWidget
keyMapKeyMap

Content

bbarPanel
defaultsContainer
footerPanel
headerPanel
itemsContainer
lazyItemsContainer
namedItemsContainer
stripsPanel
tbarPanel
textContentContainer
toolsPanel

CSS

bodyClsPanel
borderContainer
clsWidget
colorWidget
htmlClsWidget
itemClsContainer
styleWidget
uiPanel

DOM

adoptWidget
appendToWidget
contentWidget
datasetWidget
htmlWidget
idWidget
tagWidget

Float & align

alignWidget
anchorWidget
centeredWidget
floatingWidget
xWidget
yWidget

Layout

alignSelfWidget
dockWidget
flexWidget
heightWidget
hiddenWidget
hideWhenEmptyContainer
layoutContainer
layoutStyleContainer
marginWidget
maxHeightWidget
maxWidthWidget
minHeightWidget
minWidthWidget
textAlignWidget
weightWidget
widthWidget

misc

tabBarItemsContainer

Misc

dataFieldWidget
disabledWidget
iconPanel
localeClassLocalizable
localizableLocalizable
maskedWidget
ownerWidget
readOnlyWidget
refWidget
rippleWidget
tabWidget
titlePanel
tooltipWidget

Other

calculateMaskTaskEditorBase
calculateMaskDelayTaskEditorBase
columnWidget
defaultFocusContainer
dependencyIdFieldTaskEditorBase
drawerPanel
labelPositionContainer
modalPopup
renditionContainer
resizableResizable
rtlRTL
spanWidget

Record

recordContainer

Scrolling

State

stateIdState

Properties

101

Class hierarchy

isSchedulerTaskEditor: Booleanreadonly

Identifies an object as an instance of SchedulerTaskEditor class, or subclass thereof

isTaskEditor: Boolean= truereadonly
Identifies an object as an instance of TaskEditor class, or subclass thereof.
isTaskEditor: Boolean= truereadonlystatic
Identifies an object as an instance of TaskEditor class, or subclass thereof.
isContainerContainer
isDelayableDelayable
isEventsEvents
isGanttTaskEditorGanttTaskEditor
isKeyMapKeyMap
isLocalizableLocalizable
isPanelPanel
isPopupPopup
isResizableResizable
isStateState
isTaskEditorBaseTaskEditorBase
isToolableToolable
isWidgetWidget

Accessibility

keyMapKeyMap

Content

bbarPanel
tbarPanel

CSS

clsWidget

DOM

appendToWidget
contentWidget
datasetWidget
elementWidget
htmlWidget
idWidget
styleWidget

Float & align

xWidget
yWidget

Layout

alignSelfWidget
flexWidget
heightWidget
layoutContainer
layoutStyleContainer
marginWidget
maxHeightWidget
maxWidthWidget
minHeightWidget
minWidthWidget
widthWidget

Lifecycle

configBase

Misc

cellInfoWidget
disabledWidget
localeHelperLocalizable
localeManagerLocalizable
readOnlyWidget
refWidget
tabWidget
titlePanel
tooltipWidget

Other

$namestaticWidget
columnWidget
firstItemContainer
hasChangesContainer
isValidContainer
itemsContainer
labelPositionContainer
lastItemContainer
renditionContainer
resizableResizable
rtlRTL
spanWidget
toolsPanel
typestaticWidget
valuesContainer

Record

recordContainer

State

stateState

Visibility

hiddenWidget
isVisibleWidget

Widget hierarchy

ownerWidget
parentWidget
widgetMapContainer

Functions

76

Configuration

applyDefaultsstaticBase

Events

Float & align

alignToWidget
setXYWidget
showByWidget
toFrontWidget

Lifecycle

createstaticWidget
destroystaticBase
initClassstaticWidget

Misc

attachTooltipstaticWidget
fromElementstaticWidget
fromSelectorstaticWidget
getByIdstaticWidget
isOfTypeNamestaticBase
mixinstaticBase
optionalLstaticLocalizable

Other

addContainer
closePopup
composeWidget
createOnFrameDelayable
disableWidget
enableWidget
focusWidget
getAtContainer
getWidgetByIdContainer
insertContainer
LstaticLocalizable
loadEventTaskEditorBase
maskWidget
onEvents
recomposeWidget
relayAllEvents
removeContainer
removeAllContainer
resetValuesContainer
setValuesContainer
triggerEvents
unEvents
unmaskWidget

State

Visibility

hideWidget
showWidget

Widget hierarchy

closestWidget
containsWidget
ownsWidget
queryWidget
queryAllWidget
upWidget

Events

22

Event handlers

22

Typedefs

7

CSS variables

64