ngx-quill is an angular (>=2) module for the Quill Rich Text Editor containing all components you need.
If you like my work, feel free to support it. Donations to the project are always welcomed :)
PayPal: PayPal.Me/bengtler
| Angular | ngx-quill | supported |
|---|---|---|
| v21 | >= 29.x | until May, 2027 |
| v20 | 28.x | until Nov, 2026 |
| v19 | 27.x | until May, 2026 |
- Advanced Demo
- custom word count module
- custom toolbar with custom fonts and formats, toolbar position
- show the differences between sanitizing and not sanitizing your content if your content format is html
- usage of different content formats
- template-driven and reactive forms
- code + syntax highlighting
- formulas
- image resizing
- custom key-bindings, e.g. shift + b for bold
- dynamic styles and placeholder
- toggle readonly
- bubble toolbar
- activate formats after editor initialisation, e.g. rtl direction
- present quilljs content with the
quill-viewandquill-view-htmlcomponent
- Ionic Demo
- Angular Universal
npm install ngx-quill- install
@angular/core,@angular/common,@angular/forms,@angular/platform-browser,quillversion^2.0.0andrxjs- peer dependencies of ngx-quill - include theme styling: bubble.css or snow.css of quilljs in your index.html (you can find them in
node_modules/quill/dist), or add them in your css/scss files with@importstatements, or add them external stylings in your build process. - Example at the beginning of your style.(s)css:
@import '~quill/dist/quill.bubble.css';
// or
@import '~quill/dist/quill.snow.css';
- import
QuillModulefromngx-quill:
import { QuillModule } from 'ngx-quill'- add
QuillModuleto the imports of your NgModule:
@NgModule({
imports: [
...,
QuillModule.forRoot()
],
...
})
class YourModule { ... }
- use
<quill-editor></quill-editor>in your templates to add a default quill editor - do not forget to include quill + theme css in your buildprocess, module or index.html!
- for builds with angular-cli >=6 only add quilljs to your scripts or scripts section of angular.json, if you need it as a global :)!
HINT: If you are using lazy loading modules, you have to add QuillModule.forRoot() to your imports in your root module to make sure the Config services is registered.
It's possible to set custom default modules and Quill config options with the import of the QuillConfigModule from the ngx-quill/config. This module provides a global config, but eliminates the need to import the ngx-quill library into the vendor bundle:
import { QuillConfigModule } from 'ngx-quill/config';
@NgModule({
imports: [
...,
QuillConfigModule.forRoot({
modules: {
syntax: true,
toolbar: [...]
}
})
],
...
})
class AppModule {}
Registering the global configuration can be also done using the standalone function if you are bootstrapping an Angular application using standalone features:
import { provideQuillConfig } from 'ngx-quill/config';
bootstrapApplication(AppComponent, {
providers: [
provideQuillConfig({
modules: {
syntax: true,
toolbar: [...]
}
})
]
})
If you want to use the syntax module follow the Syntax Highlight Module Guide.
See Quill Configuration for a full list of config options.
The QuillModule exports the defaultModules if you want to extend them :).
- IME/special characters can add some unwanted new line (#1821 (comment)) - possible solution: unpatch the
compositionendevent from zone.js (https://angular.io/guide/zone#setting-up-zonejs) - formControl/model change is triggered on first rendering by quill (#1547), because validation can only be done after quill editor is initialise - possible solution: /
Important
Currently there are many issues with HTML + Quill v2 (https://github.com/slab/quill/issues?q=is%3Aissue%20state%3Aopen%20getSemanticHtml especially slab/quill#4509)
Tip
using html format is general not the best practise, use the "Delta"-represenation as object/json to be able to correclty render it and be able to migrate to different editors or major quill version
- use customOptions for adding for example custom font sizes or other options/formats
- use customModules for adding and overwriting modules, e.g. image-resize or your own modules
Per default when Quill.register is called and you are overwriting an already existing module, QuillJS logs a warning. If you pass customOptions or customModules ngx-quill is registering those modules/options/formats for you.
In e.g. an angular univeral project your AppModule and so QuillModule.forRoot() is executed twice (1x server side, 1x browser). QuillJS is running in a mocked env on server side, so it is intendet that every register runs twice.
To subpress those expected warnings you can turn them off by passing suppressGlobalRegisterWarning: true.
Ngx-quill updates the ngModel or formControl for every user change in the editor.
Checkout the QuillJS Source parameter of the text-change event.
If you are using the editor reference to directly manipulate the editor content and want to update the model, pass 'user' as the source parameter to the QuillJS api methods.
- ngModel - set initial value or allow two-way databinding for template driven forms
- formControl/formControlName - set initial value or allow two-way databinding for reactive forms
- readOnly (true | false) if user can edit content
- formats - array of allowed formats/groupings
- format - model format - default:
html, values:html | object | text | json, sets the model value type - html = html string, object = quill operation object, json = quill operation json, text = plain text - modules - configure/disable quill modules, e.g toolbar or add custom toolbar via html element default is
const modules = {
toolbar: [
['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'], // remove formatting button
['link', 'image', 'video'] // link and image, video
]
};
- theme - bubble/snow, default is
snow - sanitize - uses angulars DomSanitizer to sanitize html values - default:
false, boolean (only for format="html") - styles - set a styles object, e.g.
[styles]="{height: '250px'}" - placeholder - placeholder text, default is
Insert text here ... - bounds - boundary of the editor, default
document.body, pass 'self' to attach the editor element - maxLength - add validation for maxlength - set model state to
invalidand addng-invalidclass - minLength - add validation for minlength - set model state to
invalidand addng-invalidclass, only set invalid if editor text not empty --> if you want to check if text is required --> use the required attribute - trimOnValidation - trim trailing|leading newlines on validation run for required, min- and maxLength, default
false - required - add validation as a required field -
[required]="true"- default: false, boolean expected (no strings!) - registry - custom parchment registry to not change things globally
- compareValues - compare values in object format to avoid endless loops when setting ngModel value explicit, default
false - onlyFormatEventData - flag if onContentEditorChanged/onEditorChanged only sets format fitting the editor format, default
false, possible valuestrue | false | 'none'. Boosts performance when nonhtmlformat is used (by avoiding expensive calls toquill.getSemanticHtml()).noneskips all extra format data, so the event only returns thedeltaandoldDelta. - beforeRender - a function, which is executed before the Quill editor is rendered, this might be useful for lazy-loading CSS. Given the following example:
// typings.d.ts
declare module '!!raw-loader!*.css' {
const css: string;
export default css;
}
// my.component.ts
const quillCSS$ = defer(() =>
import('!!raw-loader!quill/dist/quill.core.css').then((m) => {
const style = document.createElement('style');
style.innerHTML = m.default;
document.head.appendChild(style);
})
).pipe(shareReplay({ bufferSize: 1, refCount: true }));
@Component({
template: '<quill-editor [beforeRender]="beforeRender"></quill-editor>',
})
export class MyComponent {
beforeRender = () => firstValueFrom(quillCSS$);
}
- use customOptions for adding for example custom font sizes - array of objects
{ import: string; whitelist: any[] }--> this overwrites this options globally !!!
// Example with registering custom fonts
customOptions: [{
import: 'formats/font',
whitelist: ['mirza', 'roboto', 'aref', 'serif', 'sansserif', 'monospace']
}]
- use customModules for adding and overwriting modules - an array of objects
{ implementation: any; path: string }--> this overwrites this modules globally !!!
// The `implementation` may be a custom module constructor or an Observable that resolves to
// a custom module constructor (in case you'd want to load your custom module lazily).
// For instance, these options are applicable:
// import BlotFormatter from 'quill-blot-formatter';
customModules = [
{ path: 'modules/blotFormatter', implementation: BlotFormatter }
]
// Or:
const BlotFormatter$ = defer(() => import('quill-blot-formatter').then(m => m.default))
customModules = [
{ path: 'modules/blotFormatter', implementation: BlotFormatter$ }
]
- checkout the demo repo about usage of
customOptionsandcustomModulesDemo Repo - possibility to create a custom toolbar via projection slot
[quill-editor-toolbar]and add content above[above-quill-editor-toolbar]and below[below-quill-editor-toolbar]the toolbar:
Try to not use much angular magic here, like (output) listeners. Use native EventListeners
<quill-editor>
<div above-quill-editor-toolbar>
above
</div>
<div quill-editor-toolbar>
<span class="ql-formats">
<button class="ql-bold" [title]="'Bold'"></button>
</span>
<span class="ql-formats">
<select class="ql-align" [title]="'Aligment'">
<option selected></option>
<option value="center"></option>
<option value="right"></option>
<option value="justify"></option>
</select>
<select class="ql-align" [title]="'Aligment2'">
<option selected></option>
<option value="center"></option>
<option value="right"></option>
<option value="justify"></option>
</select>
</span>
</div>
<div below-quill-editor-toolbar>
below
</div>
</quill-editor>
- customToolbarPosition - if you are working with a custom toolbar you can switch the position :). - default:
top, possible valuestop,bottom - debug - set log level
warn,error,logorfalseto deactivate logging, default:warn - trackChanges - check if only
user(quill source user) orallcontent/selection changes should be trigger model update, defaultuser. Usingallis not recommended, it cause some unexpected sideeffects. - classes - a space separated list of CSS classes that will be added onto the editor element
- linkPlaceholder - optional - set placeholder for the link tooltip
- debounceTime - optional - debounces
onContentChanged,onEditorChanged,ngModeland form control value changes. Improves performance (especially when working with large, >2-3 MiB Deltas), as neithereditorChangeHandler, nortextChangeHandlerhandler runs internally. - defaultEmptyValue - optional - change the default value for an empty editor. Currently it is
null, but you can set it e.g. to empty string
- onEditorCreated - editor instance
- Use this output to get the editor instance and use it directly. After this output has called the component is stable and all listeners are binded
editor // Quill
- onContentChanged - text is updated
{
editor: editorInstance, // Quill
html: html, // html string
text: text, // plain text string
content: content, // Content - operatins representation
delta: delta, // Delta
oldDelta: oldDelta, // Delta
source: source // ('user', 'api', 'silent' , undefined)
}
- onSelectionChanged - selection is updated, also triggered for onBlur and onFocus, because the selection changed
{
editor: editorInstance, // Quill
range: range, // Range
oldRange: oldRange, // Range
source: source // ('user', 'api', 'silent' , undefined)
}
- onEditorChanged - text or selection is updated - independent of the source
{
editor: editorInstance, // Quill
event: 'text-change' // event type
html: html, // html string
text: text, // plain text string
content: content, // Content - operatins representation
delta: delta, // Delta
oldDelta: oldDelta, // Delta
source: source // ('user', 'api', 'silent' , undefined)
}
or
{
editor: editorInstance, // Quill
event: 'selection-change' // event type
range: range, // Range
oldRange: oldRange, // Range
source: source // ('user', 'api', 'silent' , undefined)
}
- onFocus - editor is focused
{
editor: editorInstance, // Quill
source: source // ('user', 'api', 'silent' , undefined)
}
- onBlur - editor is blured
{
editor: editorInstance, // Quill
source: source // ('user', 'api', 'silent' , undefined)
}
- onNativeFocus - editor is focused, based on native focus event
{
editor: editorInstance, // Quill
source: source // ('dom')
}
- onNativeBlur - editor is blured, based on native blur event
{
editor: editorInstance, // Quill
source: source // ('dom')
}
In most cases a wysiwyg editor is used in backoffice to store the content to the database. On the other side this value should be used, to show the content to the enduser.
In most cases the html format is used, but it is not recommended by QuillJS, because it has the intention to be a solid, easy to maintain editor. Because of that it uses blots and object representations of the content and operation.
This content object is easy to store and to maintain, because there is no html syntax parsing necessary. So you even switching to another editor is very easy when you can work with that.
ngx-quill provides some helper components, to present quilljs content.
In general QuillJS recommends to use a QuillJS instance to present your content. Just create a quill editor without a toolbar and in readonly mode. With some simple css lines you can remove the default border around the content.
As a helper ngx-quill provides a component where you can pass many options of the quill-editor like modules, format, formats, customOptions, but renders only the content as readonly and without a toolbar. Import is the content input, where you can pass the editor content you want to present.
- content - the content to be presented
- formats - array of allowed formats/groupings
- format - model format - default:
html, values:html | object | text | json, sets the model value type - html = html string, object = quill operation object, json = quill operation json, text = plain text - modules - configure/disable quill modules
- theme - bubble/snow, default is
snow - debug - set log level
warn,error,logorfalseto deactivate logging, default:warn - use customOptions for adding for example custom font sizes --> this overwrites this options globally !!!
- use customModules for adding and overwriting modules --> this overwrites this modules globally !!!
- sanitize - uses angulars DomSanitizer to sanitize html values - default:
false, boolean (only for format="html")
- onEditorCreated - editor instance
<quill-view [content]="content" format="text" theme="snow"></quill-view>Most of you will use the html format (even it is not recommended). To render custom html with angular you should use the [innerHTML] attribute.
But there are some pitfalls:
- You need to have the quill css files loaded, when using classes and not inline styling (https://quilljs.com/guides/how-to-customize-quill/#class-vs-inline)
- When using classes use a
div-tag that has theinnerHTMLattribute and add theql-editorclass. Wrap your div in anotherdiv-tag with css classesql-containerand your theme, e.g.ql-snow.: - With quill v2 ngx-quill is using
quill.getSemanticHTML()to get html content. There some list tag information are stripped. (slab/quill#4103) (#1888)
<div class="ql-container ql-snow" style="border-width: 0;">
<div class="ql-editor" [innerHTML]="byPassedHTMLString">
</div>
</div>
- Angular has html sanitation, so it will strip unkown or not trusted parts of your HTML - just mark your html as trusted (DomSanitizer)
After that your content should look like what you expected.
If you store html in your database, checkout your backend code, sometimes backends are stripping unwanted tags as well ;).
As a helper ngx-quill provides a component where you can simply pass your html string and the component does everything for you to render it:
- add necessary css classes
- bypass html sanitation
<quill-view-html [content]="htmlstring" theme="snow"></quill-view-html>- content - html string to be presented
- theme - bubble/snow, default is
snow - sanitize - default:
false, boolean (uses DomSanitizer to bypass angular html sanitation when set to false)
Angular templates provide some assurance against XSS in the form of client side sanitizing of all inputs https://angular.io/guide/security#xss.
Ngx-quill components provide the input paramter sanitize to sanitize html-strings passed as ngModel or formControl to the component.
Caution
It is deactivated per default to avoid stripping content or styling, which is not expected.
Tip
But it is recommended to activate this option, if you are working with html strings as model values.
ngx-quill's People
Forkers
shibas alvirtuoso matuszeman princemaple whale-street hf-dev ryanechternacht disruptivemind hustfrog 1242035 caballerog vaags surajkhanal lockonf hypercubed dbfannin dasrick trowj baio seawenzhu fengbaozhiling mattmcsparran ioscreatix vishalvatsal joebos mostafacs aelkz danielmhair rourou0818 johanchouquet idevn muhammadusmanf85 chrisvfabio cuca24 mrholek derejekitaw coolwr julianhm9612 jfaquinojr ksanthoshkuma folkertcode swissnerd rayabaginextventure wupaz hesungyoon aleixsuau hack-a-code nakedcreativity yy7054wyq5 eseliger nothingstopi iwe7 shawn0919 jorroll syam yharaskrik ramesh-ns davidalphafox ijavascripter mshahin364 russ3ll-franz tavo379 aeongo-chujia lyyarrow camdenbrown-zz neryams danieltreiber akitha justinelst bagginz ngnam lfroment0 charlesguillot easyworks haiderm-hexaware emmanueldaher dmitrijs markgoho gjlaubenstein serhiikovalskyi ejahn andrewdex onerzafer thinglogix darkoandreev earshinov harshadvala nishchhal-shrestha macwac ebra100 tomort zzzz1997 dalestone rock-fe-libs solanin08 cwspear aiira-co adriansfichi lishaguoguo panmxngx-quill's Issues
upload image from url
How can I upload image from url ?now this only upload image from local.I want both.
Where do I get quill.snow.css from?
Hi again,
I don't want to use the Quill CDN for quill.snow.css and would like to reference it from the Node modules in my angualar-cli json file so it is packaged in WebPack. However, I can't seem to find it in ngx-quill or quill - where can I find it?
Adding custom button/s
Hi there,
how to add new buttons and functionality?
Thanks
Update rxjs to release version (^5.0.1)
Can you please update rxjs version to ^5.0.1 to be able to work latest versions of angular which require rxjs ^5.0.1?
Thanks!
Syntax highlighter
Hi
This might be the wrong place for my question but here goes...
I have added angular2-highlight-js and it works very well inside quill.
But when I want to display syntax highlighted code outside quill I am not able to get it working.
On the element i set:
highlight-js-content=".highlight"
This is according to the docs in highlight. But quill saves it:
<pre class="ql-syntax" spellcheck="false">
Any idea on how I can make this work?
In advance thank you.
Registration of quill-image-resize-module fails
I have been trying to register an image resize module (https://github.com/kensnyder/quill-image-resize-module) with Quill. But as soon as Quill.register('modules/imageResize', ImageResize); is called, I get the following error: TypeError: Cannot read property 'imports' of undefined
I created a plunker that shows the issue:
https://plnkr.co/edit/IrSndtpRKSXG324zArN7?p=preview
I don't really know if this is really an issue or if I'm simply mistaking something in the configuration. I have had a look at the examples provided and other issues but have not been able to resolve this problem. Hence, any help would be deeply appreciated as the ability to resize images is something quite handy to have.
Thank you very much.
How to add custom handler
Hi, first of all, thank you for this cool package :).
So, here is my issue: I need to add a custom handler for the images (I don't want the image to be stored in base 64)
How can I add a custom handler ?
I need the index.js
Hi,
I am using Angular-seed project which is using SystemJS. It requires the index.js instead of index.ts. For example, the ng2-ckeditor is doing the same thing - wrapping the ckeditor. And I could get it working with my Angular-seed project. Can you add tsconfig.json and do the same thing to in your project?
Regards
Cheng
Register new module ImageResize
I'm trying to add a new module in the editor to show image size and can resize it.
I found this module for the Quill editor but I am not able to add it in ngx-quill when it returns the editor in onEditorCreated ()
Component.js
onEditorCreated(quill) { this.editor = quill; this.editor.register('modules/ImageResize',ImageResize); console.log('quill is ready! this is current quill instance object', quill); }
`/**
* Custom module for quilljs to allow user to resize <img> elements
* (Works on Chrome, Edge, Safari and replaces Firefox's native resize behavior)
* @see https://quilljs.com/blog/building-a-custom-module/
*/
export class ImageResize {
constructor(quill, options = {}) {
// save the quill reference and options
this.quill = quill;
this.options = options;
// bind handlers to this instance
this.handleClick = this.handleClick.bind(this);
this.handleMousedown = this.handleMousedown.bind(this);
this.handleMouseup = this.handleMouseup.bind(this);
this.handleDrag = this.handleDrag.bind(this);
this.checkImage = this.checkImage.bind(this);
// track resize handles
this.boxes = [];
// disable native image resizing on firefox
document.execCommand('enableObjectResizing', false, 'false');
// respond to clicks inside the editor
this.quill.root.addEventListener('click', this.handleClick, false);
}
handleClick(evt) {
if (evt.target && evt.target.tagName && evt.target.tagName.toUpperCase() == 'IMG') {
if (this.img === evt.target) {
// we are already focused on this image
return;
}
if (this.img) {
// we were just focused on another image
this.hide();
}
// clicked on an image inside the editor
this.show(evt.target);
}
else if (this.img) {
// clicked on a non image
this.hide();
}
}
show(img) {
// keep track of this img element
this.img = img;
this.showResizers();
this.showSizeDisplay();
// position the resize handles at the corners
const rect = this.img.getBoundingClientRect();
this.positionBoxes(rect);
this.positionSizeDisplay(rect);
}
hide() {
this.hideResizers();
this.hideSizeDisplay();
this.img = undefined;
}
showResizers() {
// prevent spurious text selection
this.setUserSelect('none');
// add 4 resize handles
this.addBox('nwse-resize'); // top left
this.addBox('nesw-resize'); // top right
this.addBox('nwse-resize'); // bottom right
this.addBox('nesw-resize'); // bottom left
// listen for the image being deleted or moved
document.addEventListener('keyup', this.checkImage, true);
this.quill.root.addEventListener('input', this.checkImage, true);
}
hideResizers() {
// stop listening for image deletion or movement
document.removeEventListener('keyup', this.checkImage);
this.quill.root.removeEventListener('input', this.checkImage);
// reset user-select
this.setUserSelect('');
this.setCursor('');
// remove boxes
this.boxes.forEach(box => document.body.removeChild(box));
// release memory
this.dragBox = undefined;
this.dragStartX = undefined;
this.preDragWidth = undefined;
this.boxes = [];
}
addBox(cursor) {
// create div element for resize handle
const box = document.createElement('div');
// apply styles
const styles = {
position: 'absolute',
height: '12px',
width: '12px',
backgroundColor: 'white',
border: '1px solid #777',
boxSizing: 'border-box',
opacity: '0.80',
cursor: cursor,
};
this.extend(box.style, styles, this.options.handleStyles || {});
// listen for mousedown on each box
box.addEventListener('mousedown', this.handleMousedown, false);
// add drag handle to document
document.body.appendChild(box);
// keep track of drag handle
this.boxes.push(box);
}
extend(destination, ...sources) {
sources.forEach(source => {
for (let prop in source) {
if (source.hasOwnProperty(prop)) {
destination[prop] = source[prop];
}
}
});
return destination;
}
positionBoxes(rect) {
// set the top and left for each drag handle
[
{left: rect.left - 6, top: rect.top - 6}, // top left
{left: rect.left + rect.width - 6, top: rect.top - 6}, // top right
{left: rect.left + rect.width - 6, top: rect.top + rect.height - 6}, // bottom right
{left: rect.left - 6, top: rect.top + rect.height - 6}, // bottom left
].forEach((pos, idx) => {
this.extend(this.boxes[idx].style, {
top: Math.round(pos.top + window.pageYOffset) + 'px',
left: Math.round(pos.left + window.pageXOffset) + 'px',
});
});
}
handleMousedown(evt) {
// note which box
this.dragBox = evt.target;
// note starting mousedown position
this.dragStartX = evt.clientX;
// store the width before the drag
this.preDragWidth = this.img.width || this.img.naturalWidth;
// set the proper cursor everywhere
this.setCursor(this.dragBox.style.cursor);
// listen for movement and mouseup
document.addEventListener('mousemove', this.handleDrag, false);
document.addEventListener('mouseup', this.handleMouseup, false);
}
handleMouseup() {
// reset cursor everywhere
this.setCursor('');
// stop listening for movement and mouseup
document.removeEventListener('mousemove', this.handleDrag);
document.removeEventListener('mouseup', this.handleMouseup);
}
handleDrag(evt) {
if (!this.img) {
// image not set yet
return;
}
// update image size
if (this.dragBox == this.boxes[0] || this.dragBox == this.boxes[3]) {
// left-side resize handler; draging right shrinks image
this.img.width = Math.round(this.preDragWidth - evt.clientX - this.dragStartX);
}
else {
// right-side resize handler; draging right enlarges image
this.img.width = Math.round(this.preDragWidth + evt.clientX - this.dragStartX);
}
// reposition the drag handles around the image
const rect = this.img.getBoundingClientRect();
this.positionBoxes(rect);
this.positionSizeDisplay(rect);
}
setUserSelect(value) {
[
'userSelect',
'mozUserSelect',
'webkitUserSelect',
'msUserSelect'
].forEach(prop => {
// set on contenteditable element and <html>
this.quill.root.style[prop] = value;
document.documentElement.style[prop] = value;
});
}
setCursor(value) {
[
document.body,
this.img,
this.quill.root
].forEach(el => el.style.cursor = value);
}
checkImage() {
if (this.img) {
this.hide();
}
}
showSizeDisplay() {
if (!this.options.displaySize) {
return;
}
this.display = document.createElement('div');
// apply styles
const styles = {
position: 'absolute',
font: '12px/1.0 Arial, Helvetica, sans-serif',
padding: '4px 8px',
textAlign: 'center',
backgroundColor: 'white',
color: '#333',
border: '1px solid #777',
boxSizing: 'border-box',
opacity: '0.80',
cursor: 'default',
};
this.extend(this.display.style, styles, this.options.displayStyles || {});
document.body.appendChild(this.display);
}
hideSizeDisplay() {
document.body.removeChild(this.display);
this.display = undefined;
}
positionSizeDisplay(rect) {
if (!this.display || !this.img) {
return;
}
const size = this.getCurrentSize();
this.display.innerHTML = size.join(' × ');
if (size[0] > 120 && size[1] > 30) {
// position on top of image
const dispRect = this.display.getBoundingClientRect();
this.extend(this.display.style, {
left: Math.round(rect.left + rect.width + window.pageXOffset - dispRect.width - 8) + 'px',
top: Math.round(rect.top + rect.height + window.pageYOffset - dispRect.height - 8) + 'px',
});
}
else {
// position off bottom right
this.extend(this.display.style, {
left: Math.round(rect.left + rect.width + window.pageXOffset + 8) + 'px',
top: Math.round(rect.top + rect.height + window.pageYOffset + 8) + 'px',
});
}
}
getCurrentSize() {
return [
this.img.width,
Math.round(this.img.width / this.img.naturalWidth * this.img.naturalHeight),
];
}
}
`
Someone know how to ?
Setting modules input results in error
Setting modules input causes error quill Cannot import modules/0. Are you sure it was registered? .
My exaple is:
<quill-editor formControlName="journalEntry" modules="{toolbar: [['bold', 'italic', 'underline', 'strike']]}") </quill-editor>
Thank you
Reset the quill editor
I'm using angular 4 + reactive forms and bringing rich text in from my api. On initialization the quill editor puts the rich text in exact how I want, but if I overwrite the initialized editor it will strip all my markup inside the opening p and closing /p tags. How can I make every patchValue replace the editor body with exactly what I want it to from the api?
Will not compile with "noImplicitAny"
Line 93 in "quill-editor.component.ts" throws an error when compiled with Typescripts "noImplicitAny" flag set.
"[ts] Element implicitly has an 'any' type because type 'Object' has no index signature."
The code:
if (toolbarElem) {
modules['toolbar'] = toolbarElem; // Throws error
}
onContentChanged - triggers when item is removed from array
I have a problem regarding the onContentChanged method.
In my project I have a array of quill editors. And a user can add a new editor instance to the array and delete one from the array. But when the user delete a editor from the array the onContentChanged method is triggered.
And that is causing some side effects in my project. Because every time onContentChanged is triggered I save the data to the database. And when I delete a editor from my array, onContentChanged will add it back ;-(
Is there a way to change the behavior of onContentChanged so it's only watching the content of the current instance of the editor?
Source code has linting errors
Hi again,
When I include the SRC version, my AngularCLI (with strict linting) includes any issues found in the ngx-quill node module:
I am not sure why it is doing it but no other node modules do this (my linting is set to exclude Node Modules). Perhaps it is something to do with the fact that it is using the source?
Throw 'Unexpected token export' when import the module
system: OSX 10.12.4
angular: 2.4.1
code:
import { QuillModule } from 'ngx-quill';
console.log('QuillModule', QuillModule);
errors:
Uncaught SyntaxError: Unexpected token export
es5-shim.js?hash=adc3c62…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
at es5-shim.js?hash=adc3c62…:17
at es5-shim.js?hash=adc3c62…:2789
(anonymous) @ es5-shim.js?hash=adc3c62…:17
(anonymous) @ es5-shim.js?hash=adc3c62…:2789
promise.js?hash=db5ea3b…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
at promise.js?hash=db5ea3b…:17
at promise.js?hash=db5ea3b…:581
(anonymous) @ promise.js?hash=db5ea3b…:17
(anonymous) @ promise.js?hash=db5ea3b…:581
ecmascript-runtime.js?hash=361600e…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
at ecmascript-runtime.js?hash=361600e…:17
at ecmascript-runtime.js?hash=361600e…:4630
(anonymous) @ ecmascript-runtime.js?hash=361600e…:17
(anonymous) @ ecmascript-runtime.js?hash=361600e…:4630
babel-runtime.js?hash=542c082…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
at babel-runtime.js?hash=542c082…:17
at babel-runtime.js?hash=542c082…:160
(anonymous) @ babel-runtime.js?hash=542c082…:17
(anonymous) @ babel-runtime.js?hash=542c082…:160
random.js?hash=31dadb9…:18 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
at random.js?hash=31dadb9…:18
at random.js?hash=31dadb9…:355
(anonymous) @ random.js?hash=31dadb9…:18
(anonymous) @ random.js?hash=31dadb9…:355
mongo-id.js?hash=345d169…:19 Uncaught TypeError: Cannot read property 'Random' of undefined
at mongo-id.js?hash=345d169…:19
at mongo-id.js?hash=345d169…:142
(anonymous) @ mongo-id.js?hash=345d169…:19
(anonymous) @ mongo-id.js?hash=345d169…:142
geojson-utils.js?hash=b204c7d…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
at geojson-utils.js?hash=b204c7d…:17
at geojson-utils.js?hash=b204c7d…:439
(anonymous) @ geojson-utils.js?hash=b204c7d…:17
(anonymous) @ geojson-utils.js?hash=b204c7d…:439
minimongo.js?hash=66cc6ab…:23 Uncaught TypeError: Cannot read property 'MongoID' of undefined
at minimongo.js?hash=66cc6ab…:23
at minimongo.js?hash=66cc6ab…:3917
(anonymous) @ minimongo.js?hash=66cc6ab…:23
(anonymous) @ minimongo.js?hash=66cc6ab…:3917
check.js?hash=63d7478…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
at check.js?hash=63d7478…:17
at check.js?hash=63d7478…:613
(anonymous) @ check.js?hash=63d7478…:17
(anonymous) @ check.js?hash=63d7478…:613
retry.js?hash=1e40961…:18 Uncaught TypeError: Cannot read property 'Random' of undefined
at retry.js?hash=1e40961…:18
at retry.js?hash=1e40961…:110
(anonymous) @ retry.js?hash=1e40961…:18
(anonymous) @ retry.js?hash=1e40961…:110
ddp-common.js?hash=d42359b…:17 Uncaught TypeError: Cannot read property 'check' of undefined
at ddp-common.js?hash=d42359b…:17
at ddp-common.js?hash=d42359b…:493
(anonymous) @ ddp-common.js?hash=d42359b…:17
(anonymous) @ ddp-common.js?hash=d42359b…:493
reload.js?hash=628b069…:18 Uncaught TypeError: Cannot read property 'Symbol' of undefined
at reload.js?hash=628b069…:18
at reload.js?hash=628b069…:309
(anonymous) @ reload.js?hash=628b069…:18
(anonymous) @ reload.js?hash=628b069…:309
ddp-client.js?hash=bc32a16…:17 Uncaught TypeError: Cannot read property 'check' of undefined
at ddp-client.js?hash=bc32a16…:17
at ddp-client.js?hash=bc32a16…:4983
(anonymous) @ ddp-client.js?hash=bc32a16…:17
(anonymous) @ ddp-client.js?hash=bc32a16…:4983
ddp.js?hash=25dc3f4…:14 Uncaught TypeError: Cannot read property 'DDP' of undefined
at ddp.js?hash=25dc3f4…:14
at ddp.js?hash=25dc3f4…:27
(anonymous) @ ddp.js?hash=25dc3f4…:14
(anonymous) @ ddp.js?hash=25dc3f4…:27
allow-deny.js?hash=c9344ef…:18 Uncaught TypeError: Cannot read property 'LocalCollection' of undefined
at allow-deny.js?hash=c9344ef…:18
at allow-deny.js?hash=c9344ef…:536
(anonymous) @ allow-deny.js?hash=c9344ef…:18
(anonymous) @ allow-deny.js?hash=c9344ef…:536
mongo.js?hash=c4281c0…:17 Uncaught TypeError: Cannot read property 'AllowDeny' of undefined
at mongo.js?hash=c4281c0…:17
at mongo.js?hash=c4281c0…:909
(anonymous) @ mongo.js?hash=c4281c0…:17
(anonymous) @ mongo.js?hash=c4281c0…:909
xolvio_cleaner.js?hash=a137467…:17 Uncaught TypeError: Cannot read property 'Mongo' of undefined
at xolvio_cleaner.js?hash=a137467…:17
at xolvio_cleaner.js?hash=a137467…:102
(anonymous) @ xolvio_cleaner.js?hash=a137467…:17
(anonymous) @ xolvio_cleaner.js?hash=a137467…:102
practicalmeteor_chai.js?hash=92e20bf…:17 Uncaught TypeError: Cannot read property 'Symbol' of undefined
at practicalmeteor_chai.js?hash=92e20bf…:17
at practicalmeteor_chai.js?hash=92e20bf…:5639
(anonymous) @ practicalmeteor_chai.js?hash=92e20bf…:17
(anonymous) @ practicalmeteor_chai.js?hash=92e20bf…:5639
practicalmeteor_sinon.js?hash=b2d5a9f…:17 Uncaught TypeError: Cannot read property 'chai' of undefined
at practicalmeteor_sinon.js?hash=b2d5a9f…:17
at practicalmeteor_sinon.js?hash=b2d5a9f…:6256
(anonymous) @ practicalmeteor_sinon.js?hash=b2d5a9f…:17
(anonymous) @ practicalmeteor_sinon.js?hash=b2d5a9f…:6256
hwillson_stub-collections.js?hash=fd53027…:17 Uncaught TypeError: Cannot read property 'Mongo' of undefined
at hwillson_stub-collections.js?hash=fd53027…:17
at hwillson_stub-collections.js?hash=fd53027…:106
(anonymous) @ hwillson_stub-collections.js?hash=fd53027…:17
(anonymous) @ hwillson_stub-collections.js?hash=fd53027…:106
webapp.js?hash=3026d45…:18 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
at webapp.js?hash=3026d45…:18
at webapp.js?hash=3026d45…:70
(anonymous) @ webapp.js?hash=3026d45…:18
(anonymous) @ webapp.js?hash=3026d45…:70
livedata.js?hash=7cf1831…:14 Uncaught TypeError: Cannot read property 'DDP' of undefined
at livedata.js?hash=7cf1831…:14
at livedata.js?hash=7cf1831…:31
(anonymous) @ livedata.js?hash=7cf1831…:14
(anonymous) @ livedata.js?hash=7cf1831…:31
autoupdate.js?hash=1fd9cf3…:19 Uncaught TypeError: Cannot read property 'Retry' of undefined
at autoupdate.js?hash=1fd9cf3…:19
at autoupdate.js?hash=1fd9cf3…:206
(anonymous) @ autoupdate.js?hash=1fd9cf3…:19
(anonymous) @ autoupdate.js?hash=1fd9cf3…:206
barbatus_typescript-runtime.js?hash=7df7215…:17 Uncaught TypeError: Cannot read property 'meteorInstall' of undefined
at barbatus_typescript-runtime.js?hash=7df7215…:17
at barbatus_typescript-runtime.js?hash=7df7215…:215
(anonymous) @ barbatus_typescript-runtime.js?hash=7df7215…:17
(anonymous) @ barbatus_typescript-runtime.js?hash=7df7215…:215
global-imports.js?hash=4c0db35…:3 Uncaught TypeError: Cannot read property 'Mongo' of undefined
at global-imports.js?hash=4c0db35…:3
(anonymous) @ global-imports.js?hash=4c0db35…:3
app.js?hash=151d68c…:1 Uncaught ReferenceError: meteorInstall is not defined
at app.js?hash=151d68c…:1
(anonymous) @ app.js?hash=151d68c…:1
Does this replace ng2-Quill?
Hi,
I noticed another similar project (https://www.npmjs.com/package/ng2-quill "ng2-quill": "0.0.6",) but this one looks more recent - I assume ngx is the latest for ng2?
Thanks
Cursor moving to beginning of line
As seen above, whenever I first initiate the quill editor (with a null, '', or database value), the cursor automatically moves to the front and starts placing characters in front of it.
quill version: "ngx-quill": "^1.3.3" (I've confirmed that 1.33 is installed by using the npm list --depth=0 command
HTML:
<quill-editor formControlName="answer" (onEditorCreated)="setFocus($event)"></quill-editor>
The setFocus method is the same as you have in your demo.
Any insights as to why this is happening? If you need more information, please let me know.
Error: Unexpected value 'QuillModule' imported by the module 'AppModule' at d
I've been trying to get Quill working in my Angular 2 project and I can't figure out this error from ngx-quill. I followed the instructions for the systemjs.config file, added import { QuillModule } from 'ngx-quill'; to my app.module file, added it to the Imports, added "ngx-quill": "1.0.0" to my packages.json file and "@types/quill": "^0.0.29" to devDependencies.
Any idea what this console error means?
Error: Unexpected value 'QuillModule' imported by the module 'AppModule' at d
Integrating with Directives?
Wondered if there was anyway to integrate the editor with directives? I've been trying to use this example for auto including link tags on regex match but instead trying to auto include some directive or locator for Angular2 to use. Tried adding attributes like [custom] or adding custom tags to tie certain words to angular hooks but just constantly get "[Parchment] Cannot insert custom into block," 'custom' is whatever I try build either the attribute/blot/embed/inline/etc. Wondered if this was actually possible, or just incompatible.
Angular universal
Hi,
ngx-quill breaks universal
for example this line
var elem = document.createElement('div');
cause
ReferenceError: document is not defined
Build Error 1.3.3
I dialed back to 1.3.1 and everything is fine, so I'm thinking there might be an issue with a later release. (fyi ... I am not an AoT user)
node error;
build 06-Jul-2017 15:55:14 ERROR in [at-loader] ./node_modules/ngx-quill/src/quill-editor.component.ts:109:7
build 06-Jul-2017 15:55:14 TS2345: Argument of type '{ modules: any; placeholder: string; readOnly: boolean; theme: string; formats: string[]; bounds:...' is not assignable to parameter of type 'QuillOptionsStatic'.
build 06-Jul-2017 15:55:14 Object literal may only specify known properties, and 'bounds' does not exist in type 'QuillOptionsStatic'.
Add scrollingContainer option
Hello.
I need to specify scrollingContainer to restrict quill from growing.
Actually I want to do something like this: https://codepen.io/quill/pen/apmWXm
Thank you in advance.
Support for reactive forms (formControl)
First of all, thanks for your work on this great plugin! It works nicely with template driven forms.
I would, however, also like to use it with reactive forms. Thus i need to use "formControl" instead of "ngModel".
It appears that this is not fully supported(?)
My specific problem is that I am not able to use the "patchValue" method (of FormGroup) to insert content into the quill editor. The editor window remains empty after patching.
Entering new content by hand, and saving it, works fine however.
Please correct me if I'm mistaken.
Thanks!
Compiling with ng build --aot throws "can't find symbol KeyRegistry exported from module"
Using AngularCLI and trying to build in AOT mode, I get this error: "can't find symbol KeyRegistry exported from module". Honestly at this stage I have no idea what this means or why - I am raising it here in the hope that someone knows what this means - I will post back here if I can figure out the issue
>ng build --aot
0% compilingcan't resolve module C:/Git/QueMesaAdmin/QueMesaAdminApp/node_modules/ngx-quill/node_modules/@angular/core/src/di/reflective_key.d.ts from C:/Git/QueMesaAdmin/QueMesaAdminApp/node_modules/ngx-quill/node_modules/@angular/core/src/di/reflective_key.d.ts
can't find symbol KeyRegistry exported from module C:/Git/QueMesaAdmin/QueMesaAdminApp/node_modules/ngx-quill/node_modules/@angular/core/src/di/reflective_key.d.ts
Error: can't find symbol KeyRegistry exported from module C:/Git/QueMesaAdmin/QueMesaAdminApp/node_modules/ngx-quill/node_modules/@angular/core/src/di/reflective_key.d.ts
at ReflectorHost.findDeclaration (C:\Users\chuckj\src\angular\modules\@angular\compiler-cli\src\reflector_host.ts:200:15)
at C:\Users\chuckj\src\angular\modules\@angular\compiler-cli\src\codegen.ts:179:44
at Array.forEach (native)
kindly publish more examples
Hi could you publish more examples of how to use this package.
In particular it would me nice if there was a folder called "examples" with the source code of https://killercodemonkey.github.io/ngx-quill-example/ in it.
Thanks
AOT Build Error with angular 4
When try AOT Build with Angular 4, I got the flowing error:
Unexpected value 'QuillModule in /Projects/angular-seed/node_modules/ngx-quill/in
dex.d.ts' imported by the module 'AppModule in /Projects/angular-seed/src/app/app
.module.ts'. Please add a @NgModule annotation.
Here is my app.modules.ts:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { HttpModule, JsonpModule } from '@angular/http';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { QuillModule } from 'ngx-quill';
import { AppComponent } from './app.component';
import { RouteComponents, AppRoutes } from './app.routes';
@NgModule({
declarations: [
AppComponent,
RouteComponents
],
imports: [
BrowserModule,
BrowserAnimationsModule,
CommonModule,
FormsModule,
ReactiveFormsModule,
HttpModule,
JsonpModule,
NgbModule,
QuillModule,
AppRoutes
],
bootstrap: [AppComponent]
})
export class AppModule {}
and my package.json
{
"name": "angular-seed",
"version": "1.0.0",
"description": "angular seed app",
"main": "index.html",
"scripts": {
"sass": "node-sass --recursive --source-map true --source-map-contents --output src src ",
"sass:w": "npm run sass -- --watch",
"build": "npm run tsc && npm run sass",
"start": "npm run clean && npm run build && concurrently \"npm run tsc:w\" \"npm run sass:w\" \"npm run gulp:dev\"",
"gulp:dev": "gulp dev",
"gulp:serve": "gulp serve",
"clean": "rm -rf dist && find src -name \\*.js -type f -delete && find src -name \\*.js.map -type f -delete && find src -name \\*.ngfactory.ts -type f -delete && find src -name \\*.css -type f -delete && find src -name \\*.css.map -type f -delete && find src -name \\*.shim.ts -type f -delete && find src -name \\*.ngsummary.json -type f -delete && find src -name \\*.ngstyle.ts -type f -delete",
"ngc": "ngc --project tsconfig-aot.json",
"tsc": "tsc --project tsconfig.json",
"tsc:w": "npm run tsc -- --watch",
"tsc-aot": "tsc -p tsconfig-aot.json",
"rollup": "rollup -c rollup.config.js",
"build-aot": "npm run build && npm run ngc && npm run tsc-aot && npm run rollup"
},
"repository": {
"type": "git",
"url": "git+https://github.com/beginor/angular-seed.git"
},
"keywords": ["angular", "seed", "gulp", "systemjs"],
"author": "beginor",
"license": "MIT",
"bugs": {
"url": "https://github.com/beginor/angular-seed/issues"
},
"homepage": "https://github.com/beginor/angular-seed#readme",
"dependencies": {
"@angular/animations": "^4.2.5",
"@angular/common": "^4.2.5",
"@angular/compiler": "^4.2.5",
"@angular/core": "^4.2.5",
"@angular/forms": "^4.2.5",
"@angular/http": "^4.2.5",
"@angular/platform-browser": "^4.2.5",
"@angular/platform-browser-dynamic": "^4.2.5",
"@angular/router": "^4.2.5",
"core-js": "^2.4.1",
"reflect-metadata": "^0.1.10",
"rxjs": "~5.4.1",
"systemjs": "^0.20.14",
"zone.js": "^0.8.12",
"bootstrap": "^4.0.0-alpha.6",
"@ng-bootstrap/ng-bootstrap": "^1.0.0-alpha.26",
"font-awesome": "^4.7.0",
"web-animations-js": "^2.2.5",
"quill": "^1.2.6",
"ngx-quill": "^1.3.3"
},
"devDependencies": {
"@angular/compiler-cli": "^4.2.5",
"@angular/platform-server": "^4.2.5",
"@types/core-js": "~0.9.42",
"@types/node": "~8.0.6",
"concurrently": "^3.5.0",
"gulp": "^3.9.1",
"gulp-connect": "^5.0.0",
"http-proxy-middleware": "0.17.4",
"node-sass": "^4.5.3",
"rollup": "^0.43.0",
"rollup-plugin-commonjs": "^8.0.2",
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-uglify": "^2.0.1",
"typescript": "~2.3.4",
"@types/web-animations-js": "^2.2.4",
"@types/quill":"^0.0.31"
}
}Loading external fonts
Hello,
I'm having issues on loading external fonts.
Html:
<quill-editor [(ngModel)]="HTML_DATA" [style]="{'height' : '100%'}" [modules]="configEditor">
On my config object I've add:
configEditor: {} = {
toolbar: [
['bold', 'italic', 'underline', 'strike'],
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }],
[{ 'font': [ 'Aref Ruqaa', 'Mirza', 'Roboto'] }],
[{ 'align': [] }],
['clean'],
]
};
loaded the google font on index.html
<link href="https://fonts.googleapis.com/css?family=Aref+Ruqaa|Mirza|Roboto" rel="stylesheet">
and added some css on the component:
#editor-container {
font-family: "Aref Ruqaa";
font-size: 18px;
height: 375px;
}
#toolbar-container .ql-font span[data-label="Aref Ruqaa"]::before {
font-family: "Aref Ruqaa";
}
#toolbar-container .ql-font span[data-label="Mirza"]::before {
font-family: "Mirza";
}
#toolbar-container .ql-font span[data-label="Roboto"]::before {
font-family: "Roboto";
}
.ql-font-mirza {
font-family: "Mirza";
}
.ql-font-roboto {
font-family: "Roboto";
}
I'm doing anything wrong? It's possible to load fonts with this directive? The documentation is a little bit confusing. The only working example that I can see is in regular js.
https://codepen.io/quill/pen/gLBYam
Thanks.
Triggering clipboard with initial model value
It seems like when a new instance of quill-editor is created it triggers an event on the clipboard.
This behavior doesn't happen in the original version of quilljs. AI looked into the code and seems like you're using pasteHTML to insert the initial value, which makes it trigger the clipboard.
Context: On my application I'm listening for content that is pasted into the editor so I can clean up the content being pasted, the problem is that every time a new instance of quill-editor is created, it triggers a clipboard event which ends up changing the format of the value being passed by ngModel.
Here's a code example:
/// this should be triggered ONLY when a new text is pasted from the clipboard.
quill.clipboard.addMatcher(Node.ELEMENT_NODE, (node, delta) => {
return new Delta().insert(node.textContent);
});
cc: @EunusHosen
custom toolbar
Hello,
I m trying to use custom toolbar and it s not working.
Can you give me some direction how to use it?
many thanks
onContentChange() Debounce option
Would be nice to set a x number of seconds to debounce the onContentChange function.
So when you want to save data to your back end, you can write it every x seconds.
Prepend protocol to inserted links
Is there a way to prepend protocol to inserted links or make all link absolute?
For example, if user enters google.com as a link Quill generates link with href="google.com" which opens it incorrectly as a relative link.
Thanks
Bounds option
How would I implement the bounds options with ngx-quill?
http://quilljs.com/docs/configuration/#bounds
Think it's a missing feature, expected this to work
<quill-editor theme="bubble" [bounds]=".editor"></quill-editor>
error on compiling with angular-cli (1.0.0-rc.0)
When trying to use ngx-quill with angular-cli (1.0.0-rc.0) and angular (4.0.0-rc.2) I get an error on compiling regarding quill.module.ts
ERROR in Error encountered resolving symbol values statically. Calling function 'makeDecorator', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function
logo
Can you please give an exam,ple of how to configure the Toolbar?
Could you please give an exmple of how to configure the toolbar? I have added it to my module but not sure where the configuration goes, thanks
{```
toolbar: [
['bold', 'italic', 'underline', 'strike'], // toggled buttons
['blockquote', 'code-block'],
...
['link', 'image', 'video'] // link and image, video
]
};
Image Resize and Drop modules
There are 2 Quill modules which are very useful.
https://github.com/kensnyder/quill-image-resize-module
https://github.com/kensnyder/quill-image-drop-module
How can they be integrated to ngx-quill?
How to focus the editor?
Is there any way to focus the text field with this module? I noticed that Quill has a .focus() method, but I don't know if I can use it or how to do it.
how to set the height of the editor ?
Hi,
I'm using angular 4 + reactive forms.
How to set the height of the editor ?
Uncaught Error: Expected 'styles' to be an array of strings.
Hi.
I've just downloaded your component and im trying to make it work. I've added the component to my appModule as explained in the ReadMe file.
i get this error when trying to transpile my code:
angular 2/angular-seed/angular-webpack/node_modules/ng2-quill-editor/quillEditor.component.ts:81:57
Property 'assign' does not exist on type 'ObjectConstructor'.
i also get a bunch of errors, like this one:
Uncaught Error: Expected 'styles' to be an array of strings.
at assertArrayOfStrings (eval at (http://localhost:8081/vendor.js:95:2)
Most of the errors occur in the vendor.ts file.
I had to set the "noImplicitAny": false to false to avoid a whole bunch of other errors regarding implicitly type any.
Is there any fix to these errors? Am i missing something?
I'm running with typescript version 2.0.10 - angular version ~2.2.0
Kind regards Chris
Error 413 Payload Too Large
Hi, when I upload a image to the content, the error bellow happens:
Response {_body: "↵↵↵<meta char…s/cors/lib/index.js:185:7)↵↵↵", status: 413, ok: false, statusText: "Payload Too Large", headers: Headers, …}
headers
:
Headers {_headers: Map(12), _normalizedNames: Map(12)} ok : false
status : 413
statusText : "Payload Too Large"
type : 2
url :
"http://www.adrianabartolomucci.com.br/api/servicos/59370f9d6993d8381cd31694"
_body
:
"↵↵↵↵<title>Error</title>↵↵↵
Error: request entity too large↵↵↵"
at readStream (/home/adrianabartolomucci/apps_nodejs/node_modules/body-parser/node_modules/raw-body/index.js:196:17)
at getRawBody (/home/adrianabartolomucci/apps_nodejs/node_modules/body-parser/node_modules/raw-body/index.js:106:12)
at read (/home/adrianabartolomucci/apps_nodejs/node_modules/body-parser/lib/read.js:76:3)
at jsonParser (/home/adrianabartolomucci/apps_nodejs/node_modules/body-parser/lib/types/json.js:127:5)
at Layer.handle [as handle_request] (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:317:13)
at /home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:335:12)
at next (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:275:10)
at /home/adrianabartolomucci/apps_nodejs/app.js:43:5
at Layer.handle [as handle_request] (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/layer.js:95:5)
at trim_prefix (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:317:13)
at /home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:284:7
at Function.process_params (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:335:12)
at next (/home/adrianabartolomucci/apps_nodejs/node_modules/express/lib/router/index.js:275:10)
at cors (/home/adrianabartolomucci/apps_nodejs/node_modules/cors/lib/index.js:185:7)
proto
:
Body
unexpected actions
hi, the does the demo work for you? I checked your live demo and the editor behaves very buggy. the cursor randomly goes to the beginning of the text, some spaces are removed and there happen a huge number of selectionaction event on the background.
AOT Build Error - Cannot find quill.module.js
Hello,
Everything works well when using JIT with ionic serve, but when I try to compile with "ionic build --release --prod", then I get this error when loading my app in the browser:
main.js:93 Uncaught Error: Module build failed: Error: ENOENT: no such file or directory, open '/Users/etc/app/node_modules/ngx-quill/src/quill.module.js'
There's a related issue commenting on how Node Modules are typically pre built here: ionic-team/ionic-app-scripts#632
If you have any advice then I'd really appreciate it. Here below are my system details.
Thank you
Tom
ionic info:
Cordova CLI: 6.3.1
Ionic Framework Version: 2.2.0
Ionic CLI Version: 2.2.1
Ionic App Lib Version: 2.2.0
Ionic App Scripts Version: 1.2.2
ios-deploy version: 1.9.1
ios-sim version: 5.0.3
OS: macOS Sierra
Node Version: v6.9.1
Xcode version: Xcode 8.3.2 Build version 8E2002
package.json excerpt:
"dependencies": {
"@angular/common": "2.4.8",
"@angular/compiler": "2.4.8",
"@angular/compiler-cli": "2.4.8",
"@angular/core": "2.4.8",
"@angular/forms": "2.4.8",
"@angular/http": "2.4.8",
"@angular/platform-browser": "2.4.8",
"@angular/platform-browser-dynamic": "2.4.8",
"@angular/platform-server": "2.4.8",
"@ionic-native/core": "^3.4.4",
"@ionic-native/onesignal": "^3.4.4",
"@ionic/storage": "2.0.0",
"cropperjs": "^0.8.1",
"intl": "^1.2.4",
"ionic-angular": "2.2.0",
"ionic-native": "2.4.1",
"ionicons": "3.0.0",
"moment": "^2.14.1",
"ng2-password-strength-bar": "^1.1.2",
"ng2-resource-rest": "1.12.2",
"rxjs": "5.0.1",
"sw-toolbox": "3.4.0",
"zone.js": "0.7.2"
},
"devDependencies": {
"@ionic/app-scripts": "1.2.2",
"typescript": "2.0.9"
},
Responsive Toolbar Collapse
Feature Request
It would be nice if we could collapse the toolbar under a hamburger button to not take up so much room on small screens.
Upgrade to ng4
Hey @KillerCodeMonkey,
Angular 4 is now available.
It would be great if you could update this project to the latest version of Angular.
Thanks!
Inline vs class
Hi,
I would like to set my ngx-quill editor to inline styles instead of classes
I am aware of this: http://quilljs.com/playground/#class-vs-inline-style
I have attempted to do this within the constraints of the ngx-quill editor but it always saves as classes instead of inline style
Could you please help
Thanks
Is there a way to "clean" text as it is pasted in?
I do not have the Clean button enabled in the toolbar. Many users copy and paste rich HTML (From Word etC) into the textbox and then they can't remove the formatting.
Is there a way to clean it on paste? (ie. it removes all formatting and then they can reformat as they want?)
Thanks
Ability to add custom toolbar options through quill-editor-toolbar to existing toolbar
I'm trying to add additional options to the toolbar which contains syntax highlighting option. In other words, something like this does not work
<quill-editor [(ngModel)]="title"
[maxLength]="5"
[minLength]="3"
[required]="true"
[modules]="{syntax:true,toolbar: [['code-block']]}"
(onContentChanged)="onContentChanged($event);">
<div quill-editor-toolbar>
<span class="ql-formats">
<button class="btn-primary">save</button>
</span>
</div>
</quill-editor>
Is there a workaround for something like this?
Include 'tslint.json' into .npmignore
when using ngx-quill as dependency in angular 2+ (in my case ^4.0.0) and try to run ´ng lint´ then you will get the following error:
Failed to load /Users/foo/projects/bar/node_modules/ngx-quill/tslint.json: Could not find custom rule directory: /Users/foo/projects/bar/node_modules/ngx-quill/node_modules/codelyzer
The tslint.json is needed for development but not as part of the distribution.
So, please add 'tslint.json' into .npmignore and publish a new version ... THX
Configurable block tag (div, paragraph)
Any ideas on how to implement the solution found here in an Angular 2 project? I'm not fond of the <p><br></p> line on enter. I think the output should look the same as what's shown in the editor.
Using Grammarly Breaks Quill
- What is Grammarly
- Download Chrome Extension
- Visit Demo Page
- Attempt to use Quill while Grammarly is enabled.
When Grammarly is enabled on a page that uses the ngx-quill Editor the editor is rendered basically useless, making selecting text impossible and inserting text into the middle of a sentence impossible. The editor I'm using to write this isn't having problems so I know it's possible to correct this issue.
Grammarly is used by a huge amount of people just wanted to let you know about this. So more devs can adopt Quill without worry of users not being able to use the editor.
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
OpenClaw
Personal AI Assistant
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.



