How to make non selectable embed custom format in quilljs
Asked Answered
E

1

14

I would like to create a custom embed format which can be styled but it's text cannot be changed. My use case is pretty similar to the hashtag case. I want to have an external button that will add an hashtag to the current selected range on the editor. But after doing this i want the hashtag to behave as a "block" so that the user cannot go there and change its text.

The only way i could accomplish this was by saying that the format's node is contenteditable=false but i'm not sure i'm going the right way as i'm having some issues with this approach, mainly:

If the hashtag is the last thing on the editor i cannot move past it (with arrows or cursor) Double clicking it to select should select the whole thing (and not individual words) (for styling) If the cursor is immediately behind the hashtag, pressing right and writing will write inside the hashtag You can check a codepen i made while experimenting with this:

  Quill.import('blots/embed');
  class QuillHashtag extends Embed {
    static create(value) {
      let node = super.create(value);
      node.innerHTML = `<span contenteditable=false>#${value}</span>`;
      return node;
    }
  }
  QuillHashtag.blotName = 'hashtag'; 
  QuillHashtag.className = 'quill-hashtag';
  QuillHashtag.tagName = 'span';

Here's the full codepen: http://codepen.io/emanuelbsilva/pen/Zpmmzv

If you guys can give me any tips on how can i accomplish this i would be glad.

Thanks.

Eddo answered 20/10, 2016 at 16:32 Comment(0)
K
4

All you need to do is to set the contenteditable attribute to false on the main span. Currently, you are doing this on the nested span.

node.setAttribute('contenteditable', false);

I modified the hashtag code from your post and applied the change.

var Embed = Quill.import('blots/embed');
class QuillHashtag extends Embed {
  static create(value) {
    let node = super.create(value);
    node.setAttribute('contenteditable', false);
    node.innerHTML = value;
    return node;
  }
}
QuillHashtag.blotName = 'hashtag';
QuillHashtag.className = 'quill-hashtag';
QuillHashtag.tagName = 'span';

Quill.register({
  'formats/hashtag': QuillHashtag
});

var quill = new Quill('#editor-container', {
  modules: {
    toolbar: [
      [{
        header: [1, 2, false]
      }],
      ['bold', 'italic', 'underline'],
      ['image', 'code-block']
    ]
  },
  placeholder: 'Compose an epic...',
  theme: 'snow' // or 'bubble'
});


document.getElementById('b').addEventListener('click', () => {
  var range = quill.getSelection();
  if (range) {
    var hashtag = prompt("Select hashtag", "foobar");
    quill.insertEmbed(range.index, 'hashtag', hashtag);
  }

});
#editor-container {
  height: 375px;
}

.quill-hashtag {
  background-color: lightgray;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.1/quill.snow.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/quill/1.3.1/quill.min.js"></script>
<div id="editor-container"></div>
<button id="b">add hashtag</button>
Kyl answered 18/10, 2018 at 20:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.