TinyMCE instances in jquery sortable
I'm stumped and frustrated so time to ask for help. Done a lot of googling but yet to find a solution that works for me.
What I have is a whole bunch of divs that can be sorted using Jquery sortable, some of divs contain a TinyMCE instance. Which is all fine until you try to move a div that contains a TinyMCE instance - when you do TinyMCE seems to refresh itself and creates a new instance which you then therefore lose the data etc. And then the whole page breaks as the javascript no longer works :). During this time I get javascript constructor errors etc in Firebug.
What I have decid开发者_运维百科ed the best way to go is when the div starts to get dragged remove tinymce from the text area and when it is placed in it's new position insert tinymce back in.
I can remove it fine but having trouble adding it back in - as I get more constructor errors.
Note: TinyMCE automatically gets added to all my text areas within the system I'm using so trying to avoid messing with TinyMCE.
In the code below I'm simply targeting a specific textarea id for testing purposes.
$cols.sortable({
cursor: 'move',
revert: true,
opacity: 0.6,
placeholder: 'widgetplaceholder',
forcePlaceholderSize: true,
connectWith: cols,
zIndex:9000,
cancel: ".collapsable_box_editpanel_groups, .collapsable_box_content",
start: function(e, ui) {
// removes tinymce ok from textarea
tinyMCE.execCommand( 'mceRemoveControl', false, 'textarea1' );
},
stop: function(e,ui) {
// breaks here - constructor error
tinyMCE.execCommand( 'mceAddControl', true, 'textarea1' );
$(this).sortable( "refresh" );
}
});
Anybody else have any other solutions? If you need more information please let me :)
Hey if you already have data in your MCE instances, to avoid losing it, you can try this:
start: function(e, ui){
$(this).find('.tinyMCE').each(function(){
tinyMCE.execCommand( 'mceRemoveControl', false, $(this).attr('id') );
});
},
stop: function(e,ui) {
$(this).find('.tinyMCE').each(function(){
tinyMCE.execCommand( 'mceAddControl', true, $(this).attr('id') );
$(this).sortable("refresh");
});
}
In my case i classed all MCE Instances with .tinyMCE
For version 4 of TinyMCE
start: function (e, ui) {
$(ui.item).find('textarea').each(function () {
tinymce.execCommand('mceRemoveEditor', false, $(this).attr('id'));
});
},
stop: function (e, ui) {
$(ui.item).find('textarea').each(function () {
tinymce.execCommand('mceAddEditor', true, $(this).attr('id'));
});
}
Well, a stable solution of this problem, for TinyMce v.4+ is :
start: function(e, ui){
tinyMCE.triggerSave();
},
stop: function(e,ui) {
$(this).find('textarea').each(function(){
tinyMCE.execCommand( 'mceRemoveEditor', false, $(this).attr('id') );
// if your tinymce instance have different settings
tinymce.init(tinymce_settings($(this).attr('data-type')));
tinyMCE.execCommand( 'mceAddEditor', false, $(this).attr('id') );
});
}
If your textarea have more than one type of settings applied, you must declare tinymce.init(settings)
before each reset, otherwise the last one applied will apply to all.
An easy way to variate settings is to set a flag of settings type on your textarea such as :
<textarea data-type="settings_one"></textarea>
<textarea data-type="settings_two"></textarea>
and then use a loader function which will distrubute the necessary one :
function tinymce_settings(type) {
var settings;
switch(type) {
case 'settings_one' :
settings = {...}
break;
}
return settings;
}
For anyone trying to dynamically assign "textarea1", the draggable is in the ui object as ui.item. For one textarea per sortable:
tinyMCE.execCommand( 'mceAddControl', false, $('textarea',ui.item)[0].id );
tinyMCE.execCommand( 'mceRemoveControl', false, $('textarea',ui.item)[0].id );
No, there is no other solution. This is the way it needs to be done.
When manipulatin dom elements containing tinymce instances you need to deactivate them and reactivate them when you are done with the dom operation using mceRemoveControl
and mceAddControl
.
I ended up just destroying and recreating the edit on sortable stop() event:
stop: function (e, ui) {
$(this).find('textarea').each(function () {
tinyMCE.get($(this).attr('id')).destroy();
// the code below locates and evals the editor init script
eval($(this).parents('.item').find('script').html());
});
}
Works like a charm and is probably a better option than other suggestions to destroy the editor on start() event and then re-create on stop() - because this way you are still dragging visually appealing editor. P.S. Using TinyMCE 4.5.2
I have a dynamic form with multiple paragraphs that can all be edited with TinyMCE. To allow re-sorting of the paragraphs, I added buttons that move the textareas up and down.
I managed to get it to work using an alt="textareaid" on the button that moves a textarea up or down, and using this textareaid for the mceRemoveEditor and mceAddEditor commands. The textarea has to be in a div with class="textarea_container".
$('.move_textarea_up').click(function(){
var tinymceid= $(this).attr("alt");
tinyMCE.execCommand('mceRemoveEditor', false, tinymceid);
$(this).closest('div.textarea_container').insertBefore($(this).closest('div.textarea_container').prev());
tinyMCE.execCommand('mceAddEditor', false, tinymceid);
});
$('.move_textarea_down').click(function(){
var tinymceid= $(this).attr("alt");
tinyMCE.execCommand('mceRemoveEditor', false, tinymceid);
$(this).closest('div.textarea_container').insertAfter($(this).closest('div.textarea_container').next());
tinyMCE.execCommand('mceAddEditor', false, tinymceid);
});
For me worked solution is here. For version 4 of TinyMCE
My Case : I am using sortable jquery with repeater field for meta box inside wordpress. Each sortable element have textarea converted into tinyMCE editor.
When I was moving one element from sortable items, editor inside only that one element get broken and no content displayed in visual tab. I used mceRemoveEditor and mceAddEditor to prevent problem.
So I came to this final solution after combining some of above solutions. Thanks to @Honorable Chow , @pragmar @Sonicdesign Well your solutions didn't worked for me as they are, so I modified them. Here is my code which is worked fine for me.
start: function(e, ui){
tinyMCE.execCommand( 'mceRemoveEditor', false, jQuery('textarea',ui.item)[0].id );
},
stop: function(e,ui) {
tinyMCE.execCommand( 'mceAddEditor', false, jQuery('textarea',ui.item)[0].id );
}
I has able to solve similar problem with:
tinymce.activeEditor.setMode('readonly');
and
tinymce.activeEditor.setMode('design');
this works for version 4.3.x
i have done
$("#stores-container").sortable({
stop: function(event, ui) {
textareaID = $(ui.item).find(' textarea').attr('id');
textareaVal=$(ui.item).find(' textarea').val();
editorID=$(ui.item).find('.mce-container').attr('id');
$( "#"+editorID ).remove();
$('#'+textareaID).show();
tinymce.init({selector: '#'+textareaID});
}
});
start: function (e, ui) {
tinyMCE.execCommand( 'mceRemoveEditor', false, editor_id );
},
stop: function (e, ui) {
tinymce.execCommand('mceAddEditor', true, editor_id);
}
This works great just I used for one editor. Thank you very much :) .
精彩评论