TinyMCE - exclude elements - javascript

I'm wondering if it's possible to exclude some elements from TinyMCE's editable DIV. Here's an example code:
<div class="editable-area">
<h2>heading</h2>
<p>paragraph</p>
<div class="exclude-this-element"></div>
</div>
.exclude-this-element:empty:before { content: "Editable Area"; }
tinymce.init({
inline: true,
fixed_toolbar_container: '.toolbar'
});
tinyMCE.execCommand('mceAddEditor', false, '.editable-area');
The problem is that, when TinyMCE is initialized on .editable-area, it adds <br> tag to .exclude-this-element and Editable Area text stops appearing. Actually, I think that entire .exclude-this-element is erased after a while. Can this element be excluded completely from being altered by TinyMCE?
I would also like to attach some actions (like click or jQuery UI functions) to .exclude-this-element and make it not interfere with TinyMCE.
I tried valid_children, valid_elements and invalid_elements but I think that none of these can be used to exclude any elements from being editable (it only excludes them when saving the content of the editor): http://www.tinymce.com/wiki.php/Configuration

You can use content editable method
http://www.tinymce.com/wiki.php/api4:property.tinymce.Env.contentEditable and also
noneditable plugin. This plugin makes elements with noneditable class to be - non editable
http://www.tinymce.com/wiki.php/Plugin:noneditable
EDIT:
Try to block the BR elements by adding this in tinyMCE INIT configuration:
force_br_newlines : false,
forced_root_block : "",
convert_newlines_to_brs: false,
If the BR tags appear inside content when you paste it from somewhere you also can add this:
paste_preprocess: function(pl, o) {
o.content = o.content.replace(/<br><\/br>/gi, " ");
}

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.

Load data into TinyMCE programmatically

I have multiple text-areas that I'd like to enhance using tinyMCE. I can get the text areas to show as the Rich Text Editors by initializing TinyMCE on all text areas in the page as below:
$(function () {
tinymce.init({
selector: "textarea",
statusbar: false,
setup: function (editor) {
editor.on('change', function () {
editor.save();
});
}
});
});
This also handles the sync process between the Tiny editor and the actual textarea.
My html, that populates the text areas looks like this:
<div id="divEditor1" class="container-fieldset">
<div class="editor-label-field" style="left: 50px">
<%:Html.LabelFor(Function(model) model.divEditor1, "divEditor1")%>
</div>
<div class="editor-field-fn">
<%:Html.TextBoxFor(Function(model) model.divEditor1, New With { Key .class = "ucase-input" } )%>
<%:Html.ValidationMessageFor(Function(model) model.divEditor1)%>
</div>
</div>
<div id="divEditor2" class="container-fieldset">
<div class="editor-label-field" style="left: 50px">
<%:Html.LabelFor(Function(model) model.divEditor2, "divEditor2")%>
</div>
<div class="editor-field-fn">
<%:Html.TextBoxFor(Function(model) model.divEditor2, New With { Key .class = "ucase-input" } )%>
<%:Html.ValidationMessageFor(Function(model) model.divEditor2)%>
</div>
</div>
... etc
I can read the content from the TinyMCE editors like this:
for (var i = 0; i < numberOfEditors; i++) {
sFieldValue = document.getElementById("FormFieldText" + i).value;
//sFieldValue = tinyMCE.get("FormFieldText" + i).getContent(); -> or like this, works just as well.
};
The problem I am having is getting the TinyMCE editor box to display the already existing text on page load (text read from a database), since it always shows up as an empty text box. However, the text is imported correctly in the original textarea in the background. Formatted and escaped, since it goes through some ajax calls.
I've seen I can set the content of tiny like this:
tinyMCE.get('my_editor').setContent(data);
However, I need to do it programmatically, in a way that all textareas on my page export the information to tiny. Just like the above
setup: function (editor) {
editor.on('change', function () {
editor.save();
});
}
Also, what would be the right time to un-encode the text so tiny can read it? (I assume this step is necessary)
If you initialize TinyMCE on each textarea before each textarea has its content then TinyMCE won't auto-magically go back and update itself when the textarea gets updated with content - it just does not work that way.
You could use TinyMCE APIs (as you already know from your post) to update the editor's content once you get the data. Alternatively you could delay initializing TinyMCE until after the data is fetched into each textarea.
Neither approach is better/worse - there are certainly multiple ways to solve this and they all work if implemented appropriately.
I ended up parsing the list of active tinymce instances by ID and populating each one with the corresponding text from the textareas in the background.
I came across this post looking for a solution to get the data from the database back into tinymce, and I ended up with
<textarea id="textarea"><?= htmlspecialchars($description); ?></textarea>
Just using php and the variable from the array from the database.

TinyMce copies the classes from the current block element when pressing Return

When using tinyMce in Wordpress, In the visual editor, I'f I'm entering content in an element and press return the classes from the parent element are copied over, i would want simply to create a new <p> element.
For example, I'm editing
<p class="blip blip--gray one-sixth push-huge--top push--bottom">d aasdas d</p>
Then i press return and the following is added:
<p class="blip blip--gray one-sixth push-huge--top push--bottom"></p>
where i would want only to add
<p></p>
I have forced_root_block option set to p
This is tinymce default behaviour.
You could add a tinymce handler to your editor that gets triggered by the keyup event. Testing for charCode 13 you can detect if ENTER has been pressed. If so you could remove the classes from the actual paragraph in the editor:
$(tinymce.get('youreditor_id').getNode()).closest('p').removeAttr('class');
This might be the solution to this problem:
tinymce.init({
selector: 'textarea', // change this value according to your HTML
keep_styles: false
});
tinymce - content filtering docs
The complete answer, based on #thariama post is
tinyMCE.editors.content.on('keyup',function(e){
if ( 13 === e.keyCode ) {
$(tinyMCE.editors.content.selection.getNode()).closest('p').removeAttr('class');
}
});

TinyMCE Remove DIVs with a specific class

I would like to remove a div from the TinyMCE editor content that has a specific class.
In the ideal world I'd like to be able to do this via the valid_elements option but I don't know if it's achievable.
Here is a sample of editor content:
<div class="content">
Some html content here
<div class="anotherclass"></div>
</div>
I would like the
<div class="content">
stripping out so the editor will only show this:
Some html content here
<div class="anotherclass"></div>
Cheers guys.
First get the innerHTML of the div, and then append that content to the div, after which you can remove it.
In jQuery:
var contentHtml = $(".content").html();
$(".content").after(contentHtml);
$(".content").remove();
Of course, if you have multiple divs with these classes its more complicated because then you would have to work with parents etc.
Problem here will that by default your editor will have a root_block element (in your case div) and all content gets wrapped inside that kind of root_block element. This is done for styling purposes, but can be deactivated using this initialization params
force_p_newlines : false,
force_br_newlines : false,
convert_newlines_to_brs : false,
remove_linebreaks : true,
Once that is done you can use this code to easily get rid tof your divs.
var $elements_to_be_removed = $(".content");
$elements_to_be_removed.each(function(index) {
$(this).replaceWith(this.innerHTML);
});

Categories