2017-09-04 32 views

Odpowiedz

7

Należy określić handleBeforeInput i handlePastedText rekwizyty. W funkcjach funkcji obsługi sprawdzasz długość bieżącej zawartości + długość wklejonego tekstu, a jeśli osiągnie maksymalny powinieneś zwrócić ciąg znaków 'handled'.

przykład Praca - https://jsfiddle.net/mnkou1mL/

const {Editor, EditorState} = Draft; 

const MAX_LENGTH = 10; 

class Container extends React.Component { 
    constructor(props) { 
    super(props); 
    this.state = { 
     editorState: EditorState.createEmpty() 
    }; 
    } 
    render() { 
    return (
     <div className="container-root"> 
     <Editor 
      placeholder="Type away :)" 
      editorState={this.state.editorState} 
      handleBeforeInput={this._handleBeforeInput} 
      handlePastedText={this._handlePastedText} 
      onChange={this._handleChange} 
     /> 
     </div> 
    ); 
    } 

    _getLengthOfSelectedText =() => { 
    const currentSelection = this.state.editorState.getSelection(); 
    const isCollapsed = currentSelection.isCollapsed(); 

    let length = 0; 

    if (!isCollapsed) { 
     const currentContent = this.state.editorState.getCurrentContent(); 
     const startKey = currentSelection.getStartKey(); 
     const endKey = currentSelection.getEndKey(); 
     const isBackward = currentSelection.getIsBackward(); 
     const blockMap = currentContent.getBlockMap(); 
     const startBlock = currentContent.getBlockForKey(startKey); 
     const endBlock = currentContent.getBlockForKey(endKey); 
     const isStartAndEndBlockAreTheSame = startKey === endKey; 
     const startBlockTextLength = startBlock.getLength(); 
     const endBlockTextLength = endBlock.getLength(); 
     const startSelectedTextLength = startBlockTextLength - currentSelection.getStartOffset(); 
     const endSelectedTextLength = currentSelection.getEndOffset(); 
     const keyAfterEnd = currentContent.getKeyAfter(endKey); 

     if (isStartAndEndBlockAreTheSame) { 
     length += currentSelection.getEndOffset() - currentSelection.getStartOffset(); 
     } else { 
     let currentKey = startKey; 
     let counter = 0; 

     while (currentKey && currentKey !== keyAfterEnd) { 
        if (currentKey === startKey) { 
      length += startSelectedTextLength + 1; 
      } else if (currentKey === endKey) { 
      length += endSelectedTextLength; 
      } else { 
      length += currentContent.getBlockForKey(currentKey).getLength() + 1; 
      } 

      currentKey = currentContent.getKeyAfter(currentKey); 
     }; 
     } 
    } 

    return length; 
    } 

    _handleBeforeInput =() => { 
    const currentContent = this.state.editorState.getCurrentContent(); 
    const currentContentLength = currentContent.getPlainText('').length 

    if (currentContentLength > MAX_LENGTH - 1) { 
     console.log('you can type max ten characters'); 

     return 'handled'; 
    } 
    } 

    _handlePastedText = (pastedText) => { 
    const currentContent = this.state.editorState.getCurrentContent(); 
    const currentContentLength = currentContent.getPlainText('').length; 
    const selectedTextLength = this._getLengthOfSelectedText(); 

    if (currentContentLength + pastedText.length - selectedTextLength > MAX_LENGTH) { 
     console.log('you can type max ten characters'); 

     return 'handled'; 
    } 
    } 

    _handleChange = (editorState) => { 
    this.setState({ editorState }); 
    } 
} 

ReactDOM.render(<Container />, document.getElementById('react-root')); 
+1

a co z przypadkiem użycia, aby podświetlić część aktualnej treści i wkleić, aby zastąpić zaznaczoną treść? – devonJS

+1

@devonJS Dobry punkt, dzięki! Ten przypadek nie został wstępnie przedstawiony. Zaktualizowałem odpowiedź, obecnie sprawdzamy długość wybranego tekstu po wklejeniu treści do edytora. –

3

metody Michaiła są poprawne, lecz wartość zwracana obsługi nie jest. "not_handled" jest przypadkiem typu fall-through, który pozwala komponentowi Editor przetwarzać dane wejściowe w normalny sposób. W takim przypadku chcemy zatrzymać edytor przed przetwarzaniem danych wejściowych.

W starszych wersjach DraftJS wygląda na to, że w kodzie obsługi występuje ciąg znaków oznaczony jako "true", więc powyższy kod zachowywał się poprawnie. W późniejszych wersjach DraftJS powyższe skrzypce nie działa - nie mam reputacji, aby opublikować więcej niż jeden Fiddle tutaj, ale spróbuj użyć kodu Mikhail'a z wersją 0.0. DraftJS do replikacji.

Aby to poprawić, należy zwrócić wartość "handled" lub true, aby Edytor nie kontynuował przetwarzania danych wejściowych.

Fiddle with corrected return values

Na przykład

_handleBeforeInput =() => { 
    const currentContent = this.state.editorState.getCurrentContent(); 
    const currentContentLength = currentContent.getPlainText('').length 

    if (currentContentLength > MAX_LENGTH - 1) { 
    console.log('you can type max ten characters'); 
    return 'handled'; 
    } 
} 

Zobacz DraftJS Docs na opłata teleskopowe na więcej.

+0

Dzięki za poprawkę. –

0

Pomyślmy o tym przez chwilę. Co się nazywa, aby dokonać zmian? Twoja onChange, prawda? Dobry. Znamy również numer length. Poprawny? Mamy attact się „pracownik”, który jest onChange:

const length = editorState.getCurrentContent().getPlainText('').length; 

// Your onChange function: 
onChange(editorState) { 
const MAX_LENGTH = 10; 
const length = editorState.getCurrentContent().getPlainText('').length; 

if (length <= MAX_LENGTH) { 
    this.setState({ editorState }) // or this.setState({ editorState: editorState }) 
} 
} else { 
console.log(`Sorry, you've exceeded your limit of ${MAX_LENGTH}`) 
} 

nie próbowałem tego, ale moja 6th Sense mówi, że działa dobrze.