The reason this is happening doesn't seem to be related to jQuery, it seems to be related to how summernote initializes an editor. The optional-editor
attribute you're grabbing is a div
element and is being initialized, not the input
element.
What happens next is summernote then takes this div and creates a couple of other div
elements inside with classes like note-editor
, note-dropzone
, note-editing-area
, etc. The inner-most div has a class called note-editable
and inside this div is your input element. The note-editable
div is what summernote considers to be the actual rich-text editor, not the input element. That said, you can still click on the input element and type in whatever you want.
Summernote places some event listeners on the onkeydown
event (see the docs here) and since it's a rich text editor it seems to be checking for the spacebar character (among others, e.g. enter
which becomes a new paragraph) so that it can escape it in the HTML (space becomes
). Since you're typing inside the note-editable
div even if you're technically typing inside your input
element, this key press will be caught by summernote and it seems to be placing the escaped space character inside the div, not inside the input. This results in the text being placed above your input element. You'll notice you can use ctrl+A
when your cursor is above the input element to highlight everything inside this editable div and you can even delete your input element.
My suggestion would be to remove the input element altogether and just use the containing div as that seems to be the most common use case scenario. You could also try overriding the onkeydown
event listener and append the space to inside the input, but this seems like a very roundabout way of trying to solve something that doesn't really need to be solved.
Edit: It looks like summernote clones the node that's designated to be the rich text editor which would end up removing any event listeners on said element, including its children, so you can't override the keydown event for the text input element before initializing summernote. Trying to provide an override callback for the keyDown
event through init configuration of summernote is possible, but very ugly and has quirks due to the pre-configured event handlers set by summernote.
In the fiddle I only used one text input and gave it the id richTextInput
. Also, I removed onchange="onAnswerChoiceChange(this);"
as this was causing an error.
To provide an override in the configuration, use this:
$(optionEditors[i]).summernote({
airMode: true,
popover: {
air: [
['font', ['bold', 'underline', 'clear']]
]
},
callbacks: {
onKeydown: function(e) {
if (e.keyCode === 32) { // catch "space"
e.preventDefault();
$('.note-editable>#richTextInput').val($('.note-editable>#richTextInput').val() + " ");
}
}
}
});
The note-editable
class is the container div
created by summernote after initialization. We need to specify this because summernote automatically copies all contents of the "rich-text-editor-to-be" before initialization, then hides them with display:none
so just trying to reference the input with $('#richTextInput')
will not work because you'll be grabbing the hidden input.
Quirks: You'll notice that if you try to use this code summernote will try to automatically provide focus to the actual rich text editor div which is due to the behavior provided in the event listener registered by summernote. You could get around this by providing a timeout like so:
setTimeout(function() {
$('.note-editable>#richTextInput').focus();
}, 1);
As I said before, this is really not a good solution and although it may do the trick, I think the better route would be to ditch the text input altogether and just initialize a div or textarea without anything nested inside as the library expects. It'd be easier to do that and then style them accordingly. Using the material design styles/components probably won't work well together since material needs input or textarea elements and summernote transforms the textarea into a div, but that's a different problem.