Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace content block

Tags:

draftjs

guys! Please help.

What I want: When starting from a new line a user types an URL and presses Enter I want to remove the block containing the URL and replace it with a custom Entity. Much like the Media example from the docs, but without the Add image button.

What I tried: (just a rough draft)

var mediaBlockRenderer = function(block) {
    if (block.getType() === 'atomic') {
        return {
            component: TestComponent,
            editable: false
        };
    }
    return null;
};

var TestComponent = function() {
    return <div className="test-component">TEST COMPONENT</div>;
};

onChange: function(editorState) {
        var currentKey = editorState.getSelection().getStartKey();
        var content = editorState.getCurrentContent();
        var selection = content.getSelectionBefore();
        var beforeKey = content.getKeyBefore(currentKey);
        var block = content.getBlockForKey(beforeKey);

        if (block && block.getText() === 'test') {
            console.log(block.getText());
            var len = block.getCharacterList().size;

            var newSelection = selection.merge({
                anchorOffset: 0,
                focusOffset: len
            });

            var newContent = Modifier.removeRange(content, newSelection, 'backward');
            editorState = EditorState.push(editorState, newContent, 'insert');
            var key = Entity.create('media', 'IMMUTABLE');
            editorState = AtomicBlockUtils.insertAtomicBlock(
                editorState,
                key,
                ' '
            );
            //editorState = EditorState.forceSelection(editorState, newContent.getSelectionBefore());

        }

        this.setState({
            editorState: editorState
        })
    }

It almost does what I want, but the inserted block can't be deleted by pressing backspace, the cursor just jumps to the top right corner.

My question: What is the recommended way of replacing blocks? How do you remove a block? And why my inserted block just won't get deleted?

Thanks!

like image 871
iliaznk Avatar asked May 16 '16 12:05

iliaznk


1 Answers

I ended up figuring out this by using Modifier.replaceText instead of Modifier.removeRange. What you can do is find the initial index of the URL and last index of the URL (let us call these a and b respectively), and we can do the following:

let newSelection = editorState.getSelection();
newSelection = newSelection.merge({
    anchorOffset: a,
    focusOffset: b
});

let newContent = Modifier.replaceText(editorState.getCurrentContent(), newSelection, "");
let newState = EditorState.push(editorState, newContent, 'insert-characters');

this.setState({ editorState: newState });

You can also define your newSelection however you want, so if you prefer to partition by ContentBlocks you can.

like image 67
Anish Muthali Avatar answered Nov 06 '22 02:11

Anish Muthali