jQuery Summernote custom button function

Sanya picture Sanya · Apr 14, 2015 · Viewed 18.9k times · Source

I have a jsFiddle here -> http://jsfiddle.net/cm910t89/2/

I created a custom button in Summernote WYSIWYG Editor and I can't seem to get my function to work properly inside the plugin.

I want the user to be able to highlight (or select using their cursor) any text within the editor and then click my custom button which will wrap that selected text in a span tag with a special class of 'snote'.

Right now I can wrap the selected in a span tag with that class, but all of the formatting within the editor gets erased.

Can anyone help so that the selected text gets wrapped in the span tag AND the formatting remains the same?

jsFiddle -> http://jsfiddle.net/cm910t89/2/

$(document).ready(function() {
var editor = $('#summernote');
editor.summernote({
    height: ($(window).height() - 250),
    focus: false,
    toolbar: [
            ['style', ['bold', 'italic', 'underline', 'clear']],
            ['font', ['strikethrough']],
            ['fontsize', ['fontsize']],
            ['para', ['ul', 'ol', 'paragraph']],
            ['height', ['height']],
            ['view', ['fullscreen', 'codeview']],
        ],
    oninit: function() {
        // Add "open" - "save" buttons
        var noteBtn = '<button id="makeSnote" type="button" class="btn btn-default btn-sm btn-small" title="Identify a music note" data-event="something" tabindex="-1"><i class="fa fa-music"></i></button>';            
        var fileGroup = '<div class="note-file btn-group">' + noteBtn + '</div>';
        $(fileGroup).appendTo($('.note-toolbar'));
        // Button tooltips
        $('#makeSnote').tooltip({container: 'body', placement: 'bottom'});
        // Button events
        $('#makeSnote').click(function(event) {
            var highlight = window.getSelection(),  
            spn = '<span class="snote" style="color:blue;">' + highlight + '</span>',
            text = $('.note-editable').children('p').text(),
            range = highlight.getRangeAt(0),
            startText = text.substring(0, range.startOffset), 
            endText = text.substring(range.endOffset, text.length);

            $('.note-editable').html(startText + spn + endText);
        });
     },

});

Answer

Denis Ali picture Denis Ali · Apr 22, 2015

Since $('.note-editable') is a textarea, when you call .text() it will get only the text for the element, loosing all the html that the plugin summernote is adding to show nicely for you.

You don't need all that code to replace the highlighted text. In fact, all you need is that range object you created! With him, you call .deleteContents()to clear the selected range and then call .insertNode(node) to insert a dynamic created span with the text:

$('#makeSnote').click(function(event) {
     var highlight = window.getSelection(),  
         spn = document.createElement('span'),
         range = highlight.getRangeAt(0)

     spn.innerHTML = highlight;
     spn.className = 'snote';  
     spn.style.color = 'blue';

     range.deleteContents();
     range.insertNode(spn);
});

Here's working fiddle.