Reputation: 413
I would like to add a character counter on my React Quill.
At the moment I have a character limiter of 950.
The problem is that the user must be aware that the number of characters must not be more than 950, thus the character counter
I've tried adding getLength()
on the render but gives me an error.
This is my code:
attachQuillRefs = () => {
if (typeof this.reactQuillRef.getEditor !== "function") return;
this.quillRef = this.reactQuillRef.getEditor();
};
//Handles changes to description field
handleDetailChange(value) {
var limit = 950;
var quill = this.quillRef;
quill.on("text-change", function (delta, old, source) {
if (quill.getLength() > limit) {
quill.deleteText(limit, quill.getLength());
}
});
this.setState({
detail: value,
});
}
at Render:
<ReactQuill
ref={(el) => {
this.reactQuillRef = el;
}}
onChange={this.handleDetailChange}
value={this.state.detail || ""}
>
<p>{this.reactQuillRef.getLength() + "/950"}</p>
</ReactQuill>
Upvotes: 1
Views: 5560
Reputation: 1427
I was able to get it to work with @Juan Lanus's advice, using UnprivilegedEditor
provided by onChange
in react-quill
This is implemented in NextJS 12 - (React 18)
You may refer to sample snippet below:
import { useState } from 'react'
import dynamic from 'next/dynamic'
import 'react-quill/dist/quill.snow.css'
import { ReactQuillProps, UnprivilegedEditor } from 'react-quill'
import { DeltaStatic, Sources } from 'quill'
const ReactQuill = dynamic(() => import('react-quill'), { ssr: false })
export interface ICustomRichTextEditorProps extends ReactQuillProps {
value?: string
maxLength?: number
errorMessage?: string
helperText?: string
disabled?: boolean
}
const RichTextEditor = ({
placeholder,
value,
onChange,
}: ICustomRichTextEditorProps) => {
const [count, setCount] = useState<number>(0)
const [shrink, setShrink] = useState(false)
const handleOnChange = (
value: string,
deltaOp: DeltaStatic,
sources: Sources,
editor: UnprivilegedEditor,
) => {
const characterCount = editor.getLength() - 1
console.log(characterCount)
// you can also choose to assign the character count with React useState like so:
// setCount(characterCount)
onChange && onChange(value, deltaOp, sources, editor)
}
return (
<div>
<ReactQuill
value={value}
placeholder={placeholder}
onChange={handleOnChange}
// ... other props
/>
</div>
)
}
export default RichTextEditor
Note that I am using react-quill beta version, which is what i found to be most compatible to Next12 per time when posting in this thread
"react-quill": "^2.0.0-beta.4",
Upvotes: 0
Reputation: 2344
react-quill event handlers expose 4 args, like this:
onChange(content, delta, source, editor)
The 4th argument, editor
, is a reference to an "unprivileged" editor that exposes a restricted subset of the Quill API.
One of the methods provided is getLength()
that returns the content length in characters.
https://github.com/zenoamaro/react-quill#the-unprivileged-editor
This solves the length calculation.
As of the limit, you can display not the number of chars entered, but 950 minus said number, in an element that turns red when the limit is exceeded (less than zero characters left).
Upvotes: 2
Reputation: 320
1)create a custom module and register it with qill as below.
class Counter {
constructor(quill, options) {
this.quill = quill;
this.options = options;
this.container = document.querySelector(options.container);
quill.on('text-change', this.update.bind(this));
this.update(); // Account for initial contents
}
calculate() {
let text = this.quill.getText().trim();
if (this.options.unit === 'word') {
text = text.trim();
// Splitting empty text returns a non-empty array
return text.length > 0 ? text.split(/\s+/).length : 0;
} else {
return text.length;
}
}
update() {
var length = this.calculate();
var label = this.options.unit;
if (length !== 1) {
label += 's';
}
this.container.innerText = length + ' ' + label;
}
}
Quill.register('modules/counter', Counter);
2) then add below code to modules as shown in image.
counter: {
container: '#counter',
unit: 'character'
}
3) now you can add a new div tag under quilleditor tag with counter id.
<ReactQuill
ref={(el) => {
this.reactQuillRef = el;
}}
onChange={this.handleDetailChange}
value={this.state.detail || ""}
>
<p>{this.reactQuillRef.getLength() + "/950"}</p>
</ReactQuill>
<div id="counter">0</div>
Upvotes: 1