jQuery Summernote custom button function
Asked Answered
R

3

12

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);
        });
     },

});
Ryter answered 14/4, 2015 at 16:1 Comment(3)
It's not a complete solution, because it gets rid of all the <p> tags and the entirety of the <ol> tag, but here's what I've got so far: jsfiddle.net/cm910t89/27Kaczmarek
This helps. Thanks. If you can also keep the same format then you win!Ryter
Just to note, the onInit function must be called within callbacks section: summernote.org/deep-dive/#oninitKeverne
Z
9

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.

Zealous answered 22/4, 2015 at 2:40 Comment(2)
It still loses the formatting within the highlighted areaKaczmarek
Should add some validation to prevent the user to edit text outside the editable area?Riana
G
1

Try this

$('#makeSnote').click(function(event) {
    var highlight = window.getSelection(),  
    spn = '<span class="snote" style="color:blue;">' + highlight + '</span>',
    text = $(highlight.anchorNode).text(),
    range = highlight.getRangeAt(0),
    startText = text.substring(0, range.startOffset), 
    endText = text.substring(range.endOffset, text.length);
    $(highlight.anchorNode).replaceWith(startText + spn + endText);
});

I used the anchorNode instead, beacause you have other HTML Node other than Text in your TextArea.

Genesisgenet answered 27/4, 2015 at 9:19 Comment(0)
M
0

I haven't used SummerNote but looking at the fiddles, it is a wrapper converting textarea to a contenteditable div. As it's a div, the spacing is preserved with <p> and <br> tags, so to keep formatting you just need to get the innerHTML as opposed to the Text. The answer from +Denis Ali should work as it leaves the tags exactly where they are and only deletes/reinjects the selected part.

You can use innerHTML (JS) or $().html() (Jq) to get the formatted content instead of .text but if neither +Denis's or this works, there has to be something else having an impact. Denis's should have worked based on your fiddle and libraries.

Machado answered 28/4, 2015 at 17:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.