You could check the size of the contents in onChange if the ContentState has changed, and slice off the contents that go beyond the limit.
to solve the problem, as follows:
onChange(editorState) {
const contentState = editorState.getCurrentContent();
if (contentState.getPlainText().length > this.props.maxLength) {
editorState = EditorState.undo(editorState);
}
this.setState({editorState});
}
Well, I don't know if I would recommend using undo for this, since it may jump you back to a previous boundary state that you don't want.
Ideally, you'd be able to do:
onChange(editorState) {
const contentState = editorState.getCurrentContent();
const oldContent = this.state.editorState.getCurrentContent();
const {maxLength} = this.props;
if (contentState === oldContent || contentState.getPlainText().length <= maxLength) {
this.setState({editorState});
}
}
But I think beforeInput native rendering might cause trouble for this, so for now, to be really safe, you'd also want to implement handleBeforeInput:
handleBeforeInput(chars) {
const totalLength = this.state.editorState.getCurrentContent().getPlainText().length + chars.length;
return totalLength > this.props.maxLength;
}
By returning true, we prevent the beforeInput event from rendering the new character or from executing onChange.
chars type is String chars.length ?
That's correct, thanks. Fixed my comment.
when chars will be greater than an length?
Sorry, I don't understand the question.
@hellendag i tried your solution, but it dose not work for me and this is work for me
your solution prevent setState, but it still writing.
onChange = editorState => {
const contentState = editorState.getCurrentContent();
const oldContent = this.state.editorState.getCurrentContent();
if(contentState === oldContent || contentState.getPlainText().length <= 25) {
this.setState({ editorState });
} else {
const editorState = EditorState.moveFocusToEnd(
EditorState.push(
this.state.editorState,
ContentState.createFromText(oldContent.getPlainText())
)
);
this.setState({ editorState });
}
}
@AnasRezk to prevent focus move to end, use following solution. This also doesn't jump as mentioned from @hellendag
onChange = editorState => {
const contentState = editorState.getCurrentContent();
const oldContent = this.state.editorState.getCurrentContent();
if(contentState === oldContent || contentState.getPlainText().length <= 25) {
this.setState({ editorState });
} else {
const editorState = EditorState.undo(
EditorState.push(
this.state.editorState,
ContentState.createFromText(oldContent.getPlainText()),
'delete-character'
)
);
this.setState({ editorState });
}
}
here some typescript solution:
getStateWithMaxLengthEnsured(oldState: Draft.EditorState, newState: Draft.EditorState, maxLength: number): Draft.EditorState {
const contentState = newState.getCurrentContent();
const oldContent = oldState.getCurrentContent();
if (contentState === oldContent || contentState.getPlainText().length <= maxLength) {
return newState;
} else {
return Draft.EditorState.undo(
Draft.EditorState.push(
oldState,
Draft.ContentState.createFromText(oldContent.getPlainText()),
'delete-character'
)
);
}
}
Most helpful comment
Well, I don't know if I would recommend using
undofor this, since it may jump you back to a previous boundary state that you don't want.Ideally, you'd be able to do:
But I think
beforeInputnative rendering might cause trouble for this, so for now, to be really safe, you'd also want to implementhandleBeforeInput:By returning true, we prevent the
beforeInputevent from rendering the new character or from executingonChange.