Hiding TinyMCE with jQuery - javascript

I have a TinyMCE textarea inside of #container
When I use $('#container').hide() and then $('#container').show(), tinyMCE throws:
Cannot read property 'selection' of undefined
I'm using the jquery plugin, so this is how I set it up:
$('#container textarea').tinymce({ /* options */ });
What should I be doing differently?

The correct command to use here is
// editor_id is the id of your textarea and
// tinymce will use this id to uniquely identify this editor instance
editor_id = $("#container textarea").attr('id');
tinymce.get(editor_id).hide();
to make it visible again use
tinymce.get(editor_id).show();

This question is about hiding and showing tinymce editor but if anyone came here about removing and re-adding tinymce editor without error then my solution can work for them.
To remove existing tinymce editor and add new needs clearance of tinymce.EditorManager.editors array. This solution works in both cases : 1. If you have only one editor and you want to remove and add it again. 2. If you have multiple editors and you want to remove some special editor and add it again.
console.log(tinymce.EditorManager.editors);
This will give you a view of the array and exact index of you desired editor which you want to remove. For example one sample output of above console can be:
Array[2]
0:B
1:B
length:2
textarea-1:B
textarea-2:B
_proto_Array[0]
This is the output of the console when i have two tinymce editors on textareas : #textarea-1 and #textarea-2 Lets suppose I want to delete #textarea-2 and re-add it then it can be done as follows:
tinymce.EditorManager.editors.splice(1, 1);//removing second element in array.
delete tinymce.EditorManager.editors['textarea-2'];//deleting respective textarea id from array
Then you can add it again simply using init:
tinymce.init({
selector:'#ts-textarea-2'
});
If you have only one textarea associated with tinymce editor lets say : #textarea-1 and you want to remove and re-initialize it then you can just empty tinymce.EditorManager.editors by :
tinymce.EditorManager.editors = [];
And then you can add using init command as explained above. Worked for me without any error.
I hope it helps

Instead of hiding it, try sending it off screen - something like:
$('#container').css('left', '-1000px');
EDIT/UPDATE:
You could also try removing TinyMCE from the textarea before you hide() the container, and then bring it back after you show(). But you'll need to give your textarea an #ID:
//To Enable
tinyMCE.execCommand('mceAddControl', false, $("#container textarea").attr('id'));
//To Disable
tinyMCE.execCommand('mceRemoveControl', false, $("#container textarea").attr('id'));

Apparently it was the animation. if I show()/hide() I'm fine, but when I try to animate in tinyMCE has an issue after I finish animating, possibly trying to set options once the textarea's display isn't none.

Related

ckeditor for particular section

I have a used case, where I have multiple text-areas on page. And unfortunately the name and id for these textareas are same. Actually it is tabbed section on the page.
I need to apply ckeditor to particular tab section, and not all.
CKEDITOR.replace('textarea');
replaces only the first textarea. However, I want to skip first and replace second or for another context I want to skip second and replace third and first textareas of same name.
Any idea?
All html elements are stored in an index . Try the following jquery funtion .eq() to grab a specific textarea .
Example .
var textArea1 = $("textarea");
then replace a specific textarea at any index in the dom..
// FYI grabing the 2nd <textarea> element on the page...
CKEDITOR.replace(textArea1.eq(1))
WORKING EXAMPLE HERE: http://codepen.io/theConstructor/pen/pyRXYa
Well I tried something like this.
Each tabbed section has its own id or whaterver,
$('textarea.ckeditor').each(function() {
CKEDITOR.replace(this);
});
And this worked fine for me!

How to remove() and undo remove() on page width conditional ? I don't need a hide or toggle

I'm using select2 which takes in rails instance variables. Due to the design layout, I can't just scale down the original select2 input. I have to create another.
The problem: A rails partial including the logic for the select2 interferes with the logic I need for the mobile select2 feature. So, it needs to not exist, not simply to be hidden (display: none) , etc..
I was able to get the mobile to work by using remove() on the original partial, but how can I get it back. Maybe something with a page-width conditional, but I'm not sure how that would work.
this is the element / render I neeed to have removed then to have it 'un-removed': (haml markup)
.divider-row
.row-border.vOne
#vCompare
= render 'compare', :categories => #categories, :v_friends => #v_friends
my JS:
if (screen.width < 760){
$('#vCompare').remove();
}
how would I get this information back, when the screen size was over 760? append?
Im trying to use detach and appendTo() as some have suggested below:
$('.compare-searchM').on('change', function () {
$('#vCompare').detach();
})
$(window).resize(function() {
$('#vCompare').appendTo($('#vAppend'));
sizing();
});
haml / markup :
.row-border
#vAppend
#vCompare
= render 'compare', :categories => #categories,
the detach is working, but I must not be understanding something with appendto()
Instead of using .remove() you can use .detach() and store the jquery object in some other variable, like
$vCompare = $('#vCompare').detach();
in your media queries, Later you can use this depending upon your media queries. for more info look .detach() | jQuery. hope this would help you.
When you add the item to the page, try storing it as a variable first and then adding it from there, somewhat like this:
var vCompare = $("<div/>",{id:"vCompare"});
vCompare.appendTo("body");
The div object will be stored in the variable vCompare, so you can still remove it with .remove();:
$('#vCompare').remove();
And then add it back later with the .appendTo(); line seen in the first code snippet.
Hope this helps!
Yes, you should use append here. But before you should get proper position from where you removing the element. You can do it via .index()
So, when you want to restore removed element, use .before() on the found by index element.
If lists, or whatever, have a big difference between mobile and desktop, I'd prefer to create two lists, one of which is shown for mobile and another for desktop.

