2

I'm using Angular and ngx-quill. I have a custom toolbar button that will insert text with certain attributes. I want to select that text when it is clicked.

Here's what I have so far:

export class InsertDemographic extends Embed {
  static blotName: string = "demographic";
  static tagName: string = "span";
  static className: string = "demographic";

  static create(demographic: Demographic) {
    let node = super.create();
    node.setAttribute('data-demographic_id', demographic.id);
    node.innerHTML = `[${demographic.name.replace(" ","_")}]`;
    node.addEventListener("click", () => {
        console.log(this);
        /* const range = this.quill.getSelection(true);
        this.quill.setSelection(range.index - 1, 1, 'user'); */
    });
    
    return node;
  }

  static value(node){
    return {
        name: node.textContent.replace(/[\[\]]/g,""),
        id: node.dataset.demographic_id
    } as Demographic;
  }
}

I've added a click event listener which should get the current quill instance in order to get and set the selection. The commented code would work but I have no idea how to get the quill instance!

Currently this code is in a file that is separate from my editor component that extends the toolbar and maps custom icons etc. This separate file being outside the component makes it hard to manage the quill instance, not sure what the correct approach is.

Jake Zeitz
  • 2,429
  • 3
  • 23
  • 43

1 Answers1

4

Short answer

Here's a utility method for grabbing a Quill instance from any child node:

function findQuill(node) {
  while (node) {
    const quill = Quill.find(node);
    if (quill instanceof Quill) return quill;
    node = node.parentElement;
  }
}

Long answer

Sometimes trying to access the Quill instance from within a blot itself can feel like fighting Quill, which is a little bit of an anti-pattern. Sometimes the more "Quill-y" way of doing things might be to use a module:

import Module from 'quill/core/module';

export class Demographics extends Module {
  constructor(quill, options) {
    super(quill, options);
    quill.root.addEventListener('click', (event) => this.handleClick(event));
  }

  handleClick(event) {
    const node = event.target;
    const demographic = node.closest('.demographic');
    if (!demographic) return;
    const blot = Quill.find(node);
    const index = this.quill.getIndex(blot);
    const length = blot.length();
    this.quill.setSelection(index, length);
  }
}

I've put together a working example (working on the strong tag for simplicity).

Alec
  • 2,432
  • 2
  • 18
  • 28