PomeGranate PomeGranate - 5 months ago 176
HTML Question

How can I add a new format (<hr> tag) to Quill.js?

I want to add a button which would add a

<hr>
tag to the quill.js (beta) editor.

Here the fiddle.

<!-- Initialize Quill editor -->
<div id="toolbar-container">
<span class="ql-formats">
<button class="ql-hr"></button> //here my hr-button
</span>
<span class="ql-formats">
<button class="ql-bold"></button>
<button class="ql-italic"></button>
</span>
</div>

<div id="editor">

<p>Hello World!</p>
<hr> // this gets replaced by <p> tag automatically *strange*
<p>Some initial <strong>bold</strong> text</p>
</div>


I initialize my editor:

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


Here I add a
<h1>
tag functionality to my editor and it works very well:

$('.ql-hr').on("click",function(){

var range = quill.getSelection();
var text = quill.getText(range.index, range.length);
quill.deleteText(range.index, range.length);
quill.pasteHTML(range.index, '<h1>'+text+'</h1>');
})


Now I try the same for a
<hr>
tag, which doesn't work at all:

$('.ql-hr').on("click",function(){

var range = quill.getSelection();
quill.pasteHTML(range.index, '<hr>');
})


the
<hr>
tag in the initial
div#editor
gets replaced with a
<p>
tag. And the button functionality I added doensn't work for
<hr>
tags, but for other tags it works. I know the
<hr>
tag is not implemented to Quill.js, that's also why I get this console output:


quill:toolbar ignoring attaching to nonexistent format hr select.ql-hr


Is there any way to fix this?

Answer

I have still no idea why the question has downvotes, but however here is the solution:

Import the embed blot - important: not "block", not "embed", "block/embed"!

 var Embed = Quill.import('blots/block/embed');

Define a new class that extends that Embed

        class Hr extends Embed {
            static create(value) {
                let node = super.create(value);
                // give it some margin
                node.setAttribute('style', "height:0px; margin-top:10px; margin-bottom:10px;");
                return node;
            }
        }

Define your tag

        Hr.blotName = 'hr'; //now you can use .ql-hr classname in your toolbar
        Hr.className = 'my-hr';
        Hr.tagName = 'hr';

Write a custom handler for the <hr> button

        var customHrHandler = function(){
            // get the position of the cursor
            var range = quill.getSelection();
            if (range) {
                // insert the <hr> where the cursor is
                quill.insertEmbed(range.index,"hr","null")
            }
        }

Register your new format

        Quill.register({
            'formats/hr': Hr
        });

Instantiate your Editor with the right selectors in your HTML

       var quill = new Quill('#editor', {
          modules: {
            toolbar: { container: '#toolbar-container',
                handlers: {
                    'hr': customHrHandler
                }
            }
          },
          theme: 'snow'
        });

The HTML part remains the same.

Thank you, you helpful community.