The problem is that when I click on the option/button of the HTML code editor -> <>and paste some code, content, text or anything, the code HTML
that is displayed in <textarea>
it is encoded in entities HTML
, therefore, so that it returns to be code HTML
I have to make one enteror some change in the text of the editor in the options of the buttons Bold -> B, italic -> Iamong others, to make code again HTML
.
$(function() {
function formatHtmlCode(str) {
var p = document.createElement('p');
p.innerHTML = str.trim();
return format(p, 0).innerHTML;
}
function format(node, level) {
var indentBefore = new Array(level++ + 1).join(' '),
indentAfter = new Array(level - 1).join(' '),
textNode;
for (var i = 0; i < node.children.length; i++) {
textNode = document.createTextNode('\n' + indentBefore);
node.insertBefore(textNode, node.children[i]);
format(node.children[i], level);
if (node.lastElementChild == node.children[i]) {
textNode = document.createTextNode('\n' + indentAfter);
node.appendChild(textNode);
}
}
return node;
}
$('#editControls a').click(function(e) {
switch ($(this).data('role')) {
case 'h2':
case 'h3':
case 'p':
document.execCommand('formatBlock', false, $(this).data('role'));
break;
case 'code':
codeMode = !codeMode;
if (codeMode) {
var formattedHtml = formatHtmlCode(htmlDiv.html());
htmlDiv.css("white-space", "pre");
htmlDiv.text(formattedHtml);
var editor = $("#editor");
editor.addClass("black-bg-colr codeMode");
//editor.attr('id', 'editor newID');
} else {
htmlDiv.css("white-space", "normal");
htmlDiv.html(htmlDiv.text().replace(/\r?\n|\r/g, ""));
var editor = $("#editor");
editor.removeClass("black-bg-colr codeMode");
//editor.attr('id', 'editor');
}
break;
default:
document.execCommand($(this).data('role'), false, null);
break;
}
});
let codeMode = false;
let htmlDiv = $("#editor");
htmlDiv.on('keyup', function(e) {
if (!e.shiftKey && e.keyCode === 13) {
document.execCommand('formatBlock', false, 'p');
} else if (e.shiftKey) {
document.execCommand('formatBlock', false, 'p');
}
});
htmlDiv.on("paste", function(e) {
e.preventDefault();
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
document.execCommand('formatBlock', false, 'p');
document.execCommand('insertText', false, text);
});
htmlDiv.on("input", function(e) {
$(".editor-preview").val(htmlDiv.html());
$(".editor-preview").keyup();
});
$('.editor-preview').keyup(function() {
var contentAttr = $(this).attr('class');
if (!codeMode) {
var value = $(this).val();
$('.' + contentAttr).html(value);
} else {
$('.' + contentAttr).html(htmlDiv.text());
}
});
});
.fieldsets {
border: 1px solid #ccc;
padding: 1em;
}
#editControls {
overflow: auto;
border-top: 1px solid transparent;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
border-color: silver;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding: .5em 1em .5em 1em;
background-color: #fbfbfb;
width: 100%;
/* max-width: 950px; */
}
#editor {
resize: vertical;
overflow: auto;
border: 1px solid silver;
border-bottom-right-radius: 5px;
border-bottom-left-radius: 5px;
min-height: 100px;
padding: 1em;
background-color: white;
width: 100%;
color: #333;
/* max-width: 950px; */
}
#preview {
padding: 1em;
margin: 0 auto;
width: 97%;
border-top: 1px dotted #c8ccd0;
border-bottom: 1px dotted #c8ccd0;
clear: both;
}
.btn-group>.btn-editor:first-child {
margin-left: 0;
-webkit-border-top-left-radius: 4px;
-moz-border-radius-topleft: 4px;
border-top-left-radius: 4px;
-webkit-border-bottom-left-radius: 4px;
-moz-border-radius-bottomleft: 4px;
border-bottom-left-radius: 4px;
}
.btn-group a {
text-decoration: none;
}
.btn-not-space {
position: relative;
float: left;
margin-left: 0 !important;
border-radius: inherit;
border: 1px solid transparent;
border-color: #ccc;
}
.btn-editor {
height: 30px;
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 11px;
font-weight: normal;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border-radius: 4px;
border: 1px solid transparent;
color: #333;
background-color: #fff;
border-color: #ccc;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset class="fieldsets">
<div class="form-group">
<div class="editor-wrapper">
<div id="editControls">
<div class="btn-group">
<a class="btn-editor btn-not-space" data-role="bold" data-ref="#">
<i class="icon-bold">B</i>
</a>
<a class="btn-editor btn-not-space" data-role="italic" data-ref="#">
<i class="icon-italic">I</i>
</a>
<a class="btn-editor btn-not-space" data-role="underline" data-ref="#">
<i class="icon-underline">U</i>
</a>
</div>
<div class="btn-group">
<a class="btn-editor btn-not-space" data-role="code" data-ref="#">
<i class="icon-code-view"><></i>
</a>
</div>
</div>
<div id="editor" contenteditable=""></div>
<br><br><br>
<textarea id="textarea" class="editor-preview" name="detail"></textarea>
<br><br><br>
<div id="preview" class="editor-preview"></div>
</div>
</div> </fieldset>
To be clearer, I attach an image of the problem, in number 1, I write some text, you can see that in textarea
said text it is attached with a code HTML
that text is written from the div
editable one, now in image 2, I click on The code editor function <>
is where the problem is, because when I paste some code or text, the HTML code is converted into HTML entities, as can be seen in the textarea in image 3.
How can I solve this problem, without having to hit enter
the div
editable or make changes to the text from the editor buttons?
Attached fiddle: https://jsfiddle.net/f4qhpov5/
If actually what solves your problem is a Enterafter pasting the text. You can fire a with JQuery to "press" a key, as soon as a pasteEnter event is detected .
So you would simulate that the key has been pressed and problem solved
I made some modifications to avoid the issue that was actually what is called a side-effect.
First I modified your HTML to save myself the trouble of modifying things I didn't want:
As you can see, both elements have the same class, so that will create subtle problems in the interaction.
The next thing, it was very difficult for me to understand what the button did <>, so when I realized that it was not a normal button but a toggle, I added a style change to see when it was activated and thus give a visual confirmation to facilitate debugging.
In the CSS I made it look different on and off
And in the javascript below your state change as well:
To facilitate debugging I used the S of SOLID and created several methods that did one thing, so if something went wrong I would know that it would not inadvertently hit other functionalities and I would make sure that everything worked well in the
#editor
.Then I took care that everything worked fine in the
.editor-preview
.At that time it only remained to add new code that did not exist for the
#textarea
.If we were in visual edit mode it should show the HTML, but if not... it should show the editor text and not its HTML, that way it would look the same no matter what.