How to re-enable jQuery tooltip after disabled = true?

Trying to temporarily disable the jQuery tooltip
$(document).tooltip( "option", "disabled", true );
When I try to re-enable them again, all of the title attributes are gone. I was trying to re-enable them using:
$(document).tooltip( "option", "disabled", false);
The title attributes is actually being removed completely when i first set it to disabled to true.
Also tried:
$(document).tooltip("disable");
$(document).tooltip("enable");
It is doing the same thing...
Update
Found a solution to my own question with the help of Jasen and zgr024. See below.
This appears to be a bug with the jquery version so you need a work-around to insert the title attribute after disabling tooltips.
Use a class name on the tooltip element you need re-enabled or use the [title] attribute selector.
<input type="text" class="tooltip-hack" title="tooltip text" />
$("#disable").on("click", function (e) {
var tooltips = $("[title]"); // or $(".tooltip-hack")
$(document).tooltip("disable");
tooltips.attr("title", "");
});
Use the least destructive of the two depending on your html structure.
Also, you note that all title attributes are removed so be more selective with your tooltip.
// instead of
$(document).tooltip();
// use a more restrictive selector
$(".tooltip-hack").tooltip();
Working example: jsFiddle
So with the help of others above, I finally found a better solution. That require no brutal fix to re-adding title to every single elements. Don't get me wrong, that fix will work, but performance is important (especially I still need to support IE8 ugh).
Basically I add a custom variable to the tooltip object, this can also be a global variable. Since everything is an Object in js, you can just add anything you want to it.
$(document).tooltip.temporarilyOff
Then when I initialize the jQuery tooltip, I just need to add a check in the open:
var settings = {};
settings.tooltipClass = "tooltip";
settings.open = function (event, ui) {
if ($(document).tooltip.temporarilyOff) {
ui.tooltip.stop().remove();
}
};
$(document).tooltip(settings);
Then when I need to temporarily disable the jQuery tooltip, I just need to toggle the flag anywhere I want. Like so:
$(document).tooltip.temporarilyOff = true;
Anything after this point, the tooltip won't be triggered, and all the elements will keep their title attributes. When I am done with what I am doing, I just need to set the flag back to false and tooltip will work exactly like before.
I can probably make this into jQuery plugin for easier calls and also hide the slightly ugly variable name... but anyway that's the idea. I think this is a much better fix as it won't force jQuery to remove the title attribute for nothing, then adding it back afterward doing twice the useless work.
Here is the updated example forked from #Jasen's original jsFiddle:
Codenamezero is a nice example of extending an object in jQuery/js but you can do this out-of-the-box:
$(document).tooltip("disable").tooltip("hide");
$(document).tooltip("enable").tooltip("show");
I have validation where this method can be useful to override defaults

Resizing a specific TinyMCE editor added by JS

I am adding/replacing two textareas with TinyMCE via two different javascript clicks/calls. They have different IDs and are being added correctly by the 'execCommand' call:
tinymce.execCommand('mceAddControl',true,'comment1');
However, I am having trouble resizing the objects when there are more than one on screen. If there is just one I am able to successfully call 'resizeTo' using the 'activeEditor' to resize the object, like this:
tinymce.execCommand('mceAddControl',true,'comment1');
var ed = tinymce.activeEditor;
ed.theme.resizeTo(400, 200);
But when there is more than one editor, I cannot use 'activeEditor' and I don't know how to select a specific editor to resize. I have tried the following, but it didn't work:
var edd = tinymce.get('comment2');
edd.theme.resizeTo(350,306);
Any help/suggestions? Thanks!
In order to have to working tinymce editors with textareas as source elements you have given each of those testareas a unique id. This id will help you to get the correct editor instance.
Use
var editor = tinymce.get('your_textarea_id');
to get the correct editor. That's all.

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