Skip to content
Permalink
Branch: master
Find file Copy path
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
910 lines (754 sloc) 23.6 KB

TOAST UI Grid v4.0 Migration Guide ✈️

Table of Contents

Overview

Lightweight and dependency-free TOAST UI Grid v4.0 has been released recently. New API that enables users to use TOAST UI Grid more extensively in this update, and existing API, including name changes, have been reorganized.

In order to use v4.0, you have migrated your API. Listed are the different API types.

  • Options
  • Methods
  • Custom Events

There are three majors stages in migration: improved features, changes, and removed.

  • Improved Features : A list of API with features that are either new or enhanced.
  • Changes : A list of API with features that have different names or types.
  • Removed : A list of API that have been either removed or discontinued.

There are some warnings concerning installing and using the new version of TOAST UI Grid. Therefore, before starting the migration process, it is recommended that the user reads the warnings carefully.

Installation

The v4.0 can easily be installed using the npm command.

npm install tui-grid@next

The biggest change in the v4.0 is the dependency removal. If the new version is to be loaded on a browser, make sure that the dependencies have been properly removed. (When using date-picker or pagination features, do not remove tui-code-snippet, and proceed normally.)

  • jquery
  • underscore
  • backbone
  • tui-code-snippet

Furthermore, the bundle file including all of dependencies is no longer provided, so pay necessary precautions when using the CDN.

// v3
- dist
    - tui.grid.comb.js
    - tui.grid.full.js
    - tui-grid.js
// v4
- dist
    - tui-grid.js

If the new version is installed, let’s move on to the API migration.

API Migration

Improved Features

Custom Editor & Custom Renderer

In the previous version, there were numerous limitations when implementing a cell customization feature like indirectly using the formatter option. In order to address these problems, v4.0 introduces a Custom Editor and a Custom Renderer. Now, users can freely customize cells to his or her liking.

Custom Editor

TOAST UI Grid provides a diverse range of default editors.

  • Text : <input type="text" />
  • Password : <input type="password" />
  • Checkbox : <input type="checkbox" /> & <label>
  • Radio : <input type="radio" /> & <label>
  • Select : <select> & <options>

While the default editor was created using the editOptions option, in v4.0, the option’s name has been changed to editor. Below is an example of creating the Checkbox editor.

// v3
const grid = new Grid({
  // ...
  columns: [
    {
      name: 'genre',
      editOptions: {
        type: 'checkbox',
        listItems: [
          { text: 'Pop', value: '1' },
          { text: 'Rock', value: '2' },
          { text: 'R&B', value: '3' }
        ]
      }
    }
  ]
});
// v4
const grid = new Grid({
  // ...
  columns: [
    {
      name: 'genre',
      editor: {
        type: 'checkbox',
        options: {
          listItems: [
            { text: 'Pop', value: '1' },
            { text: 'Rock', value: '2' },
            { text: 'R&B', value: '3' }
          ]
        }
      }
    }
  ]
});

TOAST UI Grid’s built-in editor is created by a constructor function of the CellEditor type, and the CellEditor is implemented using the following methods and interfaces. (Reference: Text Editor Constructor Function)

Name Return Type Function Note
getElement HTMLElement Returns an element that corresponds to the Editor Mandatory
getValue string | number | boolean Returns the cell data Mandatory
mounted void Executed after the element returned from getElement has rendered Optional
beforeDestroy void Executed before the element returned from getElement is destroyed Optional

When editors other than the default editor are required, or when the default editor has to be extended in its purpose, use the user defined custom editor constructor function based on the CellEditor interface. The following is an example of using the user defined custom editor constructor function.

class CustomTextEditor {
  constructor(props) {
    const el = document.createElement('input');

    el.type = 'text';
    el.value = String(props.value);

    this.el = el;
  }

  getElement() {
    return this.el;
  }

  getValue() {
    return this.el.value;
  }

  mounted() {
    this.el.select();
  }
}

First of all, declare the constructor function according to the CellEditor interface. Here, the constructor function can take any objects (as props) that can access the properties used in TOAST UI Grid, and such objects can be used to customize the editor in a wide range of styles. The information on object properties are as follows.

(For more detailed information regarding columnInfo property, refer to types.ts.

Name Type
grid Grid
rowKey string | number
value number | boolean
columnInfo ColumnInfo

All there’s left to do is to configure the CustomTextEditor constructor function created above as the option value of the editor.type. The editor.options option can be used to configure properties other than those provided by props.

class CustomTextEditor {
  constructor(props) {
    const options = props.columnInfo.editor.myCustomOptions;
    // ...
  }
  // ...
}

const grid = new Grid({
  // ...
  columns: [
    {
      name: 'genre',
      editor: {
        type: CustomTextEditor,
        options: {
          myCustomOptions: {
            // ...
          }
        }
      }
    }
  ]
});
Custom Renderer

The Custom Renderer is a constructor function that functions in a similar way as the Custom Editor. TOAST UI Grid’s cell contents are created by the constructor function of CellRenderer type, and the CellRenderer is implemented using the following methods and interfaces. (Reference: Default Renderer Constructor Function).

Name Return Type Function Note
getElement HTMLElement Returns an element that corresponds to the cell content Mandatory
mounted void Executed after the element returned from getElement has rendered Optional
render void Executed when a cell data has been changed Mandatory
beforeDestroy void Executed before the element returned from getElement is destoryed Optional
focused string | number | boolean Executed when a cell has been focused on Optional

In the previous versions, the formatter was used to customize the cell contents. However, such usage did not suit the purpose. Therefore, in v4.0, it is recommended to use the user defined Custom Renderer constructor function based on the CellRenderer interface. The following is an example of using the user defined Custom Renderer constructor function.

class SliderRenderer {
  constructor(props) {
    const el = document.createElement('input');
    const { grid, rowKey, columnInfo } = props;

    el.type = 'range';

    el.addEventListener('mousedown', (ev) => {
      ev.stopPropagation();
    });

    el.addEventListener('change', () => {
      grid.setValue(rowKey, columnInfo.name, Number(el.value));
    });

    this.el = el;
    this.render(props);
  }

  getElement() {
    return this.el;
  }

  render(props) {
    this.el.value = String(props.value);
  }
}

The general usage is the same as that of the CellEditor. Declare the constructor function according to the CellRenderer, and objects (as props) that can access the properties used in TOAST UI Grid are used for the customization. The information on the object properties are as follows. (For more detailed information regarding columnInfo property, refer to types.ts).

Name Type
grid Grid
rowKey number | string
columnInfo object
editable boolean
disabled boolean
invalidState 'REQUIRED' | 'TYPE_STRING' | 'TYPE_NUMBER'
formattedValue string
value string | boolean
className string

For the Custom Renderer, use the renderer option that has been newly added to v4.0. Then, configure the SliderRenderer constructor function created above as option value for renderer.type. The renderer.options option can be used to configure properties other than those provided by props.

class SliderRenderer {
  constructor(props) {
    const { min, max } = props.columnInfo.renderer.options;

    el.min = String(min);
    el.max = String(max);

    // ...
  }
  // ...
}

const grid = new Grid({
  columns: [
    // ...
    {
      name: 'score',
      renderer: {
        type: SliderRenderer,
        options: {
          min: 10,
          max: 30
        }
      }
    } 
  ]
});

Data Source

In the previous versions, the Net add-on was used for the purpose of server communication and data synchronization, but since the feature has been implemented, the usability has decreased. In v4.0, the Data Source data type has replaced the Net and has enabled a more convenient implementation of server communication logic.

The following section compares usages of the Net and the Data Source to proceed with the migration using the new feature.

Data Source is an edited form of the Net option object, and uses data option to be configured. Characteristically, the Data Source can assign different method values to each CRUD settings. In the previous version, when using the pagination feature, the perPage option, a lower rank option pagination and Net instance constructor option, was used, but from v4.0, the pageOptions option can be used to configure everything in one go.

// v3
const options = {
  el: $('#data_form'),
  initialRequest: true,
  readDataMethod: 'GET', // deprecated
  perPage: 500, // deprecated
  enableAjaxHistory: true, // deprecated
  withCredentials: false,
  api: {
    readData: './api/read', // changed
    createData: './api/create', // changed
    updateData: './api/update', // changed
    deleteData: './api/delete', // changed
    modifyData: './api/modify', // changed
    downloadExcel: './api/download/excel', // deprecated
    downloadExcelAll: './api/download/excelAll' // deprecated
  }
};

const grid = new Grid({
  // ...
  pagination: true
});

grid.use('Net', options);
// v4
const dataSource = {
  withCredentials: false,
  initialRequest: true,
  api: {
    readData: { url: '/api/read', method: 'GET' },
    createData: { url: '/api/create', method: 'POST' },
    updateData: { url: '/api/update', method: 'PUT' },
    deleteData: { url: '/api/delete', method: 'DELETE' },
    modifyData: { url: '/api/modify', method: 'POST' }
  }
};

const grid = new Grid({
  // ...
  data: dataSource,
  pageOptions: {
    perPage: 500
  }
});

When making a server request through the Data Source, the instance’s request method is called. Furthermore, hasDataParam and updateOriginal properties of the call parameter have been removed, and the default value of checkedOnly property has been changed to false. The updateOriginal option has been replaced by resetData, reloadData, and readData so that when the method is called, the data is refreshed.

The following is a comparison of logic to deal with createData request. With the implementation of Data Source, implementing server communication has been made much easier.

// v3
const net = grid.getAddOn('Net');

net.request('createData', {
  hasDataParam: true, // deprecated
  checkedOnly: true, // changed
  modifiedOnly: true,
  showConfirm: true,
  updateOriginal: true, // deprecated
  withCredentials: false
});
// v4
grid.request('createData', {
  checkedOnly: false,
  modifiedOnly: true,
  showConfirm: true,
  withCredentials: false
});

Changes

Supported Browsers (IE > 9)

Starting from v4.0, the range of supported browsers has been changed to above Internet Explorer 9. While the previous version supported Internet Explorer 8, the low browser occupancy rate and the introduction of new development environments like webpack 4 has contributed to this decision to change the support range.

header Naming

TOAST UI Grid is composed of tables. To suit table’s functionality, the name of the element that corresponds to the header section has been changed to header.

  • Column Option
v3 v4
columns[].title columns[].header
// v3
const grid = new Grid({
  // ...
  columns: [
    {
      name: 'genre',
      title: 'Genre',
      // ...
    }
  ]
});
// v4
const grid = new Grid({
  // ...
  columns: [
    {
      name: 'genre',
      header: 'Genre',
      // ...
    }
  ]
});
  • Row Header Option
v3 v4
rowHeaders[].title rowHeaders[].header
// v3
const grid = new Grid({
  // ...
  rowHeaders: [
    {
      type: 'rowNum',
      title: 'No.',
      // ...
    }
  ]
});
// v4
const grid = new Grid({
  // ...
  rowHeaders: [
    {
      type: 'rowNum',
      header: 'No.',
      // ...
    }
  ]
});
  • Theme Option
v3 v4
cell.head cell.header
cell.selectedHead cell.selectedHeader
cell.rowHead cell.rowHeader
cell.selectedRowHead cell.selectedRowHeader
// v3
const extOptions = {
  cell: {
    head: '#333'
  }
};
Grid.applyTheme('default', extOptions);
// v4
const extOptions = {
  cell: {
    header: '#333'
  }
};
Grid.applyTheme('default', extOptions);
  • Methods
v3 v4
setColumnTitles setColumnHeaders

_extraData

The _extraData was used to configure extra attributes outside of data that corresponds to each columns in previous versions. In order to clarify the functionality, it has been renamed as _attributes, and its lower rank options have been reclassified separately.

  • Data Option
v3 v4
data[]._extraData data[]._attributes
  • Lower Rank Option
v3 v4
_extraData.rowState: 'DISABLED' _attributes.disabled
_extraData.rowState: 'DISABLED_CHECK' _attributes.checkDisabled
_extraData.rowState: 'CHECKED' _attributes.checked
_extraData.treeState: 'EXPAND' _attributes.expanded: true
_extraData.treeState: 'COLLAPSE' _attributes.expanded: false
// v3
const grid = new Grid({
  // ...
  data: [
    {
      name: 'X',
      artist: 'Ed Sheeran',
      _extraData: {
        rowState: 'DISABLED',
        // ...
      }
    }
  ]
});
// v4
const grid = new Grid({
  // ...
  data: [
    {
      name: 'X',
      artist: 'Ed Sheeran',
      _attributes: {
        disabled: true,
        // ...
      }
    }
  ]
});

columns[].editOptions Option

In the process of providing user defined Custom Editors, editOptions option has been changed to editor, and the lower rank options have been changed as well.

  • editOptions.listItemeditor.options.listItem : Used to configure values of Checkbox, Radio, and Select elements, and the definition has changed to be under options.

  • editOptions.useViewMode Removed : As the original useViewMode: false can be implemented using the Custom Renderer, editOptions.useViewMode has been removed for extensibility.

  • formatter: 'listItemText' New Built-In Values : Used to print the values configured in editor.options.listItem option in string format.

// v3
const grid = new Grid({
  // ...
  columns: [
    {
      name: 'genre',
      editOptions: {
        type: 'checkbox',
        listItem: [
          { text: 'Pop', value: '1' },
          { text: 'Rock', value: '2' }
        ],
        useViewMode: true
      }
    }
  ]
});
// v4
const grid = new Grid({
  // ...
  columns: [
    {
      name: 'genre',
      formatter: 'listItemText',
      editor: {
        type: 'checkbox',
        options: {
          listItem: [
            { text: 'Pop', value: '1' },
            { text: 'Rock', value: '2' }
          ]
        }
      }
    }
  ]
});

columns[].relations Option

The column[].relations option is used to work with relation column functionality, and as the lower rank options have changed, pay necessary precautions. When working with relation column, the Select built-in editor is used. The Select List is created using the value returned from the callback function configured in the relations.listItems option, but the type of the parameter that is passed in to the callback function has been changed. Originally, two parameters, value and rowData were passed, but starting from v4.0, the parameters are passed included in the object.

Furthermore, the editOptions option has been changed, so when creating a editor for a related column, use the editor option. Also, make certain that the editor.options.listItems option is initialized with an empty array([]).

// v3
grid.setColumns([
  {
    title: 'col1',
    name: 'col1',
    relations: [
      targetNames: ['col2'],
      listItems(value, rowData) {
        let items;

        if (value === '1') {
          items = [
           { text: 'opt1', value: '1' }
           { text: 'opt2', value: '2' }
          ];
        } else {
          items = [
            { text: 'opt3', value: '3' }
            { text: 'opt4', value: '4' }
          ];
        }

        return items;
     }
  ]
},
{
  title: 'col2',
  name: 'col2',
    editOptions: {
      type: 'select'
    }
  }
]);
// v4
grid.setColumns([
  {
    header: 'col1',
    name: 'col1',
    formatter: 'listItemText',
    editor: {
      type: 'select',
      options: {
        listItems: []
      }
    },
    relations: [
      targetNames: ['col2'],
      listItems({ value }) {
        let items;

        if (value === '1') {
          items = [
            { text: 'opt1', value: '1' }
            { text: 'opt2', value: '2' }
          ];
        } else {
          items = [
            { text: 'opt3', value: '3' }
            { text: 'opt4', value: '4' }
          ]
        }
        return items;
      }
    ]
  },
  {
    header: 'col2',
    name: 'col2',
    formatter: 'listItemText',
    editor: {
      type: 'select',
      options: {
        listItems: []
      }
    }
  }
]);

rowHeaders Option

A change has been made in customizing the row header column. The Custom Renderer is used as is when dealing with regular columns, and the related options have changed like the following.

  • template Removed : Uses the renderer option to customize cell inputs.
  • header Use : Although the values assigned in the template option were used to customize the entire Checkbox, the corresponding option has been removed, and has been changed to use the template literal configured in the header option. (Original template literal – refer to the example below.)
  • type:radio Removed : While in previous version, users could assign row numbers, Checkbox, Radio, to the row header column, the type:radio has been removed to utilize the Custom Renderer.
// v3
const grid = new Grid({
  // ...
  rowHeaders: [
    {
      type: 'checkbox',
      template: (props) => {
        // ...
        return tmpl;
      }
    }
  ]
});
// v4
class SingleCheckRenderer {
  // ...
}

const grid = new Grid({
  // ...
  rowHeaders: [
    {
      type: 'checkbox',
      header: `
        <label for="all-checkbox" class="checkbox">
          <input type="checkbox" id="all-checkbox" class="hidden-input" name="_checked" />
          <span class="custom-input"></span>
        </label>
      `,
      renderer: SingleCheckRenderer
    }
  ]
});

Tree Events

Event names and event objects of handler functions have been changed.

v3 v4
expanded expand
collapsed collapse
// v3
grid.on('expanded', (rowKey, descendantRowKeys) => {
  console.log(rowKey, descendantRowKeys);
});
// v4
grid.on('expand', (ev) => {
  const rowKey = ev.rowKey;
  const descendantRowKeys = grid.getDescendantRows();

  console.log(rowKey, descendantRowKeys);
});

Method Names

Methods with unclear or incorrect names have been renamed.

v3 v4
getRows getData
setData resetData
unSort unsort
selection setSelectionRange
enableCheck enableRowCheck
disableCheck disableRowCheck
focusIn startEditing
focusInAt startEditingAt
getAncestors getAncestorRows
getDescendants getDescendantRows
getParent getParentRow
getChildren getChildRows

Removed

setData

setData method, previously used to configure data has been removed in the process of renaming it as resetData. Starting from v4.0, use resetData to call and configure data.

// v4
grid.resetData([ ... ]);

Net

With the new support for DataSource, API related to Net has been removed.

  • use
  • getAddOn
// v3
const grid = new Grid({
  // ...
  pagination: true
});

grid.use('Net', {
  // ...
});

const net = grid.getAddOn('Net'); // deprecated
net.request('createData');

columns[].prefix / columns[].postfix Option

columns[].prefix and columns[].postfix were provided as a mean to customize cell data, but starting from v4.0, these options have been removed since Custom Renderers can be used for customization.

// v3
const grid = new Grid({
  // ...
  columns: [
    {
      name: 'genre',
      formatter: (value) => {
        return `<a href="#">${value}</a>`;
      },
      prefix: 'pre text', // deprecated
      postfix: 'post text' // deprecated
    }
  ]
});

columns[].component Option

The columns[].component option, used to configure external components, has been removed. As the Date Picker functionality has been moved from the component to the Custom Editor, observe the following steps to implement the Date Picker.

// v3
const grid = new Grid({
  // ...
  columns: [
    {
      name: 'release',
      editOptions: {
        type: 'text'
      },
      component: {
        name: 'datePicker',
        options: {
          date: new Date(2017, 3, 10)
          format: 'yyyy/MM/dd'
        }
      }
    }
  ]
});
// v4
const grid = new Grid({
  // ...
  columns: [
    {
      name: 'release',
      editor: {
        type: 'datePicker',
        options: {
          format: 'yyyy/MM/dd',
        }
      }
    }
  ]
});

toJSON Parameter

The parameter value to return JSON string at the point of a method call has been removed.

  • getCheckedRowKeys
  • getCheckedRows
  • getRow
  • getRowAt
  • getData
// v3
/**
 * Returns a list of the checked rows.
 * @param {boolean} [useJson=false] - If set to true, return value will be converted to JSON string.
 * @returns {Array|string} - A list of the checked rows. (or JSON string of the list)
 */
getCheckedRows: function(useJson) { ... }
// v4
/**
 * Returns a list of the checked rows.
 * @param {boolean} [useJson=false] - If set to true, return value will be converted to JSON string.
 */
public getCheckedRowKeys(): RowKey[] { ... }

Tree Event

The Tree events have been removed as they can be substituted by expand and collapse events.

  • expandedAll
  • collapsedAll
You can’t perform that action at this time.