Enter mode is getting changed in CKEditor - javascript

In CKEditor I wants to differentiate between pasted content and the content added by the user. So, on paste event of ckeditor I am changing the p tags of copied content to div so that all new paragraphs are represented by div tags for copied code. Below is the code.
editor.on('paste', function(evt) {
evt.data.dataValue = data.replace(/(<p)/igm, '<div').replace(/<\/p>/igm, '</div>');
});
This works fine but after doing this when I am pressing enter and trying add any new content ckeditor is adding a new div tag to wrap the content whereas I have this declaration present in my config
config.enterMode = CKEDITOR.ENTER_P;
config.shiftEnterMode = CKEDITOR.ENTER_P;
I tried to change the enter mode in after paste event but didn't helped.
editor.on('afterPaste', function(evt) {
editor.setActiveEnterMode(null);
});
Any suggesttions?

You should not mix <div>s with paragraphs. The content inside the editor should be clean and by making it inconsistent you make it messy. This may cause more issues in the future.
Try the config.forceEnterMode option. By default CKEditor uses the block that you're currently in (to be consistent). With this option you are forcing it to use the block from the enter mode.

Related

How to wrap TinyMCE element with custom HTML code without external JavaScript

I am trying to wrap some elements of TinyMCE with my custom HTML code.
For example, let us consider the user wants to add Media or Image element, the user will just click on Media or Image element icon, and he will be asked to enter the link, and TinyMCE will generate the required HTML code for that.
What I want to achieve is wrapping that generated HTML code with my custom code. I.e., so I will simply get this:
<div>
... What TinyMCE has generated for the image or media ...
</div>
For Media element, I tried using media_url_resolver, but that does not work for me, because this function does not give the ability to wrap the default behaviour, but only to rewrite the whole logic (which is a bad idea).
Could some one tell me if there is any TinyMCE native solution to get that (without any custom external JavaScript)?
There is no configuration option to do what you want but you can get notified when content is set into the editor and modify it before its inserted:
http://fiddle.tinymce.com/prgaab
The key code is here:
editor.on('BeforeSetContent', function (e) {
//Look at this object - it tells you a bunch of stuff about the insert activity
//such as was it via paste? Was there selected content in TinyMCE that will be overwritten?
//Using the browser tooling you can inspect the e object and learn a lot about the content that will be set.
console.log(e);
//Then you can modify that content if you want...for example:
if (e.content.startsWith("<a href=")) {
console.log('ADDING CONTENT');
e.content = '<p>BEFORE</p>' + e.content + '<p>AFTER</p>';
}
});

CKEditor: How to insert anchor tag into document?

On the surface this should be easy:
CKEDITOR.instances[Object.keys(CKEDITOR.instances)[0]].insertHtml( html );
...where html is a string of an actual HTML tag. Sadly, however, this doesn't work. When I click the button on my page that calls this code, nothing happens. It doesn't appear anywhere in the document at all, not even in Source mode.
I tried using insertElement:
var element = CKEDITOR.dom.element.createFromHtml( html );
CKEDITOR.instances.editor1.insertElement( element );
...and all it did was stick a little red flag in the document that was nothing; if I saved the document and reloaded it, it was gone.
The goal is to insert:
<a name="something"></a>
But the only thing that works is insertText() and that turns it into "safe" text, i.e. the < and > turn into lt; and gt;.
Help please? :)
I guess you used the code from the CKEDITOR Documentation (https://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement)
You probably ran into an issue, which says, that empty anchors show
a little red flag in the editor
(https://dev.ckeditor.com/ticket/14689). Unfortunately there seems to
be no way of CKEDITOR from doing this.
Empty Links are removed from
CKEDITOR automatically. You can add data-cke-survive="true" so these
links aren't removed,
Regards

Inserting a popup DOM node into WYSIWYG

I am trying to add a clickable div to the sceditor. The basic requirement is to use a wysiwyg and programmatically add an element into the editor, which can display a popup when the user clicks on it.
To do this I use:
var text = "<div onClick='editdiv(this)'>"+name+"</div>";▓
$('.sceditor').sceditor('instance').insert(text);
This inserts the div into the editor but when I click on it, I get an error saying editdiv is not defined. Whereas editdiv is a function present inside the javascript same javascript file which runs the above code.
Can someone please tell me what am I doing wrong and/or a way to achieve what I want? Thanks!
What you want is impossible to get without drawbacks.
Events can only be caught inside an active browsing instance (I think that's the name). Everything inside a contentEditable=true" is not an active browsing instance
Based on that, You need to terminate the contentEditable and make a new one inside. For example (code not tested):
var text = "<div contentEditable='false' onclick='editdiv(this)'><div contentEditable='true'>"+name+"</div></div>";
$('.sceditor').sceditor('instance').insert(text);
That should make that click event work as expected

CKeditor setData() method is omitting images

when setting data in CKEditor images disappear in the editor area. Links and other format is ok, so doesn't look like a double quote thing. Also, I tryed with absolute positioned and also external images, so it's not an image not found problem.
This is my code:
function getContent(id)
{
console.log($('#content-article-' + id).html());
return $('#content-article-' + id).html();
}
function enableEdition()
{
if (current_conclusion != 'NEW')
{
$('#titular-edit').val(getTitle(current_article));
//This setData() sets everthing but images
CKEDITOR.instances.editor.setData(getContent(current_article));
}
}
The image tag is substituted by a <br> tag inside the editor iframe
CKEditor 4.1 comes with Advanced Content Filter which is the root of your problem. Most likely you don't use the image plugin that adds <img> to allowedContent rules (don't you?). This is why editor discards those tags from your content and this is why you have to configure it manually.
See related answers: Stop CKEditor removing divs, CKEditor strips inline attributes

Completely Reload TinyMCE

I have been writing a CMS for a while now and am currently putting the last few touches on it. one of which includes using ajax to deliver a tinyMCE editor in a lightbox styled window.
when it is loaded, the first time it works perfectly, but when i do it the second time or more, the element names get messed up and it doesn't send data back, or display the current value in the TinyMCE window. When I use Chrome to inspect the element, I can see that the span that contains the previous tinyMCE window is still there.
I use document.body.removeChild to remove the div that is holding it. Does anyone have any ideas?
Addition:
when AJAX gets back from making the request (it has all the html code of what goes in the window), it creates a new div element and uses document.body.appendChild to add the element to the document and puts the html code into the div tag.
Then it travels through the new code and searches for the scripts in that area (of which one is the MCE initiator) and appends them to the head so they are executed.
if the user clicks cancel rather than save, it removes the div tag by using:
document.body.removeChild(document.getElementById("popupbox"));
which works fine,
however when i bring up popup and repopulate as said before, and inspect the elements there, there is still a span there which was created by TinyMCE and the naming has been changed (instead of being identified by 'content', it is now 8 for some reason) and there is no content in the editor region.
I have used:
tinyMCE.execCommand('mceRemoveControl',true,'mce{$Setting['name']}');
tinyMCE.editors[0].destroy();
but neither of them work. They return the tinymce window to a textarea, but the elements are still there.
Removing the editor as you described (using the correct tinymce editor id) before moving or removing the html element holding the tinymce iframe is a good choice. Where do you load your tinymce.js? If you deliver it using ajax i think it might be better to load it on the parent page(!). Some more code would be helpfull.
EDIT: I remember a situation where i had to remove a leftover span. Here is my code for this:
// remove leftover span
$('div .mceEditor').each(function(item){
if (typeof $(this).attr('style') !== "undefined" ){
$(this).removeAttr('style'); // entfernt "style: none";
}
else {
$(this).remove();
}
});

Categories