Reputation: 1
I have try several ways of making the quill-better-table work with no success, most of the examples out there are not for Angular, I'm getting an error that says "Cannot read property 'insertTable' of undefined" I will include my code and error below, please help me out. Note: this is meant for an application used in production.
This is my HTML code:
<div class="card">
<div ibmGrid>
<div ibmRow>
<div ibmCol>
<button ibmButton="secondary" size="sm" (click)="onInsertTable()">Add table</button>
<form [formGroup]="editorForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<quill-editor [styles]="editorStyle" [modules]="config" formControlName="editor" (onEditorCreated)="editorCreated($event)"></quill-editor>
</div>
<button ibmButton="primary">Save changes</button>
</form>
</div>
</div>
</div>
This is my Angular TS code:
import { Component, OnInit, AfterViewInit, ChangeDetectionStrategy } from '@angular/core';
import { FormControl, FormGroup } from '@angular/forms';
import { DropdownModule, ModalService } from 'carbon-components-angular';
import * as quillBetterTable from 'quill-better-table';
interface Quill {
getModule(moduleName: string);
}
interface BetterTableModule {
insertTable(rows: number, columns: number): void;
}
// declare const require: any;
// let Quill: any = null;
@Component({
selector: 'app-fnl-report',
templateUrl: './fnl-report.component.html',
styleUrls: ['./fnl-report.component.scss'],
// changeDetection: ChangeDetectionStrategy.OnPush
})
export class FnlReportComponent implements OnInit {
editorForm: FormGroup
public quill: Quill;
editorStyle = {
height: '500px',
backgroundColor: '#fff'
}
config = {
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'] // link and image, video ['link', 'image', 'video']
]
}
constructor() { }
ngOnInit() {
this.editorForm = new FormGroup({
'editor': new FormControl(null)
});
}
public editorCreated(event: Quill): void {
this.quill = event;
// Example on how to add new table to editor
this.addNewtable();
}
private get tableModule(): BetterTableModule {
return this.quill.getModule("better-table");
}
private addNewtable(): void {
this.tableModule.insertTable(3, 3);
console.log('Hi');
}
onSubmit() {
console.log(this.editorForm.get('editor').value);
}
onInsertTable() {
// const tableModule = this.quill.getModule('better-table');
// tableModule.insertTable(3, 3);
}
}
This is my module file:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { LoadingModule, DropdownModule, GridModule, FileUploaderModule, DialogModule, ButtonModule } from 'carbon-components-angular';
import { Help16Module } from '@carbon/icons-angular/lib/help/16';
import { UploadFilesComponent } from './upload-files/upload-files.component';
import { FnlReportComponent } from './fnl-report/fnl-report.component';
import { ReactiveFormsModule } from '@angular/forms';
import { QuillModule, QuillConfig } from "ngx-quill";
import * as Quill from "quill";
import QuillBetterTable from "quill-better-table";
Quill.register(
{
"modules/better-table": QuillBetterTable
},
true
);
const quillConfig: QuillConfig = {
modules: {
table: false, // disable table module
"better-table": {
operationMenu: {
items: {
unmergeCells: {
text: "Another unmerge cells name"
}
},
color: {
colors: ["#fff", "red", "rgb(0, 0, 0)"], // colors in operationMenu
text: "Background Colors" // subtitle
}
}
},
keyboard: {
bindings: QuillBetterTable.keyboardBindings
}
}
};
@NgModule({
declarations: [
UploadFilesComponent,
FnlReportComponent
],
imports: [
CommonModule,
LoadingModule,
DropdownModule,
GridModule,
ButtonModule,
FileUploaderModule,
Help16Module,
DialogModule,
ReactiveFormsModule,
QuillModule.forRoot(quillConfig)
],
providers:[],
exports: []
})
export class ImsHubModule { }
This are my css imports for quill:
@import '~quill/dist/quill.core.css';
@import '~quill/dist/quill.bubble.css';
@import '~quill/dist/quill.snow.css';
This is my package.json dependencies for quill and quill table:
"dependencies": {
"ngx-quill": "^13.0.1",
"quill": "^1.3.7",
"quill-better-table": "^1.2.10"
}
This is the error that I'm getting:
FnlReportComponent.html:24 ERROR TypeError: Cannot read property 'insertTable' of undefined
Upvotes: 0
Views: 5656
Reputation: 71
Unfortunately, you cannot use quill-better-table with ngx-quill wrapper. ngx-quill is still based on quilljs v1. quill-better-table requires quilljs v2.0.0-dev.3. You can read about that in the Requirements section: here
I can share with you how I implemented simple paste and read table in my case. Its inspired by this article and created with custom block. And its not a correct way to add elements to quill. But we are using editor internally so we are sure that it is in safe hands.
import Quill from 'quill';
const BlockEmbed = Quill.import('blots/block/embed');
export class TableBlockEmbed extends BlockEmbed {
static blotName = 'TableBlockEmbed';
static tagName = 'table';
static create(value) {
const node = super.create();
let valueToReturn = value;
if (!value.includes('assignedTableId')) {
const tableId = `assignedTableId-${Date.now()}`;
valueToReturn = value
.replace('#tableId', `#${tableId}`)
.replace('table-layout: fixed;', '');
node.setAttribute('id', tableId);
} else {
const existedId = valueToReturn.match(/#assignedTableId-(\d+)/i)[1];
node.setAttribute('id', `assignedTableId-${existedId}`);
}
node.innerHTML = this.transformValue(valueToReturn);
return node;
}
static transformValue(value) {
let handleArr = value.split('\n');
handleArr = handleArr.map(e => e.replace(/^[\s]+/, '')
.replace(/[\s]+$/, ''));
return handleArr.join('');
}
static value(node) {
return node.innerHTML;
}
}
constructor() {
Quill.register(TableBlockEmbed, true);
}
onEditorCreated(quill: Quill): void {
quill.clipboard.addMatcher('TABLE', (node, delta) => {
const Delta = Quill.import('delta');
const tableTagStyles = node.getAttribute('style');
return new Delta([
{
insert: {
TableBlockEmbed:
`<style>#tableId {${tableTagStyles} margin: 0 auto !important; }</style>` + delta.ops[0].insert.TableBlockEmbed
}
}
]);
});
}
quill-view,
quill-editor{
::ng-deep {
table {
width: 100%; // if table has no width - then give it by default 100%
max-width: 100% !important;
box-sizing: border-box;
}
}
}
I know this solution is just workaround but until waiting for ngx-quill based on quill 2, I was able at least to give the feature of pasting tables inside the editor which looks quite nice.
Example:
table in office word:
table in ngx-quill:
table in excel:
table in ngx-quill:
Upvotes: 2