Как программно вставить текст в форматированное текстовое поле черновика js, сохраняя при этом текущий встроенный стиль?

#javascript #reactjs #draftjs

Вопрос:

Когда я нажимаю на кнопку с определенным символом, я бы хотел, чтобы он помещал символ в текстовое поле.

Для этого я использую функцию для вставки текста:

 insertText(characterToInsert) {
    let editorState = this.state.editorState;

    const currentContent = editorState.getCurrentContent(),
        currentSelection = editorState.getSelection();

    let newContent = Modifier.replaceText(
        currentContent,
        currentSelection,
        characterToInsert
    );

    return EditorState.push(editorState, newContent, 'insert-characters');
}
 

Я бы хотел, чтобы там был текст подстрочного индекса, когда включен встроенный стиль подстрочного индекса.

Я пытался сделать что-то вроде

 if (this.isSubscriptOn()) {
    newContent = Modifier.applyInlineStyle(newContent, currentSelection, 'SUBSCRIPT');
}
 

однако я не знаю, как изменить второй аргумент, чтобы выбор был нацелен на вновь размещенные символы.

Есть ли лучший способ подойти к этому?

Ответ №1:

Первым шагом является использование applyInlineStyle: function (contentState: ContentState, selectionState: SelectionState, inlineStyle: string) функции статического Modifier класса. Как вы можете видеть — это требует выбора области, к которой мы хотим применить наш стиль. Мы создадим такой стиль, используя set метод из immutable.js :

 const textToInsertSelection = currentSelection.set('focusOffset', currentSelection.getFocusOffset()   textToInsert.length);
 

Затем мы получим OrderedSet текущие встроенные стили и применим каждый из них к упомянутому выбору:

 let inlineStyles = editorState.getCurrentInlineStyle();
inlineStyles.forEach(inLineStyle => newContent = Modifier.applyInlineStyle(newContent, textToInsertSelection, inLineStyle));
 

Если мы остановимся прямо здесь, текст будет помещен в поле ввода при выделении (вокруг него появится синий прямоугольник). Чтобы избежать такого поведения, давайте перенесем выделение в конец вставленного текста:

 newState = EditorState.forceSelection(newState, textToInsertSelection.set('anchorOffset', textToInsertSelection.getAnchorOffset()   textToInsert.length));
 

Вся функция выглядит следующим образом:

 insertText(textToInsert) {
    let editorState = this.state.editorState;

    const currentContent = editorState.getCurrentContent();
    const currentSelection = editorState.getSelection();

    let newContent = Modifier.replaceText(
        currentContent,
        currentSelection,
        textToInsert
    );

    const textToInsertSelection = currentSelection.set('focusOffset', currentSelection.getFocusOffset()   textToInsert.length);

    let inlineStyles = editorState.getCurrentInlineStyle();

    inlineStyles.forEach(inLineStyle => newContent = Modifier.applyInlineStyle(newContent, textToInsertSelection, inLineStyle));

    let newState = EditorState.push(editorState, newContent, 'insert-characters');
    newState = EditorState.forceSelection(newState, textToInsertSelection.set('anchorOffset', textToInsertSelection.getAnchorOffset()   textToInsert.length));

    return newState;
}