Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Spec] Cell Renderer Interface #388

Closed
dongwoo-kim opened this issue Jun 1, 2019 · 0 comments
Closed

[Spec] Cell Renderer Interface #388

dongwoo-kim opened this issue Jun 1, 2019 · 0 comments
Labels
Milestone

Comments

@dongwoo-kim
Copy link

dongwoo-kim commented Jun 1, 2019

Cell Renderer

Intro

The cell renderer is more powerful abstraction than formatter option and gives more control of cell rendering behavior to end users. TOAST UI Grid 4 will support official Cell Renderer interface so that users can customize the cell UI to meet their own requirements.

CellRenderer Interface

The CellRenderer should be the constructor function. The TOAST UI Grid will create instances of it using new keyword internally. We recommend using class keyword, but in case class keyword is not available, function and prototype can be used instead.

The CellRenderer should implement the interface below.

interface CellRenderer {
  getElement(): HTMLElement;
  mounted?(parent: HTMLElement): void;
  changed?(props: CellRendererProps): void;
  focused?(): void;
}

getElement()

This method should return the root DOM element of the cell contents. When the cell (TD element) is mounted, the returned element will be appended as a child elemement.

mounted()

This method is an optional, and can be used to initialize the contents of the cell. This method is invoked right after the root element returned by getElement() is attached to the DOM.

changed()

This method is an optional, and can be used to sychronize the rendered contents and the value of the cell. This method is invoked whenever the value of the cell is changed.

focused()

This method is an optional, and can be used to add some behavior when the focus is set on the cell. This method is invoked whenever the focus is changed and set on the cell.

Example

The following is the source code of the default cell renderer.

class DefaultRenderer  {
  public constructor(props) {
    const el = document.createElement('div');
    const { ellipsis, whiteSpace } = props.columnInfo;

    el.className = 'tui-grid-cell-content';
    if (ellipsis) {
      el.style.textOverflow = 'ellipsis';
    }
    if (whiteSpace) {
      el.style.whiteSpace = whiteSpace;
    }

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

  getElement() {
    return this.el;
  }

  changed(props) {
    this.el.innerHTML = props.formattedValue;
  }
}

The constructor function is invoked when the cell element (TD) is mounted to the DOM. It's common to store the root element as a instance member, so that it can be used later in other methods such as getElement() and changed().

The constructor function receives props object which contains useful information for customizing contents of the cell. The interface of the props object is like below.

export type CellRendererProps {
  grid: Grid;
  rowKey: RowKey;
  columnInfo: ColumnInfo;
  editable: boolean;
  disabled: boolean;
  invalidState: '' | 'REQUIRED' | 'TYPE_STRING' | 'TYPE_NUMBER';
  formattedValue: string;
  prefix: string;
  postfix: string;
  value: number | string | boolean;
  className: string;
};

The grid property is an instance of TOAST UI Grid itself. This can be useful if you want to get specific data or manipulate the grid data manually.

The columnInfo property contains the all information of the column in which the target cell is contained. The inerface of the ColumnInfo is like below.

export interface ColumnInfo {
  readonly name: string;
  header: string;
  minWidth: number;
  editor?: CellEditorClass;
  editorOptions?: Dictionary<any>;
  renderer: CellRendererClass;
  rendererOptions?: Dictionary<any>;
  copyOptions?: ClipboardCopyOptions;
  hidden: boolean;
  formatter?: Formatter;
  prefix?: Formatter;
  postfix?: Formatter;
  baseWidth: number;
  resizable: boolean;
  fixedWidth: boolean;
  relationMap?: Dictionary<Relations>;
  related?: boolean;
  align?: 'left' | 'center' | 'right';
  valign?: 'top' | 'middle' | 'bottom';
  whiteSpace?: 'pre' | 'normal' | 'norwap' | 'pre-wrap' | 'pre-line';
  ellipsis?: boolean;
  escapeHTML?: boolean;
  defaultValue?: CellValue;
  sortable?: boolean;
  validation?: Validation;
  onBeforeChange?: Function;
  onAfterChange?: Function;
}

More information of every properties will be specified in the official document. Before that, please refer to the source code of the store/types.ts file.

Usage

You don't need to specify the Cell Renderer if you want to use the default renderer. But if you want to use your own Renderer, the constructor function should be set to the renderer property of the columns options.

class MyCustomRenderer {
  constructor(props) {
    const options = props.columnInfo.rendererOptions.myCustomOptions;
    // ...
  }
  // ...
}

const grid = new Grid({
  columns: [
    // ...
    {
      name: 'genre',
      renderer: MyCustomRenderer,
      rendererOptions: {
        myCustomOptions: {
          // ...
        }
      }
    } 
  ]
});

Note that you can define your own rendererOptions and use it in the constructor function using props.columnInfo.rendererOptions.

Feedback Welcome!

The TOAST UI Grid 4 is still in progress and plainning to release the official version by middle of June. If you are a passionate user of the TOAST UI Grid, please give the alpha version of V4 a try and give us some feedback about the spec. Thanks!!

@dongwoo-kim dongwoo-kim pinned this issue Jun 1, 2019
@dongwoo-kim dongwoo-kim added this to the 4.0.0 milestone Jun 1, 2019
@js87zz js87zz unpinned this issue Jun 24, 2019
@js87zz js87zz closed this as completed Jun 25, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants