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

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'
});
});

Related

quill js production problem in next js app

I am using quill JS with Next JS, its working totally fine on local machine but on production not working like when I selecting any header tag like h3 its by default selecting h1 tag
and when I selecting any color its not selecting it
Here is my component for quill js
RichTextEditor.js
import React from 'react'
import dynamic from 'next/dynamic'
const QullEditor = dynamic(import("react-quill"), {ssr: false})
const toolbarOptions = [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
['link'],
[{ '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'], // remove formatting button
];
const RichTextEditor = ({ handler, defaultValue,placeholder }) => {
return (
<QullEditor modules={{toolbar:toolbarOptions}} onChange={(data) => handler(data)} theme="snow" placeholder={ placeholder ?? 'Enter Your Paragraph'} defaultValue={defaultValue} />
)
}
export default RichTextEditor
and I am using it like this
<RichTextEditor handler={setSubText} defaultValue={update.is ? update.data.subtext : null} />
Please Let me know How to solve this bug

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

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.

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();

(ng)quill problem: the selected value of custom font family/size is not displayed in ql-picker-label

We have added the ng-quill component to our web app build with angularjs. With the code below my developer tried to customize font family and font size picker in the toolbar. It is functional so far but the selected value of the dropdown options is not displayed after selection. "Sans serif" and "normal" keep to be displayed.
Here the code:
(function () {
'use strict';
angular
.module('tu.richtext.editor', ['ngQuill'])
.constant('NG_QUILL_CONFIG', {
modules: {
toolbar: [
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block', 'link'],
[{ 'header': 1 }, { 'header': 2 }],
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'script': 'sub' }, { 'script': 'super' }],
[{ 'indent': '-1' }, { 'indent': '+1' }],
[{ 'direction': 'rtl' }],
[{ 'size': [false, '14px', '16px', '18px', '20px'] }],
[{ 'header': [1, 2, 3, 4, 5, false] }],
[{ 'color': [] }, { 'background': [] }],
[{ 'font': ['sans-serif', 'times-new-roman', 'roboto', 'lato', 'oswald', 'montserrat', 'raleway', 'lora', 'nunito', 'prompt'] }],
[{ 'align': [] }],
['clean'],
['link', 'image', 'video']
]
},
theme: 'snow',
placeholder: '',
readonly: false,
bounds: document.body
})
.config(function(ngQuillConfigProvider, NG_QUILL_CONFIG) {
ngQuillConfigProvider.set(NG_QUILL_CONFIG);
// ngQuillConfigProvider.set(null, null, 'custom placeholder');
})
.component('tuRichtextEditor', {
bindings: {
ngModel: '=',
required: '<',
format: '<'
},
controller: RichtextEditorCtrl,
controllerAs: '$ctrl',
templateUrl: 'app-commons/components/tu-richtext-editor/tuRichText.tpl.html'
});
function RichtextEditorCtrl($scope, $timeout, $sce) {
var ctrl = this;
ctrl.loadComplete = false;
ctrl.customOptions = [{
import: 'attributors/style/size',
whitelist: [false, '14px', '16px', '18px', '20px']
}, {
import: 'attributors/class/font',
whitelist: ['sans-serif', 'times-new-roman', 'roboto', 'lato', 'oswald', 'montserrat', 'raleway', 'lora', 'nunito', 'prompt']
}];
$scope.customModules = {
toolbar: [
[{'size': [false, '14', '16', '18', '20']}]
]
};
ctrl.$onInit = function () {
// console.log(Quill);
// console.log(ctrl.ngModel);
ctrl.readOnly = false;
ctrl.required = ctrl.required? 'required' : '';
registerDelegates();
};
function registerDelegates() {
ctrl.editorCreated = function (editor) {
console.log(editor);
console.log(editor.editor);
};
ctrl.contentChanged = function (editor, html, text, content, delta, oldDelta, source) {
ctrl.ngModel = html;
};
ctrl.selectionChanged = function (editor, range, oldRange, source) {
console.log('editor: ', editor, 'range: ', range, 'oldRange:', oldRange, 'source:', source);
};
ctrl.loadComplete = true;
}
}})();
The css classes are changed too regarding to these examples:
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="14px"]::before {content: '14'; font-size: 14px !important;}
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="roboto"]::before {content: 'Roboto'; font-family: 'Roboto', sans-serif !important; }
He had given up now and I have not been able to find the bug.
Quill has an example for how to use custom fonts:
https://quilljs.com/playground/#custom-fonts
You can add custom sizes the same way.

Highstock Navigator Displayed Twice

I am using highstock,5.0.10 with angularJS.
In my chart navigator got displayed twice, like below
As you can see, navigator has been rendered twice. However, if you refresh the page, everything looks fine.
Any ideas?
I have added my Highstock code here.
Highcharts.stockChart('FindComputerUsage', {
rangeSelector: {
selected: 1
},
credits: {
enabled: false
},
title: {
text: ''
},
yAxis: {
title: {
text: 'Percentage of time (%) '
}
},
tooltip: {
formatter: function() {
var date = new Date(requiredData[this.points[0].point.index][0]);
return date + '<br>' + 'Percentage:' + requiredData[this.points[0].point.index][1] + '%';
}
},
series: [{
name: 'Percentage (%)',
data: requiredData,
tooltip: {
valueDecimals: 2,
}
}],
lang :{
noData : "No data to display "
}
});
Here you can see a working example: https://plnkr.co/edit/OphM9wf8WyGm8U6HXfTy
You haven't show your HTML view, but I guess it's similar to this.
<div ng-controller="demoCtrl">
<div id="container" style="height: 400px; min-width: 310px"></div>
</div>
Concerning controller scope, I didn't change anything:
var app = angular.module('demoApp', []);
app.controller('demoCtrl', function($scope){
$scope.data = [
[1290729600000,45.00],
[1290988800000,45.27],
[1291075200000,44.45]
];
Highcharts.stockChart('container', {
rangeSelector: {
selected: 1
},
title: {
text: 'Qing Xu Example'
},
series: [{
name: 'Value',
data: $scope.data,
tooltip: {
valueDecimals: 2
}
}]
})
});

Resources