How to add a link? I know how to add link to selection
const contentState = editorState.getCurrentContent();
const contentStateWithEntity = contentState.createEntity(
'LINK',
'MUTABLE',
{url: urlValue}
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
const newEditorState = EditorState.set(editorState, { currentContent: contentStateWithEntity });
this.setState({
editorState: RichUtils.toggleLink(
newEditorState,
newEditorState.getSelection(),
entityKey
)}
We get selection newEditorState.getSelection()
and add link.
But how to add link without selection? Just add new a
tag with text if text is not selected? It doesn't add anything if I doesn't select any text.
My really concise solution. With cool annotation
insertLink = (type, data, text) => {
const editorState = this.state.editorState;
const contentState = editorState.getCurrentContent();
const selection = editorState.getSelection();
const textWithSpace = text.concat(' ');
// create new content with text
const newContent = Modifier.insertText(
contentState,
selection,
textWithSpace,
);
// create new link entity
const newContentWithEntity = newContent.createEntity(
type,
'MUTABLE',
data,
false,
);
const entityKey = newContentWithEntity.getLastCreatedEntityKey();
// create new selection with the inserted text
const anchorOffset = selection.getAnchorOffset();
const newSelection = new SelectionState({
anchorKey: selection.getAnchorKey(),
anchorOffset,
focusKey: selection.getAnchorKey(),
focusOffset: anchorOffset + text.length,
});
// and aply link entity to the inserted text
const newContentWithLink = Modifier.applyEntity(
newContentWithEntity,
newSelection,
entityKey,
);
// create new state with link text
const withLinkText = EditorState.push(
editorState,
newContentWithLink,
'insert-characters',
);
// now lets add cursor right after the inserted link
const withProperCursor = EditorState.forceSelection(
withLinkText,
newContent.getSelectionAfter(),
);
// update the editor with all changes
this.setState({editorState: withProperCursor });
};
You can do any operations with the editor state without the component updating. So you can add a text that you need, after that programmatically set selection on this text and finally create a link and update your component.
Look at this working example - https://jsfiddle.net/levsha/2op5cyxm/ Here I add a link after a button click.
handleAddLink = () => {
const { editorState } = this.state;
const selectionState = editorState.getSelection();
const contentState = editorState.getCurrentContent();
const currentBlock = contentState.getBlockForKey(selectionState.getStartKey());
const currentBlockKey = currentBlock.getKey();
const blockMap = contentState.getBlockMap();
const blocksBefore = blockMap.toSeq().takeUntil((v) => (v === currentBlock));
const blocksAfter = blockMap.toSeq().skipUntil((v) => (v === currentBlock)).rest();
const newBlockKey = genKey();
// add new ContentBlock to editor state with appropriate text
const newBlock = new ContentBlock({
key: newBlockKey,
type: 'unstyled',
text: linkText,
characterList: new List(Repeat(CharacterMetadata.create(), linkText.length)),
});
const newBlockMap = blocksBefore.concat(
[[currentBlockKey, currentBlock], [newBlockKey, newBlock]],
blocksAfter
).toOrderedMap();
const selection = editorState.getSelection();
const newContent = contentState.merge({
blockMap: newBlockMap,
selectionBefore: selection,
selectionAfter: selection.merge({
anchorKey: newBlockKey,
anchorOffset: 0,
focusKey: newBlockKey,
focusOffset: 0,
isBackward: false,
}),
});
let newEditorState = EditorState.push(editorState, newContent, 'split-block');
// programmatically apply selection on this text
const newSelection = new SelectionState({
anchorKey: newBlockKey,
anchorOffset: 0,
focusKey: newBlockKey,
focusOffset: linkText.length
});
newEditorState = EditorState.forceSelection(newEditorState, newSelection);
// create link entity
const newContentState = newEditorState.getCurrentContent();
const contentStateWithEntity = newContentState.createEntity(
'LINK',
'IMMUTABLE',
{ url: linkUrl }
);
const entityKey = contentStateWithEntity.getLastCreatedEntityKey();
newEditorState = EditorState.set(newEditorState, { currentContent: contentStateWithEntity });
newEditorState = RichUtils.toggleLink(newEditorState, newEditorState.getSelection(), entityKey);
// reset selection
newSelection = new SelectionState({
anchorKey: newBlockKey,
anchorOffset: linkText.length,
focusKey: newBlockKey,
focusOffset: linkText.length
});
newEditorState = EditorState.forceSelection(newEditorState, newSelection);
// update our component
this._handleChange(newEditorState);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With