How to add a non editable tag to content in Quill editor
Asked Answered
H

1

12

I want to add a couple of pre-built labels like

<div class="label"> Label Text <span>x</span><div>

to the html content in the quill editor. Add such a tag should not be a problem in itself. However I don't want the user to be able to edit the text inside the label. The cursor should not even be allowed to be placed inside the label. On delete the whole div should be deleted. The whole label should act like an image in some sense. Is it possible ?

Haulm answered 20/9, 2016 at 19:7 Comment(3)
have you solved your issue ?Polynesia
@Polynesia Nope.. :( Not sure if quill is outdated or the question!Haulm
#40160339Aquatic
E
14

You should be able to achieve this by writing your own Blot:

class Label extends Parchment.Embed {
  static create(value) {
    const node = super.create(value);
    node.innerText = value;
    // Remember to set this so users can't edit
    // the label's content
    node.contentEditable = 'false';
    this._addRemovalButton(node);
    return node;
  }

  static value(node) {
    // Only return the text of the first child
    // node (ie the text node), otherwise the
    // value includes the contents of the button
    return node.childNodes[0].textContent;
  }

  static _addRemovalButton(node) {
    const button = document.createElement('button');
    button.innerText = 'x';
    button.onclick = () => node.remove();
    button.contentEditable = 'false';
    node.appendChild(button);

    // Extra span forces the cursor to the end of
    // the label, otherwise it appears inside the
    // removal button
    const span = document.createElement('span');
    span.innerText = ' ';
    node.appendChild(span);
  }
}
Label.blotName = 'label';
Label.tagName = 'SPAN';
Label.className = 'ql-label';

You register it with Quill:

Quill.register(Label);

And finally, you can use it in a similar way to an image or other embeds:

quill.updateContents(
  new Delta().insert({ label: 'foo' })
);

NB: Any styling you need can be applied with the .ql-label class:

.ql-label {
  background-color: lightgrey;
  padding: 0.3em;
  margin: 0 0.2em;
}

.ql-label button {
  margin-left: 0.3em;
}

Finally finally: a working example.

Equate answered 10/4, 2019 at 15:26 Comment(4)
Thanks! I have a similar use case, but that requires adding the Blots per content. I've created a new question for that -- #56048510Rhapsodic
Thanks for your answer! but where exactly should i define the class LabelKilian
Any idea how you can make your blot just maintain its contents including its attributes? For example I'd like to have a blot tag "var" that acts like a variable that can be expanded and updated lately in the backend. So in addition to its inner html which is visible, I want it to have a data-var attribute that is also kept so it can be part of the html serialized back to the backend. Also would be nice if it could keep all its child elements too. Atm it seems Quill strips away everything but the inner html of the blot.Monatomic
@Monatomic you'll probably want to add a format. Have a look at how Quill deals with image metadata for example: github.com/quilljs/quill/blob/…Equate

© 2022 - 2024 — McMap. All rights reserved.