quill-better-table
quill-better-table copied to clipboard
Is there any way to display operationMenu buttons in quill's toolbar instead of the right click pop up ?
this is my best failed try :
import { Component, ViewChild, Output, EventEmitter, AfterViewInit, Inject, PLATFORM_ID, ElementRef } from '@angular/core';
import { FormControl, FormGroup, Validators, ReactiveFormsModule, NgForm, FormsModule } from '@angular/forms';
import { CommonModule, isPlatformBrowser } from '@angular/common';
import { combineLatest } from 'rxjs';
import { first } from 'rxjs/operators';
import Quill from 'quill';
import QuillBetterTable from 'quill-better-table'
import { Post } from '../../models/Post';
import { AuthService } from "../../services/auth.service";
import { PostService } from "../../services/post.service";
import { DatamediatorpostsService } from '../../services/datamediator/datamediatorposts.service';
import DOMPurify from 'dompurify';
@Component({
selector: 'app-createpost',
standalone: true,
imports: [CommonModule, ReactiveFormsModule, FormsModule],
templateUrl: './createpost.component.html',
styleUrls: ['./createpost.component.css']
})
export class CreatepostComponent implements AfterViewInit {
@ViewChild("editor", { static: false }) editorElementRef!: ElementRef;
@Output() create: EventEmitter<any> = new EventEmitter();
selectedTopic!: number;
selectedSubtopic!: number;
form: FormGroup;
quillEditor: any;
constructor(
@Inject(PLATFORM_ID) private platformId: object,
private authService: AuthService,
private postService: PostService,
private datamediatorpostsService: DatamediatorpostsService
) {
this.form = this.createFormGroup();
this.datamediatorpostsService.getSelectedTopic$().subscribe(topic => {
if (topic != null) {
this.selectedTopic = topic;
}
});
this.datamediatorpostsService.getSelectedSubTopic$().subscribe(subtopic => {
if (subtopic != null) {
this.selectedSubtopic = subtopic;
}
});
}
ngAfterViewInit(): void {
if (isPlatformBrowser(this.platformId) && this.editorElementRef) {
this.initializeQuillEditor();
}
}
async initializeQuillEditor(): Promise<void> {
const { default: Quill } = await import('quill');
const { default: QuillBetterTable } = await import('quill-better-table');
Quill.register('modules/better-table', QuillBetterTable, true);
this.quillEditor = new Quill(this.editorElementRef.nativeElement, {
theme: 'snow',
modules: {
table: false,
'better-table': {
operationMenu: {
items: {
insertColumnRight: false,
insertColumnLeft: {
text: 'Insert Column',
},
insertRowUp: {
text: 'Insert Row Up',
},
insertRowDown: {
text: 'Insert Row Down',
},
mergeCells: false,
unmergeCells: false,
deleteColumn: {
text: 'Delete Selected Column',
},
deleteRow: {
text: 'Delete Selected Row',
},
deleteTable: {
text: 'Delete Table',
}
}
}
},
toolbar: {
container: [
['bold', 'italic', 'underline', 'strike'],
['blockquote', 'code-block'],
[{ 'header': 1 }, { 'header': 2 }],
[{ 'list': 'ordered' }, { 'list': 'bullet' }],
[{ 'script': 'sub' }, { 'script': 'super' }],
[{ 'indent': '-1' }, { 'indent': '+1' }],
[{ 'direction': 'rtl' }],
[{ 'size': ['small', false, 'large', 'huge'] }],
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
[{ 'color': [] }, { 'background': [] }],
[{ 'font': [] }],
[{ 'align': [] }],
['clean'],
[{ 'better-table': true }],
['insertColumnLeft', 'insertRowUp', 'deleteTable']
],
handlers: {
'better-table': () => {
const tableModule: any = this.quillEditor.getModule('better-table');
if (tableModule && tableModule.options) {
tableModule.options.show();
} else {
console.error('Better Table Module or operationMenu is not defined');
}
},
'insertColumnLeft': () => {
const tableModule: any = this.quillEditor.getModule('better-table');
if (tableModule && tableModule.options) {
tableModule.options.insertColumnLeft();
} else {
console.error('Better Table Module or operationMenu is not defined');
}
},
'insertRowUp': () => {
const tableModule: any = this.quillEditor.getModule('better-table');
if (tableModule && tableModule.options) {
tableModule.options.insertRowUp();
} else {
console.error('Better Table Module or operationMenu is not defined');
}
},
'deleteTable': () => {
const tableModule: any = this.quillEditor.getModule('better-table');
if (tableModule && tableModule.options) {
tableModule.operationMenu.deleteTable();
} else {
console.error('Better Table Module or operationMenu is not defined');
}
}
}
}
}
});
console.log('Quill editor initialized with full better-table configuration:', this.quillEditor);
this.quillEditor.on('text-change', () => {
const formBodyControl = this.form.get('body');
if (formBodyControl) {
formBodyControl.setValue(this.quillEditor.root.innerHTML);
} else {
console.error('Form control "body" is not defined');
}
});
this.editorElementRef.nativeElement.addEventListener('contextmenu', (event: MouseEvent) => {
event.preventDefault();
const tableModule: any = this.quillEditor.getModule('better-table');
if (tableModule && tableModule.operationMenu) {
tableModule.operationMenu.show(event.clientX, event.clientY);
} else {
console.error('Better Table Module or operationMenu is not defined');
}
});
}
onInsertTable() {
const tableModule = this.quillEditor.getModule('better-table');
if (tableModule) {
tableModule.insertTable(5, 5);
} else {
console.error('Better Table Module is not defined');
}
}
createFormGroup(): FormGroup {
const formGroup = new FormGroup({
title: new FormControl('', [
Validators.required,
Validators.minLength(5)
]),
body: new FormControl('', [
Validators.required,
Validators.minLength(10)
])
});
return formGroup;
}
onSubmit(formData: Pick<Post, "title" | "body">): void {
const userId = this.authService.userId;
if (userId) {
formData.body = DOMPurify.sanitize(formData.body);
this.postService.createPost(this.selectedTopic, this.selectedSubtopic, formData, userId).subscribe(() => {
this.create.emit(null);
this.form.reset();
});
} else {
console.error('Authorization error');
}
}
}
it seems the i cannot access (or don't know how to access) operationMenu functionality so i could handle the methods in my handler