How to add "strinsert" custom dropdown plugin to ckeditor4-react? - reactjs

I am working with ckeditor4-react plugin to use Text editor inside react app. Now I want to add a string dropdown inside my text editor, for this I have followed the "add custom plugin" documentation and added "strinsert" custom plugin.
Inside "node-modules/ckeditor4-react/" folder I have created a folder with name "plugins" and placed "strinsert" folder inside this.
Now my path of custom plugins is "node-modules/ckeditor4-react/plugins/strinsert/plugin.js"
Code of "plugin.js":
CKEDITOR.plugins.add('strinsert',
{
requires : ['richcombo'],
init : function( editor )
{
// array of strings to choose from that'll be inserted into the editor
var strings = [];
strings.push(['##FAQ::displayList()##', 'FAQs', 'FAQs']);
strings.push(['##Glossary::displayList()##', 'Glossary', 'Glossary']);
strings.push(['##CareerCourse::displayList()##', 'Career Courses', 'Career Courses']);
strings.push(['##CareerProfile::displayList()##', 'Career Profiles', 'Career Profiles']);
// add the menu to the editor
editor.ui.addRichCombo('strinsert',
{
label: 'Insert Content',
title: 'Insert Content',
voiceLabel: 'Insert Content',
className: 'cke_format',
multiSelect:false,
panel:
{
css: [ editor.config.contentsCss, CKEDITOR.skin.getPath('editor') ],
voiceLabel: editor.lang.panelVoiceLabel
},
init: function()
{
this.startGroup( "Insert Content" );
for (var i in strings)
{
this.add(strings[i][0], strings[i][1], strings[i][2]);
}
},
onClick: function( value )
{
editor.focus();
editor.fire( 'saveSnapshot' );
editor.insertHtml(value);
editor.fire( 'saveSnapshot' );
}
});
}
});
After adding this I have used this plugin inside Text editor by using "extraPlugins" config prop. This is a code of my TextEditor plugin file(which is inside the "src" folder of )
class TextEditor extends React.Component {
constructor(props) {
super(props);
this.state = {
editorData: this.props.data
}
}
/** lifecycle method */
componentDidMount() {
this.isMount = true;
this.setState({editorData: this.props.data})
}
componentWillUnmount() {
this.isMount = false;
}
/** function to detect the editor changes */
onEditorChange(event) {
let data = event.editor.getData()
this.props.onChange(data)
}
// main function
render() {
const { editorData } = this.state;
return (
<CKEditor
data={editorData}
onChange={(e) => this.onEditorChange(e)}
config={{
toolbar: [
{ name: 'basicstyles', items: ['Bold', 'Italic', 'Underline', 'Strike'] },
{ name: 'editing', items: ['SelectAll'] },
{ name: 'clipboard', items: ['Undo', 'Redo'] },
{ name: 'links', items: ['Link', 'Unlink', 'Anchor'] },
{ name: 'insert', items: [ 'Image', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar' ] },
{ name: 'document', items: [ 'Templates', 'Preview', '-', 'Source'] },
{ name: 'paragraph', items: ['NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', 'Blockquote', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl', 'Language'] },
{ name: 'styles', items: [ 'Styles', 'Format', 'Font', 'FontSize' ] },
{ name: 'colors', items: [ 'TextColor', 'BGColor' ] },
{ name: 'tools', items: [ 'Maximize', 'ShowBlocks' ] },
],
removePlugins: ['language'],
extraPlugins: "strinsert",
}}
/>
);
}
}
export { TextEditor };
After adding this when I am opening the text editor it shows me an error inside console::
Error::
ckeditor.js:98 GET https://cdn.ckeditor.com/4.15.1/standard-all/plugins/strinsert/plugin.js?t=KA9B
ckeditor.js:258 Uncaught Error: [CKEDITOR.resourceManager.load] Resource name "strinsert" was not found at "https://cdn.ckeditor.com/4.15.1/standard-all/plugins/strinsert/plugin.js?t=KA9B".
at window.CKEDITOR.window.CKEDITOR.dom.CKEDITOR.resourceManager.<anonymous> (ckeditor.js:258)
at n (ckeditor.js:253)
at Array.v (ckeditor.js:254)
at y (ckeditor.js:254)
at HTMLScriptElement.CKEDITOR.env.ie.g.$.onerror (ckeditor.js:255)
Please suggest how can I add "strinsert" custom plugin inside ckeditor4-react text editor.

Related

how can i set default text alignment in react-quill to right?

I want the default text-align to be right in react quill, i couldn't find a way to do that.
Here is my text editor:
import dynamic from 'next/dynamic'
import { ReactQuillProps } from 'react-quill'
import 'react-quill/dist/quill.snow.css'
const ReactQuill = dynamic(import('react-quill'), { ssr: false })
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ header: 1 }, { header: 2 }],
[{ list: 'ordered' }, { list: 'bullet' }],
[{ direction: 'rtl' }],
[{ header: [1, 2, 3, 4, 5, 6, false] }],
[{ color: [] }, { background: [] }],
[{ align: [] }],
['link', 'image', 'video'],
['clean'],
]
export default function BasicTextEditor({
value,
onChange,
placeholder,
}: {
placeholder: string
value: string
onChange: () => void
}) {
const quillProps: ReactQuillProps = {
modules: {
toolbar: toolbarOptions,
},
}
return (
<ReactQuill
className="whitespace-pre-line"
{...quillProps}
placeholder={placeholder}
theme="snow"
value={value}
onChange={onChange}
formats={[{}]}
/>
)
}
As you can see there is an option called {align: []}, i want by default my text be
Right now for me to change the alignment of the text i have to add a class manly to each element in the text but i want a better way to achieve it.

Some features of react-quill don't work in production

I have a Next app and Text Editor using react-quill. In localhost everything works well, but when I got my project in vercel some features of react-quill don't work, like fontSize, color of font, align and so on.
`
import { Box } from '#chakra-ui/react';
import dynamic from 'next/dynamic';
import 'react-quill/dist/quill.snow.css';
const QuillNoSSRWrapper = dynamic(import('react-quill'), {
ssr: false,
loading: () => <p>Loading ...</p>,
});
const modules = {
toolbar: [
[{ header: '1' }, { header: '2' }, 'code-block'],
[{ size: [] }],
[{ script: 'super' }, { script: 'sub' }],
[{ color: [] }, { background: [] }],
['bold', 'italic', 'underline', 'strike', 'blockquote'],
[
'direction',
{ align: [] },
{ list: 'ordered' },
{ list: 'bullet' },
{ indent: '-1' },
{ indent: '+1' },
],
['link', 'image', 'video'],
['clean'],
],
};
const formats = [
'header',
'font',
'size',
'bold',
'italic',
'underline',
'strike',
'blockquote',
'list',
'bullet',
'indent',
'link',
'image',
'video',
'code-block',
'align',
'direction',
'color',
'background',
'script',
'super',
'sub',
];
const TextEditor = ({ setContentValue, value }: any) => {
return (
<QuillNoSSRWrapper
bounds={'.app'}
modules={modules}
formats={formats}
onChange={setContentValue}
placeholder="Write your post here. You can edit your text by tools above"
value={value}
theme="snow"
/>
);
};
export default TextEditor;
`
Here my code of TextEditor
Do you have any ideas about this?
I tried to use Text Editor react-quill that works well in development, but it doesn't work in vercel
Check if your next.config.ts has swcMinify: true. Removing this in my project helped.
More info here: ReactJs quill editor add color to text not working for deployed app

React Quill custom image handler not working

Can someone help me to find out what is the issue in the code. I have created a custom image upload option but for some reason the variable "quillReact" is coming null when quillImageCallback function is invoked. I am using react-hooks. The image is uploaded properly when using API and proper response is also returned from the backend.
let quillReact: ReactQuill | null = null;
const updateIssueInfo = (value: string, delta: any, source: any, editor: any) => {
setIssueManagementInEdit({
...issueManagementInEdit,
description: value
});
};
const quillImageCallback = () => {
console.log(issueManagement);
const input = document.createElement("input");
input.setAttribute("type","file");
input.setAttribute("accept", "image/*");
input.click();
input.onchange = async () => {
const file: File | null = input.files ? input.files[0] : null;
if(file){
uploadImage(file).then(async (fileName: any) => {
const newFileName:string = await fileName.text();
console.log(quillReact);
let quill: any | null = quillReact?.getEditor();
console.log(quill);
const range : any | null = quill?.getSelection(true);
quill?.insertEmbed(range.index, 'image', `http://localhost:8080/uploads/${newFileName}`);
});
}
}
};
const module = React.useMemo(() => { return {
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }], // custom button values
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent
[{ 'direction': 'rtl' }], // text direction
[{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'font': [] }],
[{ 'align': [] }],
['clean', 'image'] // remove formatting button
],
handlers: {
image: quillImageCallback
}
},
clipboard: {
// toggle to add extra line breaks when pasting HTML:
matchVisual: false,
}
}},[]);
<ReactQuill
value={issueManagementInEdit.description ? issueManagementInEdit.description : ""}
onChange={updateIssueInfo}
modules={module}
ref={(el: ReactQuill) => {
quillReact = el;
} }
style={{height: "250px"}}
id="description"
key="description"
/>
Thank You.
I suggest you try useRef:
const quillRef = React.useRef(null);
<ReactQuill ... ref={quillRef} />
And then access the editor in your callback:
const quill = quillRef.current.getEditor();

How can I display the current value from a chart?

I am new to React and I work on a small project basically, I have a chart and I just want to display the current value from the chart.
For example, I have a chart with 4 random values:[5,2,5,1], so I want to have displayed the current value below the chart like first is 5, second is 2 and so on.
Here is my part of code:
class App extends React.Component {
addPoint = (point) => {
currentData = this.state.options.series[0].data
this.setState({
options: {
series: [
{ data: [...currentData, point]}
]
}
});
}
constructor(props) {
super(props);
this.internalChart = undefined;
this.dataStream = new DataStream();
this.dataStream.setUpdateCallback(this.addPoint);
this.state = {
options: {
chart: {
events: {
load: function () {
}
}
},
time: {
useUTC: false
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 2
},
title: {
text: 'Live random data'
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: [[(new Date()).getTime(), 0]]
}]
}
};
}
render() {
return (
<HighchartsReact
constructorType={"stockChart"}
highcharts={Highcharts}
options={this.state.options}
/>
);
}}
Based on your snippet code, try to make random method by using function
Math.floor(Math.random() * Math.floor(max))
And then assign the options to HighchartsReact,
Full code on sandbox: https://codesandbox.io/s/headless-dream-0lzj1

QuillJS - Anyone can supply customized code for full toolbar with headers applied only for selections and not the entire text? Coldfusion and QuillJS

Need a working QUILLJS code with has full toolbar and a working Header icons in the toolbar to be applied only to the selected text and not to the entire text.
I am trying to avoid lot of recoding moving from a paid CKEditor into free QUILLJS.
HTML:
<div id="editor-container" style="height: 350px;">#variables.valTextSettings[url.msg]#</div>
<textarea id="htmlMessage" name="htmlMessage" style="display:none;"></textarea>
JS:
the html is handled via a hidden variable
$(document).ready(function () {
var quillcontainter = '#editor-container';
var hiddenformfield = '#htmlMessage';
var quill = new Quill(quillcontainter, {
modules: {
toolbar: [
['bold', 'italic', 'underline', 'strike'],
[{ 'font': [] }],[{ 'color': [] }, { 'background': [] }],
[{ 'list': 'ordered' }, { 'list': 'bullet' }, { 'indent': '-1' }, { 'indent': '+1' }],
[{ 'direction': 'rtl' }],
[{ 'header': 1 }, { 'header': 2 }],
['blockquote', 'code-block'],
[{ 'script': 'sub'}, { 'script': 'super' }],
[{ 'align': [] }],
['link'],
['clean'],
['showHtml']
]
},
placeholder: 'Transaction Notes..',
theme: 'snow' // or 'bubble'
});
/* Load Default values */
$(hiddenformfield).html(quill.root.innerHTML);
// This will produce a warning message in the console as we are attaching handlers separately, but we can ignore
var txtArea = document.createElement('textarea');
txtArea.style.cssText = "width: 100%;margin: 0px;background: rgb(29, 29, 29);box-sizing: border-box;color: rgb(204, 204, 204);font-size: 15px;outline: none;padding: 20px;line-height: 24px;font-family: Arial, Helvetica, sans-serif;position: absolute;top: 0;bottom: 0;border: none;display:none";
var htmlEditor = quill.addContainer('ql-custom'); htmlEditor.appendChild(txtArea);
var myEditor = document.querySelector(quillcontainter);
quill.on('text-change', function (delta, old, source) {
txtArea.value = quill.root.innerHTML;
$(hiddenformfield).html(quill.root.innerHTML);
});
var customButton = document.querySelector('.ql-showHtml');
customButton.addEventListener('click', function() {
if (txtArea.style.display === '') { var html = txtArea.value; quill.pasteHTML(html); }
// No text change but clicking the Source button
else { var html = quill.root.innerHTML; quill.pasteHTML(html); }
txtArea.style.display = txtArea.style.display === 'none' ? '' : 'none'
});
});

Resources