Instanciate and link a Tinymce editor dynamically - javascript

In my app I have a button that creates paragraphs (textareas) dynamically.
I want to link a Tinymce editor to each of them, but I just don't know how to do it.
This is the function that creates textareas dynamically:
createParagraph: function(idNb) {
attribs = {'name':'paragraph_'+idNb, 'id':'paragaraph-'+idNb, 'class':'form-control'};
document.getElementById('tag-row-1-cell-1-'+idNb).append(_createElement('textarea', attribs));
let ed = new tinymce.init({
selector: '#paragaraph-'+idNb
});
},
Can someone help me ?

Related

Add a custom button to the Quill's toolbar (and integrate it also on the PrimeFaces Text Editor)?

I am using PrimeFaces 7 and its TextEditor component, which uses internally the free and open-source editor Quill
I need to add a custom HTML button, which, when selected, inserts the word selected on the current position of the cursor in the TextEditor - (in the Quill)
It is possible to add custom buttons in the Quill Editor and to attach EventListeners to them, as shown here:
https://quilljs.com/docs/modules/toolbar/
(Please look at this part of the above page):
var customButton = document.querySelector('#custom-button');
customButton.addEventListener('click', function() {
console.log('Clicked!');
});
There is also an API provided by the Quill editor to insert text at a given position, see here:
https://quilljs.com/docs/api/#content
have a look at this mehod:
`quill.insertText(0, 'Hello', 'bold', true);`
However, I do miss a couple of things:
1.) The definition of the custom-button shall be done in the toolbar div, as specified in the following code:
`<div id="toolbar">
<!-- But you can also add your own -->
<button id="custom-button"></button>`
However: how could I do that, when using ready PrimeFaces Text Editor component?
I locally tried this:
jQuery(document).ready(function () {
jQuery(document).ready(function () {
var customButton = document.getElementById("resultsFormId:quillToolbarId_toolbar:custButId");
if (customButton!=null){
return;
}
customButton = document.createElement("button");
customButton.innerHTML = 'Params';
customButton.id="resultsFormId:quillToolbarId_toolbar:custButId";
var qlTollbar = document.getElementById("resultsFormId:quillToolbarId_toolbar");
qlTollbar.appendChild(customButton);
customButton.addEventListener('click', function() {
Quill.insertText(0, 'Hello', 'bold', true);
console.log('Clicked!');
});
});
});
and could say the following:
1.1) The custom button gets inserted on the Quill toolbar (is not nice and styled, but it is there)
1.2) When I click the custom button, first the EventListener gets executed. This is OK,but here:
Quill.insertText(0, 'Hello', 'bold', true);
instead of Quill.insertText()., I need a reference to the js-object representing the Quill editor. === > Could you help?
1.3) after the EventListener from Point (1.2) gets executed, my whole code under
jQuery(document).ready(function () {
jQuery(document).ready(function () {
gets executed once again, the id of the customButton is not found, and it is recreated once again. ===> Could I avoid that?
2.) In the code for the insertion of a text on a specific position, I need to get the last position the cursor was, before the user clicked (selected the option on the) custom button.
How can I do that?
I never heard of PrimeFaces, but maybe I can answer this part of you question:
Quill.insertText(0, 'Hello', 'bold', true);
instead of Quill.insertText()., I need a reference to the js-object representing the Quill editor. === > Could you help?
According to the code on GitHub it should be
PrimeFaces.widget.TextEditor.editor.insertText(0, 'Hello', 'bold', true)
can you confirm? Then you should also be able to get the cursor location and selection (if any) with
PrimeFaces.widget.TextEditor.editor.getSelection();

redactor.js pastePlainText - but need button to paste html instead

Most of our customers complain about formatting carried across from Word to our redactor.js rich text editor fields. We upgraded to use the pastePlainText setting, which seems to work well.
However SOME customers still need to paste html into the rich text boxes. We've added a "paste as html" button to the toolbar using a plugin but we can't work out what code to add to the plugin to paste the clipboard content as-is into the editor. Help!
We'd be almost as happy to remove the pastePlainText option and have a "paste as plain text" button on the toolbar instead, but we also can't work out how to do that.
RedactorPlugins.pasteAsHtml = {
init: function () {
this.buttonAdd('pasteAsHtml', 'Paste as HTML', this.testButton);
},
testButton: function (buttonName, buttonDOM, buttonObj, e) {
// What do we do here?
};
$(".richText").redactor({
plugins: ['pasteAsHtml'],
pastePlainText: true
});
We now have a solution to this.
We were barking up the wrong tree here: for security reasons it's difficult to read from the clipboard. We had assumed that redactor.js has the ability to do this, but in fact it appears to read from the rich text editor only after the user has initiated the paste themselves via Ctrl+v or the context menu. That means clicking a button to trigger a "paste" isn't easy. I believe there's at least one jquery plugin that attempts to solve that problem, and a bunch of solutions involving Flash, but we're after a more lightweight fix.
Instead, we did the following.
Set redactor to accept html (ie we didn't set the pastePlainText option).
Caused our button to show a modal dialog containing a textarea, into which the user pastes their html content. Once the content is pasted we process it to strip out html and retain line breaks.
So users wanting to retain formatting just paste into the RTE, and users who want to paste as plain text click the new button. Here's the code for the plugin.
if (!RedactorPlugins) var RedactorPlugins = {};
RedactorPlugins.pasteAsPlainText = {
init: function () {
// add a button to the toolbar that calls the showMyModal method when clicked
this.buttonAdd('pasteAsPlainText', 'Paste as plain text', this.showMyModal);
},
// pasteAsPlainText button handler
showMyModal: function () {
// add a modal to the DOM
var $modalHtml = $('<div id="mymodal" style="display:none;"><section><label>Paste content here to remove formatting</label><textarea id="mymodal-textarea" style="width: 100%; height: 150px;"></textarea></section><footer><button class="btn btn-primary" id="mymodal-insert" style="color:#fff;">Insert</button></footer></div>');
$("body").append($modalHtml);
// callback executed when modal is shown
var callback = $.proxy(function () {
this.selectionSave();
$('#mymodal-insert')
.css("width", "100px")
.click($.proxy(this.insertFromMyModal, this));
$("#mymodal-textarea").focus();
}, this);
// initialize modal with callback
this.modalInit('Paste as plain text', '#mymodal', 500, callback);
},
insertFromMyModal: function (html) {
this.selectionRestore();
// remove formatting from the text pasted into the textarea
html = $('#mymodal-textarea').val();
var tmp = this.document.createElement('div');
html = html.replace(/<br>|<\/H[1-6]>|<\/p>|<\/div>/gi, '\n');
tmp.innerHTML = html;
html = tmp.textContent || tmp.innerText;
html = $.trim(html);
html = html.replace('\n', '<br>');
html = this.cleanParagraphy(html);
// insert the text we pulled out of the textarea into the rich text editor
this.insertHtml(html);
// close the modal and remove from the DOM
this.modalClose();
$("#mymodal").remove();
}
};
$(".richText").redactor({
plugins: ['pasteAsPlainText']
});
By the way, if Internet Explorer had a "paste as plain text" option available via Ctrl+shift+v or on the context menu like Firefox and Chrome we would just have told customers to do that!
If you've just recently upgraded from Redactor v9 to v10, you will find that the above code does not work since Redactor has now updated most of its existing APIs and added new modules. For example, .modalInit(), .selectionRestore(), .selectionSave(), .insertHtml() from v9 is now .modal.load(), selection.restore(), .selection.save(), etc in v10.
I've modified the above code slightly and am adding it here if anybody's interested. Feel free to edit/ optimize it if needed.
Reference - http://imperavi.com/redactor/docs/how-to-create-modal/
if (!RedactorPlugins) var RedactorPlugins = {};
RedactorPlugins.pasteasplaintext = function()
{
return {
init: function()
{
// add a button to the toolbar that calls the showMyModal method when clicked
var button = this.button.add('pasteasplaintext', 'Paste As Plain Text');
this.button.setAwesome('pasteasplaintext', 'fa-paste');
this.button.addCallback(button, this.pasteasplaintext.showMyModal);
},
getTemplate: function()
{
// this function creates template for modal that is to be added
return String()
+ '<div id="mymodal">'
+ ' <section>'
+ ' <label>Paste content here to remove formatting</label>'
+ ' <textarea id="mymodal-textarea" style="width: 100%; height: 150px;"></textarea>'
+ ' </section>'
+ '</div>';
},
showMyModal: function () {
// fetch and load template
this.modal.addTemplate('pasteasplaintext', this.pasteasplaintext.getTemplate());
this.modal.load('pasteasplaintext', 'Paste As Plain Text', 500);
// create cancel and insert buttons
this.modal.createCancelButton();
var buttonPaste = this.modal.createActionButton('Paste');
buttonPaste.on('click',this.pasteasplaintext.insertFromMyModal);
// save current content, show modal and add focus to textarea
this.selection.save();
this.modal.show();
$("#mymodal-textarea").focus();
},
insertFromMyModal: function (html) {
// remove formatting from the text pasted into the textarea
html = $('#mymodal-textarea').val();
var tmp = document.createElement('div');
html = html.replace(/<br>|<\/H[1-6]>|<\/p>|<\/div>/gi, '\n');
tmp.innerHTML = html;
html = tmp.textContent || tmp.innerText;
html = $.trim(html);
html = html.replace('\n', '<br>');
// close modal, restore content and insert 'plain' text
this.modal.close();
this.selection.restore();
this.insert.html(html);
$("#mymodal").remove();
}
};
};
If you, like me, were looking for a plugin to paste simple text into Redactor and found this question only to learn that the answers are very old, you'd be happy to find out that the answer is actually in the Redactor docs.
It turns out that their example plugin with modal window is exactly that, a "paste clean text" plugin.
You can find it here:
https://imperavi.com/redactor/examples/creating-plugins/sample-plugin-with-modal-window/

How to populate tinymce with some content on trigger of javascript event?

i want to populate the tinymce body with some content on trigger of onchange event of selectbox in javascript. I tried some stuff but it did
not work for me.Please guide me in right direction.
Here is the my code that appends the tinymce on textarea
$(function() {
appendTinyMCE();
function appendTinyMCE(){
tinyMCE.init({
// General options
mode : "textareas",
theme : "advanced",
plugins : "preview",
// Theme options
theme_advanced_buttons1 : "forecolor,backcolor,|,justifyleft,justifycenter,justifyright,justifyfull,bullist,numlist,|,formatselect,fontselect,fontsizeselect,sub,sup,|,bold,italic,underline,strikethrough",
theme_advanced_buttons2 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_statusbar_location : "bottom",
theme_advanced_resizing : true
});}
});
here is the html code
<td>
<textarea rows="15" name="MyTinymceContent" cols="90" >MyTestContent</textarea>
Now i want to populate the tinymce with new content , on change of select box in javascript. So i write the below code snippet on change
of select box
function populateMyTinyMCE() {
document.form.MyTinymceContent.value ="MyNewContent";
}
But it does not put the new content in tinymce body. I am not sure what i am missing here?
You can call any of following on some event trigger:
tinyMCE.get('your_editor').setContent("MyNewContent");
//OR
tinyMCE.activeEditor.setContent('MyNewContent');
See: Here for More
Tinymce is not equal the textarea. On initialization of the editor a contenteditable iframe get created. This iframe holds the editor content and gets written back into the editor source html element (in your case a textarea) from time to time. To set the editor content you need to use the tinymce setContent function. I will show the alternatives too:
function populateMyTinyMCE() {
var editor = tinymce.editors[0];
// other ways to get the editor instance
// editor = tinymce.get('my editor id');
// editor = tinymce.activeEditor;
editor.setContent('my new content');
// alternate way of setting the content
// editor.getBody().innerHTML = 'my new content';
}
Try
tinyMCE.activeEditor.setContent("MyNewContent");

How do you dynamically add a button/plugin to TinyMCE?

I have a TinyMCE editor in my page. I would like to add/remove buttons/plugins from the toolbar based on things happening else where in the page. I am looking for a solution that avoids destroying and recreating the editor. Is there a tinyMCE command to do this? Something like
tinyMCE.execCommand("mceInsertPlugin", pluginName);
You cannot load plugins without reinitializing the editor.
But with buttons it is possible:
Create button on the fly:
ed.addButton('example', {
title : 'example.desc',
image : '../jscripts/tiny_mce/plugins/example/img/example.gif',
onclick : function() {
ed.windowManager.alert('Hello world!! Selection: ' + ed.selection.getContent({format : 'text'}));
}
});
Removal:
$('.mce_example').parent('td').remove();

Tinymce on keypress I am try to display the preview of the content

I am trying below code
$('textarea.tinymce').keypress(function(){
dealDescription = $('textarea.tinymce').tinymce().execCommand('mcePreview');
$("#deal_preview div").text(dealDescription);
});
But I am not using jquery tinymce editor suppose I use jquery tinymce and other jquery UI component not working properly so I am directly using the tinymce component.
Now I need to show content preview in preview box for each key press.
Im using this in tinymce 4.x
tinymce.init({
selector: "#tinymce-textarea",
setup : function(ed) {
ed.on("change", function(e){
$('#tinymce-livepreview').html(tinymce.activeEditor.getContent());
});
ed.on("keyup", function(){
$('#tinymce-livepreview').html(tinymce.activeEditor.getContent());
});
}
});
Explanation:
on("change") is for detect changes on mouse event if u click toolbar icon or selection from the menu. It also able to detect the keyboard event but only after lost focus (not real time).
on("keyup") is for detect changes on real time keyboard event
Could be done after initialisasing as well by getting the active editor:
tinyMCE.activeEditor.on('keyup', function () {
// your nicely formatted code here
});
There's also an editors array you can iterate over if you need it.
I try with below code is working fine
tinyMCE.init({
mode : "exact",
elements : "text",
setup : function (theEditor) {
theEditor.onKeyPress.add(
function (theEditor) {
previewContent(theEditor);
}
);
},
});
function previewContent(editorObject){
var content = editorObject.getContent();
document.getElementById("previewContent").innerHTML = content;
}

Categories