user1734974
user1734974

Reputation:

How to create a button that adds a string with HTML tags and classes?

Based on this link, I tried to add a new button, which allows me to have a string inserted at cursor position. It works so far, however I had to change this line:

this.quill.insertText(cursorPosition, "★");

to:

this.quill.clipboard.dangerouslyPasteHTML(cursorPosition, '<i>★</i>');

as I wanted to be able to paste HTML tag with the string.

Now, in the next step, I want to add a class with the HTML tag:

this.quill.clipboard.dangerouslyPasteHTML(cursorPosition, '<i class="my-icon">★</i>');

However, whenever I click the button now, the class is just completely discarded. In fact, instead of the tag i, I get the tag em, which works for what I want to do (italics), but it's still annoying.

How can I make sure the tags and class stay the same when I click the button? All I want to do is to click a button and have a little string enclosed in a span with a class to appear in the editor. How can I achieve this?

Upvotes: 16

Views: 3989

Answers (3)

Tarun Lalwani
Tarun Lalwani

Reputation: 146520

Update: 24-Apr-18

So it took a lot of time to actually figure this out and get it working. It is possible to do this by create your own Blot and overriding the italic blot

let Inline = Quill.import('blots/inline');

class Icon extends Inline {
  static create(value) {
    let node = super.create(value);
    if (value) {
      console.log(value)
      node.setAttribute('class', value);
    }
    return node;
  }

  static formats(domNode) {
    console.log(domNode)
    return domNode.getAttribute("class");
  }

  format(name, value) {
    console.log(name, value)
    if (name !== this.statics.blotName || !value) return super.format(name, value);
    if (value){
      this.domNode.setAttribute('class', value);
    }
  }
}
Icon.blotName = 'icon';
Icon.tagName = 'span';
Quill.register(Icon);

var BackgroundClass = Quill.import('attributors/class/background');
var ColorClass = Quill.import('attributors/class/color');
var SizeStyle = Quill.import('attributors/style/size');
Quill.register(BackgroundClass, true);
Quill.register(ColorClass, true);
Quill.register(SizeStyle, true);


var quill = new Quill('#editor-container', {
  modules: {
    toolbar: '#toolbar-container'
  },
  placeholder: 'Compose an epic...',
  theme: 'snow'
});


var customButton = document.querySelector('#custom-button');
customButton.addEventListener('click', function() {
  quill.insertText(quill.getSelection().index, "★\n", 'icon', 'fa fa-icon fa-icon-green');
});

Here is a codepen for the same

Working

Original Answer

QuillJS is rich text editor and not a HTML WYSIWYG editor. So you cannot get your own custom html inside the same

https://codepen.io/anon/pen/ZyEjrQ

In the above code pen, click source, try your code and click source again

Source view

Source view

Source view -> UI View -> Source view

Converted source view

If you try to remove the clipboard matchers, then you will nearly break the rich text functionality.

So either you leave this requirement or you pick a different editor for your job. Some threads you should look at

https://github.com/quilljs/quill/issues/1856

https://github.com/quilljs/quill/issues/1733

https://github.com/quilljs/quill/issues/1657#issuecomment-325737074

Upvotes: 10

Ricardo
Ricardo

Reputation: 1356

You can try this:

function insertStar() {
  const cursorPosition = this.quill.getSelection().index;
  this.quill.insertText(cursorPosition, "★");

  var bufferText = $(".ql-editor").html().replace(/<em class="my-icon">/g, "").replace(/<\/em>/g, "");

  var tmpOut = bufferText.replace(/★/g, "<em class='my-icon'>★</em>");

  $(".ql-editor").html(tmpOut);

  this.quill.setSelection(cursorPosition + 1);
}

Upvotes: 3

Ignacio Ara
Ignacio Ara

Reputation: 2582

As API says "The snippet is interpreted by Clipboard matchers, which may not produce the exactly input HTML." link As I have tested it removes id, class or whatever attribute you add.

You should edit the clipboard.js file to obtain this: https://github.com/quilljs/quill/blob/develop/modules/clipboard.js#L97

Other option is include an image, in this case it fits and shows it, for example:

this.quill.clipboard.dangerouslyPasteHTML(cursorPosition, "<img src=\"http://vchaspik.ua/sites/default/files/krug.png\"><i>★</i>", "silent");

Upvotes: 3

Related Questions