Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is there any way to display operationMenu buttons in quill's toolbar instead of the right click pop up ? #103

Open
Denis-Dev-2020 opened this issue Jun 26, 2024 · 0 comments

Comments

@Denis-Dev-2020
Copy link

Denis-Dev-2020 commented Jun 26, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant