New to KendoReact? Start a free 30-day trial

Inline

The KendoReact TreeList enables you to create, update, and delete data records inline.

Basic Concepts

The edit mode of the TreeList rows is based on the value of the editField property.

Example
View Source
Edit In Stackblitz  
Change Theme:

Setup

  1. Set the field which will indicate the editable data items by using the editField property. This field is part of the temporary data items which are used during editing.

        <TreeList
            editField="inEdit"
  2. Configure the command column by defining the command buttons inside the TreeListCell component. To render the command cell, use a Higher-Order Component which has to receive all functions that will be executed from the command buttons and the value of the TreeList editField property.

        CommandCell = MyCommandCell(this.enterEdit, this.remove, this.save, this.cancel, this.addChild, 'inEdit');
        export default function MyCommandCell(enterEdit, remove, save, cancel, addChild, editField) {
            return class extends React.Component {
                render() {
                    const { dataItem } = this.props;
                    return dataItem[editField]
                        ? (
                            <td>
                                <button
                                    className="k-button"
                                    onClick={(e) => save(dataItem)}>
                                    {dataItem.isNew
                                        ? 'Add'
                                        : 'Update'}
                                </button>
                                <button
                                    className="k-button"
                                    onClick={(e) => cancel(dataItem)}>{dataItem.isNew
                                        ? 'Discard'
                                        : 'Cancel'}
                                </button>
                            </td>
                        ) : (
                            <td>
                                <button
                                    className="k-button"
                                    onClick={(e) => addChild(dataItem)}>
                                    Add Child
                                </button>
                                <button
                                    className="k-button"
                                    onClick={(e) => enterEdit(dataItem)}>
                                    Edit
                                </button>
                                <button
                                    className="k-button"
                                    onClick={(e) => remove(dataItem)}>
                                    Remove
                                </button>
                            </td>
                        );
                }
            }
        }
  3. Set the editCell and cell properties per column.

        <TreeList
            columns={[
                { editCell: TreeListTextEditor, ... },
                { editCell: TreeListTextEditor, ... },
                { editCell: TreeListBooleanEditor, ... },
                { cell: this.CommandCell, ... }
            ]}
  4. Define a function for the onItemChange event which will handle any input changes during editing. Inside the event, all relevant data, such as the edited data item, the newly entered value, or the edited field will be available as onItemChange parameters.

         <TreeList onItemChange={this.onItemChange}>
        onItemChange = (event) => {
            this.setState({
                data: mapTree(
                    this.state.data,
                    subItemsField,
                    item => item.id === event.dataItem.id ?
                        extendDataItem(item, subItemsField, { [event.field]: event.value }) : item
                )
            });
        }
  5. Define the functions which will set the item in edit mode and create a new item in edit mode. You can call these functions from the command buttons in the command cell.

        enterEdit = (dataItem) => {
            this.setState({
                inEdit: [ ...this.state.inEdit, extendDataItem(dataItem, subItemsField) ]
            });
        }
        addRecord = () => {
            const newRecord = this.createNewItem();
            this.setState({
                data: [ newRecord, ...this.state.data ],
                inEdit: [ ...this.state.inEdit, { ...newRecord } ]
            });
        }
  6. Define the functions which will handle the save, cancel, remove, and addChild actions. You can call these functions from the command buttons, the toolbar template, or a button which is outside of the TreeList.

        save = (dataItem) => {
            const { isNew, inEdit, ...itemToSave } = dataItem;
            this.setState({
                data: mapTree(this.state.data, subItemsField, item => item.id === itemToSave.id ? itemToSave : item),
                inEdit: this.state.inEdit.filter(i => i.id !== itemToSave.id)
            });
        }
        cancel = (editedItem) => {
            const { inEdit, data } = this.state;
            if (editedItem.isNew) {
                return this.remove(editedItem);
            }
    
            this.setState({
                data: mapTree(data, subItemsField,
                    item => item.id === editedItem.id ? inEdit.find(i => i.id === item.id) : item),
                inEdit: inEdit.filter(i => i.id !== editedItem.id)
            });
        }
        remove = (dataItem) => {
            this.setState({
                data: removeItems(this.state.data, subItemsField, i => i.id === dataItem.id),
                inEdit: this.state.inEdit.filter(i => i.id !== dataItem.id)
            });
        }
        addChild = (dataItem) => {
            const newRecord = this.createNewItem();
    
            this.setState({
                inEdit: [ ...this.state.inEdit, newRecord ],
                expanded: [ ...this.state.expanded, dataItem.id ],
                data: modifySubItems(
                    this.state.data,
                    subItemsField,
                    item => item.id === dataItem.id,
                    subItems => [ newRecord, ...subItems ]
                )
            });
        }

In this article

Not finding the help you need?