Replace content block
Asked Answered
U

1

11

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!

Unhandled answered 16/5, 2016 at 12:37 Comment(2)
Also interested in finding an answer to this question, having the same problem. I assume there's some extra magic that needs to be done apart from just EditorState.push, but not sure what it is.Invert
have you solved your issue?Adaxial
B
1

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.

Bourbon answered 4/6, 2020 at 18:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.