Copy content from WYSIWYG editor to textarea - javascript

I try to copy the content from a WYSIWYG-Editor (What you see is what you get), to a textarea and It needs to be structured. I am using Quill https://www.quilljs.com/docs/quickstart
I added a textarea, the content from the Editor is pasted into it, on click at the button Edit HTML.
$("#editHTML").click(function() {
var content = $("#editor .ql-editor").html();
$("#htmlEditForm").html(content);
});
It works, but as you can see it is not structured at all. Everything is in one line:
I need it like this:
<p>FOO</p>
<p>BAR</p>
<p class="ql-align-center"><span style="color: rgb(230, 0, 0);">I am centered</span></p>
I need it to be in a textarea, because I want to use it as HTML editor. Later on I will add another button which pastes the html code back into the WYSIWYG-editor.
The goal is, to give advanced users the possibilty to edit the HTML.
I am not sure how I can do this, I was thinking of replacing any closing tags with this: e.g. </p> -> </p>\n but it just outputs </p>\n in the textarea instead of creating a new line.
Is this even possible?
UPDATE:
I tried to use getContents as suggested:
var toolbarOptions = [
['image'],
[{ 'header': [1, 2, 3, 4, 5, 6, false] }],
['bold', 'italic', 'underline', 'strike'], // toggled buttons
[{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme
[{ 'align': [] }],
['blockquote', 'code-block'],
[{ 'list': 'ordered'}, { 'list': 'bullet' }],
[{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript
[{ 'direction': 'rtl' }], // text direction
[{ 'font': [ 'arial', 'Monotype Corsiva', 'fantasy', 'serif' ] }],
['clean'] // remove formatting button
];
var quill = new Quill('#editor', {
theme: 'snow',
modules: {
toolbar: toolbarOptions
}
});
$("#editHTML").click(function() {
$("#htmlEditForm").html(quill.getContents());
});
But the textarea stays empty.
quill.getContents() does just return an object:

Unfortunately Quill is not meant to do this. Quill uses it's own document model called Parchment. It tracks everything that changes in the editor so that it can understand it's contents and make changes, but it has some limits on what can be added. For example, you can't add an element that doesn't match an existing blot/format.
If someone were to edit the HTML arbitrarily and add a div for example, the editor's document model would no longer match it's contents. When switching back to the wysiwyg view, some functions wouldn't work until it tries to recreate it's document model and messes up the changes made in the HTML view.
Edit
Also, for the original problem of how to format the HTML with new lines and indention, what your seeing is how it's formatted. The editor is not breaking to new lines for each block element or adding indentation for nesting as someone would when they're writing code.
If you want it to be formatted in some way, you'd have to do it manually. Either by parsing the getContents() output or by writing or finding a script that can format HTML.

You can combine your text area with Ace Editor (https://ace.c9.io/) which allows code editing features.

Instead of detecting .click event use the built-in quill mechanism 'text-change' ... also to get the HTML of the rich text editor all in one go use .container.childNodes[0].innerHTML
quill.on('text-change', function (delta, oldDelta, source) {
// your code here e.g.
$("#htmlEditForm").html(quill.container.childNodes[0].innerHTML);
});

Text area is not capable of showing you the formats of rich text editors. A simple solution can be strip all tags if you do not want the tags in text area. Or if you want tags like bold, italic etc you have to use WYSIWYG editor. You can disable all tools of the editor and it would be looking like a textarea.

Related

ElectronJS - Make bold text in Teaxtarea with local keyboard shortcut

I'm trying to make a text editor in ElectronJS as my first application in Electron.
I got the Textarea and the shortcut setup as it should be, but I cant get the selected text in the textarea to get bold, when pressing CTRL+B. I could use some help in the right direction on how this is done.
I have tried to use the execCommand so far to toggle the bold, but are getting the error:
Document is not defined
Main.js
menu.append(new MenuItem({
label: 'Shortcuts',
submenu: [{
role: 'Bold',
accelerator: process.platform === 'darwin' ? 'Cmd+B' : 'Ctrl+B',
click: () => {
document.execCommand('bold');
}
}]
}))
Menu.setApplicationMenu(menu)
I have also tried this in renderer.js, but not working aswell.
What am I doing wrong?
This actually answered the question: https://stackoverflow.com/a/12831155/652535
Content from link:
If you need to customize your textarea, reproduce its behavior using another element (like a DIV) with the contenteditable attribute.
It's more customizable, and a more modern approach, textarea is just for plain text content, not for rich content.
<div id='fake_textarea' contenteditable></div>
The scrollbars can be reproduced with the CSS overflow property.
You can use this fake textarea in a form normally, i.e: if you have to submit its content through POST method, you could do something like(with jQuery):
<input type='hidden' id='fake_textarea_content' name='foobar' />
...
$('#your_form').submit(function()
{
$('#fake_textarea_content').val($('#fake_textarea').html());
});

Add class style to CKEditor text with javascript

I'm building a self contained web page and am using CKEditor 4.6.2 for input. My last hurdle, for now, is trying to apply a css class style to text inserted via javascript. My css is in the head tag, nothing special there. I have defined a styleset as directed by CKEditor documentation.
CKEDITOR.stylesSet.add('my_custom_styles', [
// Block-level Styles
{ name: 'My Custom Block', element: 'p',
styles:{
'color': 'dimgray',
'padding-left':'15px',
'border-left-style':'solid',
'border-width':'3px',
'border-color':'#52bab3',
'margin-left':'2px',
}
},
{ name: 'MyCustomInline', element: 'span', attributes: {'class': 'redText'}
}
]);
And added it in CKEditor
CKEDITOR.replace('LogBook', {
language: 'en',
uiColor: '#9AB8F3',
toolbar: [
['Undo','Redo','-'],
['Bold','Italic','Underline','Strike','-'],
['RemoveFormat','-'],
['NumberedList','BulletedList','-'],
['HorizontalRule'],
'/',
['Styles','-','Source','-','About','Maximize'],
],
removeButtons: 'Subscript,Superscript,Cut,Copy,Paste,Anchor,Scayt,PasteText,PasteFromWord,Image,SpecialChar,Link,Unlink,Table,Indent,Outdent,Blockquote,Format',
removePlugins: 'wsc,scayt',
stylesSet:'my_custom_styles',
allowedContent: true
})
But for the life of me I can't figure out how to apply a class to an element in the editor with javascript like so...
<p class="My Custom Block">Some text here</p>
I have turned off content filtering and have a custom function that inserts the above code, but the paragraph element does not get styled.
I have also tried applying styles right from my style sheet like:
<p class="redText">Some text here</p>
But again the paragraph element isn't getting styled.
Any help would be great, thank you.
After a long search I finally ran across an answer (by surtyaar towards the bottom) to add a class to a CKEditor elements.
CKEDITOR.addCss( '.redText { border-bottom: 1px dotted red }' );
This needs to be called before the CKEditor instances are declared.
From the CKEditor docs.

Quill List Blank

I'm using the version of Quill from the CDN; I have Quill.js and Quill.snow.css defined. I'm adding
var quill = new Quill('#editor', {
modules: {
toolbar: [
['list'..]
]
},
theme: 'snow' // or 'bubble'
});
When it renders it generates this:
<button class="ql-list" type="button"></button>
But I don't see anything although I can click in the space and trigger the action that way.
I looked in the CSS and didn't find the .ql-list CSS class. Obvious why it isn't working but why is the CSS file incomplete?
According to their documentation here - https://quilljs.com/docs/modules/toolbar/ The list should have a value as well. try and pass it as an object like -
{ 'list': 'ordered'}, { 'list': 'bullet' } instead of 'list'
And then the generated code might look like -
<button class="ql-list" type="button" value="ordered"></button>
And maybe in the CSS file you'll find something related to
.ql-list[value="ordered"]{
// Styling for ordered list here
}
And if not in the CSS, it might be an SVG constructed dynamically based on the value. Who knows what people are upto these days!

CKEditor allow pasteFilter and enterMode at the same time

I want different formatting style while pasting a text in the editor and while writing.
But when I define enterMode : CKEDITOR.ENTER_BR, it applies for the pasted text as well and removes the pasted text formatting and tags. i.e. It overrides the pasteFilter: 'semantic-content' behavior.
Is there any way I can keep both?
Following are my config:
editor = CKEDITOR.replace("annotationEditor", {
toolbarGroups: [
{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }
],
removePlugins : 'uploadimage',
pasteFilter: 'semantic-content',
enterMode : CKEDITOR.ENTER_BR,
/*shiftEnterMode: CKEDITOR.ENTER_P,*/
extraPlugins : 'maxlength',
removeButtons : removeButtons,
pasteFromWordRemoveFontStyles: false,
autoParagraph : false
});
I tried following as well but did not work:
CKEDITOR.instances['annotationEditor'].on('key', function(e) {
e.editor.on('change', function (event){
if(e.data.keyCode == 13){ // Do this code when ENTER is pressed
CKEDITOR.config.enterMode = CKEDITOR.ENTER_BR;
CKEDITOR.config.forceEnterMode = true;
}
});
});
I want different formatting style while pasting a text in the editor and while writing.
If you want to use enterMode set to BR and paste rich content then if your ACF settings allow all the tags you want to paste, I would suggest using paste event listener with a very low priority and dontFilter flag set to true (you could do some filtering of your own in that filter as well). If this won't help I can't think of any other way to do it.
If on the other hand you want to have e.g. enterMode set to P and you want to paste content formatted like in BR mode that you could use forcePasteAsPlainText setting together with events like pasteFromWord, afterPasteFromWord, afterPaste, paste to do some extra filtering.

How to add custom class in wagtail richtextfiled

how can i add button which adds class in hallo.js editor?
Here is my code, but it dont works, it ony register fuction in wagtai;s edit interface.
In the end I need to add any class to selection or current tag.
Mb I can see it in html in someway and add classes manually?
(function() {
(function(jQuery) {
return jQuery.widget('IKS.center', {
options: {
editable: null,
toolbar: null,
uuid: '',
buttonCssClass: 'center'
},
populateToolbar: function(toolbar) {
var buttonElement, buttonset;
buttonset = jQuery('<span class="' + this.widgetName + '"></span>');
buttonElement = jQuery('<span></span>');
buttonElement.hallobutton({
uuid: this.options.uuid,
editable: this.options.editable,
label: 'Center element',
command: 'addClass("center")',
icon: 'icon-horizontalrule',
cssClass: this.options.buttonCssClass
});
buttonset.append(buttonElement);
buttonset.hallobuttonset();
return toolbar.append(buttonset);
}
});
})(jQuery);
}).call(this);
As mentioned in the Wagtail customisation docs, you need to call registerHalloPlugin. You'll also need to configure the whitelist to allow your <span> element - rich text fields intentionally don't allow inserting arbitrary HTML. (See https://stackoverflow.com/a/38097833/1853523 for more detail.)
However, I would strongly encourage using StreamField for this, rather than extending the rich text editor. The whole purpose of Wagtail is to keep a separation between the information content of pages, and its presentation. A button to say "center this text" is purely presentation - that's a detail that belongs in template code, not in your article content. Instead, you should ask: what is the purpose of this text? Is it a block-quote, a testimonial, an advert? Create block types for that, and then think about how to style them in the template. You'll have much more control over the presentation that way.
(further reading: Rich text fields and faster horses)

Categories