Draft-js: How to create action for add custom tag or custom component to editor?

Created on 8 Jun 2016  路  8Comments  路  Source: facebook/draft-js

The docs little bit confused

For example. I want to add list of checkboxes / inputs / selects.

question

Most helpful comment

I initially thought I could use any custom key for a ContentBlock's type but this does not appear to be the case. I get an error like:

nullthrows.js?2b62:18 Uncaught Error: Got unexpected null or undefined

From my understanding so far, you need to register any custom block in Draft's block render map so it understands how to handle and map to it. Draft stores a default set of block render mappings in DefaultDraftBlockRenderMap. You can extend the latter with your custom block (as documented here) by using the Editor's blockRenderMap.

See the following example:

import Immutable from 'immutable';
import {DefaultDraftBlockRenderMap} from 'draft-js';

const blockRenderMap = Immutable.Map({
  'section': {
    element: 'section'
  }
});

// Include 'paragraph' as a valid block and updated the unstyled element but
// keep support for other draft default block types
const extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(blockRenderMap);

class RichEditor extends React.Component {
  render() {
    return (
      <Editor
        ...
        blockRenderMap={extendedBlockRenderMap}
      />
    );
  }
}

I hope the above gives you some clues to continue further. I am still trying to get my custom block to work, but progressed so far. Would be great if someone can share a complete example once done.

All 8 comments

should I use AtomicBlockUtils or RichUtils ?

AtomicBlockUtils currently only provides a method to insert a new block. You can use this if you wish to have an atomic block. RichUtils contains a number of other convenience methods for supporting rich text behavior. You do not have to use either utility -- they are just made available because they are common use cases.

To support checkboxes, inputs, and selects, you will want to use custom block components. Using form inputs within the editor may not work as you expect, though, so you may wish to follow the TeX example to provide editability on some trigger action while setting the editor to be readOnly.

You may be able to get more help with more details about the issues you are encountering and the features you are aiming to build.

Thanks. I'll try to create something :)

@hellendag
Is it possible to change key 'atomic' to some custom key ?

this._blockRenderer = (block) => {
      if (block.getType() === 'atomic') {
        return {
          component: TeXBlock,
          editable: false,
          props: {
            onStartEdit: (blockKey) => {
              var {liveTeXEdits} = this.state;
              this.setState({liveTeXEdits: liveTeXEdits.set(blockKey, true)});
            },
            onFinishEdit: (blockKey) => {
              var {liveTeXEdits} = this.state;
              this.setState({liveTeXEdits: liveTeXEdits.remove(blockKey)});
            },
            onRemove: (blockKey) => this._removeTeX(blockKey),
          },
        };
      }
      return null;
    };
export function insertTeXBlock(editorState) {
  const nextFormula = count++ % examples.length;
  const entityKey = Entity.create(
    'TOKEN',
    'IMMUTABLE',
    {content: examples[nextFormula]}
  );

  return AtomicBlockUtils.insertAtomicBlock(editorState, entityKey, ' ');
}

I initially thought I could use any custom key for a ContentBlock's type but this does not appear to be the case. I get an error like:

nullthrows.js?2b62:18 Uncaught Error: Got unexpected null or undefined

My custom blockRendererFn is being called with the correct block, but when I try return my component I just get that error.

I initially thought I could use any custom key for a ContentBlock's type but this does not appear to be the case. I get an error like:

nullthrows.js?2b62:18 Uncaught Error: Got unexpected null or undefined

From my understanding so far, you need to register any custom block in Draft's block render map so it understands how to handle and map to it. Draft stores a default set of block render mappings in DefaultDraftBlockRenderMap. You can extend the latter with your custom block (as documented here) by using the Editor's blockRenderMap.

See the following example:

import Immutable from 'immutable';
import {DefaultDraftBlockRenderMap} from 'draft-js';

const blockRenderMap = Immutable.Map({
  'section': {
    element: 'section'
  }
});

// Include 'paragraph' as a valid block and updated the unstyled element but
// keep support for other draft default block types
const extendedBlockRenderMap = DefaultDraftBlockRenderMap.merge(blockRenderMap);

class RichEditor extends React.Component {
  render() {
    return (
      <Editor
        ...
        blockRenderMap={extendedBlockRenderMap}
      />
    );
  }
}

I hope the above gives you some clues to continue further. I am still trying to get my custom block to work, but progressed so far. Would be great if someone can share a complete example once done.

Also ran into this error. Thank you @hadynz for pointing me in the right direction. It seems that #372 addresses this issue and was accepted, making this a only temporary necessity.

wetert\

  1. sdfgfgh dfghfg dfghsdfg
  2. sdfg
  3. sdfg

  4. dfghdfghdfg
    dfdfgh

  5. 1.
  • [ ] testdgfhfdgh
Was this page helpful?
0 / 5 - 0 ratings