Search code examples
javascriptquill

Quill insertText producing TypeError: n.appendChild is not a function


I'm planning on implementing Quill into my website but unfortunately the insertText function is producing the following:

TypeError: n.appendChild is not a function shadow.ts:150
    wrap shadow.ts:150
    formatAt shadow.ts:70
    format embed.ts:26
    value cursor.js:25
    formatAt embed.ts:30
    formatAt container.ts:98
    forEachAt linked-list.ts:114
    formatAt container.ts:97
    formatAt block.ts:42
    value block.js:78
    value cursor.js:35
    value selection.js:110
    value quill.js:157
    a quill.js:437
    value quill.js:149
    value toolbar.js:101

I'm extending the text blot and attempting to use the documentation notes from here (copying the divider code) but the output ends up just printing true to the editor.

JS

const Text = Quill.import("blots/text");
class SchoolNameBlot extends Text {}
SchoolNameBlot.blotName = "tagName";
SchoolNameBlot.tagName = "NAME";

const toolbarOptions = [['bold', 'italic'], ['link', 'image', 'tagName']];

Quill.register(SchoolNameBlot);

const options = { 
    debug: 'info',
    theme: 'snow',
    modules: {
        toolbar: toolbarOptions
    }
}

const editor = new Quill("#msgText", options);

$("#tagName-Button").click(function() {
    let range = editor.getSelection(true);
    editor.insertText(range.index, "insertText");
});

HTML Element:

<div class="col-md-11">
    <div id="msgText"></div>
</div>

Output

Output of the inputText

From what I can tell, I am using Quill correctly so I'm not to sure why this error is being produced. I'm using the CDN's provided on their page.


Solution

  • I'm extending the text blot and attempting to use the documentation notes from here (copying the divider code) but the output ends up just printing true to the editor.

    In the link presented talking about how to clone Medium, there is no blot being created that extends blots/text. Divider is created using blots/block/embed. Basically, there are 3 types of blots that can be created:

    To help you better understand what I'm talking about, I suggest you to read a little about Parchment and Blots.

    Now, about your problem itself... As you can see from your example, you just created a blot, but didn't add any behavior to it, and you have set your created blot tag name to NAME. Of all existing tags in HTML, there is not one with the name <NAME>. Look:

    The name you give to tagName will be the HTML tag used for the result, ie what your blot will represent. If you want to add an image, for example, you need to give tagName the value IMG. For a header title, you could use h1, h2, h3, and so on.

    Looking at your code, and seeing the name "tag" written on it, it seems to me that you just want to add some stylized text. Would it be? If this is your case, look at the following example:

    let Inline = Quill.import('blots/inline');
    
    class SchoolNameBlot extends Inline {
        // Overriding this method, in this particular case, is what 
        // causes the Delta returned as content by Quill to have 
        // the desired information.
        static formats(domNode) {
            if(domNode.classList.contains('my-style')){
                return true;
            }
            else{
                return super.formats(domNode);
            }
        }
    
        formats() {
            // Returns the formats list this class (this format).
            let formats = super.formats();
    
            // Inline has the domNode reference, which in this 
            // case represents the SPAN, result defined in tagName.
            formats['tag-name'] = SchoolNameBlot.formats(this.domNode);
    
            // In the code above, it is as if we are adding this new format.
            return formats;
        }
    }
    
    SchoolNameBlot.blotName = 'tag-name';
    SchoolNameBlot.tagName = 'span';
    SchoolNameBlot.className = 'my-style';
    
    Quill.register(SchoolNameBlot);
    
    $(document).ready(function () {
        var toolbarOptions = { 
            container: [['bold', 'italic'], ['link', 'image', 'tag-name']],
            handlers: {
                'tag-name': function(){
                    this.quill.insertText(0, 'Hello', 'tag-name', true);
                }
            }
        };
    
        var quill = new Quill('#editor', {
            theme: 'snow',
            modules: {
                'toolbar': toolbarOptions
            }
        });
    });
    .my-style{
        background: rgb(254, 255, 171);
        border-radius: 2px;
        padding: 2px 2px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="//cdn.quilljs.com/1.3.6/quill.min.js"></script>
    <link href="//cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
    <p>Instructions:</p>
    <ol>
    <li>Press the invisible button (with no icon) next to the add image button.</li>
    </ol>
    <div id="editor">
      
    </div>

    To just style text, I do not advise creating a new Blot, as there is no need for something so complex. You could use Attributors. The previous code would look as:

    const Parchment = Quill.import('parchment')
    var config = {
        scope: Parchment.Scope.INLINE,
        whitelist: ['yellow', 'red', 'blue' , 'green']
    };
    var SchoolName = new Parchment.Attributor.Class('my-attributor', 'style' , config);
    Quill.register(SchoolName);
    
    $(document).ready(function () {
        var toolbarOptions = {
            container: [['bold', 'italic'], ['link', 'image', 'my-button'] , ['clean']] ,
            handlers: {
                'my-button': function () {
                    let range = this.quill.getSelection();
                    this.quill.insertText(range.index, 'Hello', 'my-attributor' , 'yellow');
                }
            }
        };
    
        var quill = new Quill('#editor', {
            theme: 'snow',
            modules: {
                'toolbar': toolbarOptions
            }
        });
    });
    .style-yellow{
        background: rgb(254, 255, 171);
        border-radius: 2px;
        padding: 2px 2px;
    }
    
    .style-red{
        background: rgb(255, 171, 171);
        border-radius: 2px;
        padding: 2px 2px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="//cdn.quilljs.com/1.3.6/quill.min.js"></script>
    <link href="//cdn.quilljs.com/1.3.6/quill.snow.css" rel="stylesheet">
    <p>Instructions:</p>
    <ol>
    <li>Press the invisible button (with no icon) next to the add image button.</li>
    </ol>
    <div id="editor">
      
    </div>

    As a final tip, you can always get more information from Quill official website, as well as from its repositories. For even more information, examples and frequently asked questions (Quill FAQ), take a look here.