Skip to content

Instantly share code, notes, and snippets.

@tinmegali
Last active August 7, 2019 22:01
Show Gist options
  • Save tinmegali/61d526bc86bad7f9224fed1ec539a5aa to your computer and use it in GitHub Desktop.
Save tinmegali/61d526bc86bad7f9224fed1ec539a5aa to your computer and use it in GitHub Desktop.

Library ngx-quill

Quill configuration

Installing library

  • npm install ngx-quill
  • for projects using Angular < v5.0.0 install npm install ngx-quill@1.6.0
  • install @angular/core, @angular/common, @angular/forms, @angular/platform-browser, quill and rxjs - peer dependencies of ngx-quill include theme stylings: bubble.css, snow.css of quilljs in your index.html, or add them in your css/scss files with @import statements, or add them external stylings in your build process.

How to use it

import QuillModule from ngx-quill

import { QuillModule } from 'ngx-quill'

add QuillModule to 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!
<!-- quill style -->
<link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
  • 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 :)!

Tips

html sample

<quill-editor formControlName="description"
  placeholder="Enter Description text...."
  format="html"
  [styles]=editorStyle
  [modules]="editorConfig"
  (onContentChanged)="onEditorContentChange($event)"
  id="field_description">
</quill-editor>

Setting limit to text

onEditorContentChange(e: any) {
  this.limitEditTextSize(e);
}

limitEditTextSize(e: any) {
  const textLimit = 10000;
  if (e.editor.getLength() > textLimit) {
    e.editor.deleteText(textLimit, e.editor.getLength());
  }
}

Defining configuration and style

editorConfig = {
  toolbar: [
    ['bold', 'italic', 'underline'], // toggled buttons
    [{ list: 'ordered' }, { list: 'bullet' }],
    ['link']
  ]
};

editorStyle = {
  height: '250px'
};

Show formatted content

 <span [innerHTML]="course.description"></span>

Fix bold format

On styles.scss

strong {
    font-weight: bold !important;
}

Jhipster

To use Quill extensions on jhipster, such as quill-image-resize, it is important to defile window.Quill as a global variable. Edit file webpack.common.js

module.exports = (options) => (
  {
  // ...
    pluguins: [
      // ...
      new webpack.ProvidePlugin({
        'window.Quill': 'quill/dist/quill.js'
      }),
      // ...
    ]
  }
);

Image Resize

  • npm install quill-image-resize-module
  • Register ImageResize module on component
  • Turn ImageResize option on in Quill Edit
// Component class
import * as QuillNamespace from 'quill';
let Quill: any = QuillNamespace;

import ImageResize from 'quill-image-resize-module';
Quill.register('modules/imageResize', ImageResize);

editorConfig = {
        toolbar: [
            ['bold', 'italic', 'underline'], // toggled buttons
            [{ list: 'ordered' }, { list: 'bullet' }],
            ['link'],
            ['image', 'video']
        ],
        imageResize: {},
    };
<quill-editor formControlName="description"
                                  placeholder="Enter Description text...."
                                  format="html"
                                  [styles]=editorStyle
                                  [modules]="editorConfig"

                                  (onContentChanged)="onEditorContentChange($event)"
                                  id="field_description">
                    </quill-editor>
<link rel="manifest" href="manifest.webapp" />
<link rel="stylesheet" href="content/css/loading.css">
<!-- jhipster-needle-add-resources-to-root - JHipster will add new resources here -->
<!-- quill style -->
\!h <link href="https://cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
</head>
<body>
import { QuillModule } from 'ngx-quill';
@NgModule({
imports: [FrontendSharedModule, RouterModule.forChild(ENTITY_STATES), QuillModule.forRoot()]
\!h import { QuillModule } from 'ngx-quill';
@NgModule({
\!h imports: [NgbModule.forRoot(), InfiniteScrollModule, CookieModule.forRoot(), FontAwesomeModule, QuillModule.forRoot()],
exports: [FormsModule, ReactiveFormsModule, CommonModule, NgbModule, NgJhipsterModule, InfiniteScrollModule, FontAwesomeModule]
})
export class FrontendSharedLibsModule {
}
<form [formGroup]="form" name="editForm" role="form" novalidate (ngSubmit)="save()" #editForm="ngForm">
<!-- Id -->
<div class="form-group" [hidden]="!course.id">
<label for="id" jhiTranslate="global.field.id">ID</label>
<input type="text" class="form-control" id="id" name="id"
formControlName="id" readonly />
</div>
<!-- Name -->
<div class="form-group">
<label class="form-control-label" jhiTranslate="frontendApp.courseCourse.name" for="field_name">Name</label>
<input type="text" class="form-control" name="name" id="field_name"
formControlName="name" required/>
<div [hidden]="!(form.get('name')?.dirty && form.get('name')?.invalid)">
<small class="form-text text-danger"
[hidden]="!form.get('name')?.errors?.required" jhiTranslate="entity.validation.required">
This field is required.
</small>
</div>
</div>
<!-- WYSIWYG Editor -->
<div class="form-group">
<label class="form-control-label" jhiTranslate="frontendApp.courseCourse.description" for="description">Description</label>
<quill-editor formControlName="description"
placeholder="Enter Description text...."
format="html"
[styles]=editorStyle
[modules]="editorConfig"
(onContentChanged)="onEditorContentChange($event)"
id="field_description">
</quill-editor>
</div>
</form>
import { FormBuilder, FormControl, FormGroup } from '@angular/forms';
@Component({
selector: 'jhi-course-update',
templateUrl: './course-update.component.html'
})
export class CourseUpdateComponent implements OnInit {
// using reactive forms
form: FormGroup;
// editor configuration
editorConfig = {
toolbar: [
['bold', 'italic', 'underline'], // toggled buttons
[{ list: 'ordered' }, { list: 'bullet' }],
['link']
]
};
// editor style
editorStyle = {
height: '250px'
};
constructor(
protected courseService: CourseService,
protected experienceService: ExperienceService,
protected accountService: AccountService,
protected activatedRoute: ActivatedRoute,
protected eventManager: JhiEventManager,
protected jhiAlertService: JhiAlertService,
\!h protected fb: FormBuilder
) {}
setNewForm() {
this.form = new FormGroup({
id: new FormControl(),
institutionId: new FormControl(),
name: new FormControl(),
description: new FormControl()
});
}
setFormValue(c: ICourse) {
this.form = this.fb.group({
id: c.id,
institutionId: c.institutionId,
name: c.name,
description: c.description
});
}
getFormValue() {
this.course.name = this.form.get('name').value;
this.course.description = this.form.get('description').value;
this.course.institutionId = this.form.get('institutionId').value;
console.log('--description: ' + this.course.description);
}
// editor change callback
onEditorContentChange(e: any) {
this.limitEditTextSize(e);
}
// set limit to editor text
limitEditTextSize(e: any) {
const textLimit = 10000;
if (e.editor.getLength() > textLimit) {
e.editor.deleteText(textLimit, e.editor.getLength());
}
}
save() {
this.isSaving = true;
this.getFormValue();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment