Reputation: 4692
I have a TinyMCE that is set over a TextArea, and I want this editor area to ocuppy all the space of its parent div, all times.
I have a JS function that get the current space and set the textarea.style.height to it, but when I enables TinyMCE it seems to stop working.
Also, the textarea has width: 100%; it doesn't resize by HTML rendering when it's using TinyMCE too.
Any ideas?
Upvotes: 35
Views: 66069
Reputation: 818
This is an old question, but apparently it still drags a lot of attention nowadays (Second half of 2020).
Sadly, with the release of the TinyMCE v5, most of the workarounds I found simply do not work anymore. I am sure they worked once, but every TinyMCE release seems to bring new "constrainings" that cripple those workarounds...
Without making it a discussion, I believe it is the cost of evolution. For an old product like the TinyMCE, it is incredible to see it is still around and kicking, staying way above the competition. It is by far one of the most efficient and flexible solutions for all environments, including mobile and for those new languages and frameworks that born since (which seems to be a trend lately, with new ones coming out of the blue every day).
So, with that in my mind, and after so many (failed) attempts to make most of the proposed solutions work, I decided to dig into the source code (TinyMCE v5.4) to better understand it. What I found was a much superior product overall, and that the solution everyone has been looking for is much simpler to implement than I was anticipating.
With no further delay, here my solution that simply works. It implements an editor that takes the entire document area (or whatever area you want), which WILL resize with the browser, requiring NO script, NO hack, and NO trick that could cause cross-browsing issues. Here's how:
<html>
and <body>
DOM objects the missing properties of size and adjust the spacing accordingly to your needs:html, body {
width : 100%;
height : 100%;
margin : 0 !important;
padding : 0 !important;
overflow : hidden; /* Required if you want to have the editor taking the entire page. */
/* Otherwise, set as you need it. */
}
<textarea>
to be embedded inside a <form>
object. Regardless if you use it as suggested or not, simply give to it and ID and the following CCS properties (in my case, it is set as <form method="post" id="editorBase">
):#editorBase {
display : block !important;
width : 100% !important;
height : 100% !important;
}
tinymce.init({
// Required Settings:
width : '100%', // Note value is set as "string".
height : '100%', // Note value is set as "string".
resize : false, // Suggestion: disable the statusbar resizing. :)
// Suggested Settings:
toolbar_sticky : true, // Keep the menu and tollbar in a fixed position .
toolbar_location : 'top', // You can try 'top', 'bottom' or 'auto'.
toolbar_mode : 'floating', // It is simply a button behavior settings.
// Options are: 'floating', 'sliding', 'scrolling', or 'wrap'.
});
Yet in the TinyMCE Init settings, find the plugins
item and remove the autoresize
option from it (it is the most important step of all!).
Done! Try and test it! (YES! It is all done!)
With those simple adjustments you can set the editor to fit any design. Feel free to adjust it as needed. Just don't forget to set the width
and the height
properties in the TinyMCE Init settings as strings, and keep it consistent with the CSS settings for the <form>
.
The reason to use strings in the width
and height
properties of the TinyMCE Init settings instead of numeric values is to allow you to use "%", "em", "pt", etc... Otherwise, the presented solution would never work.
Another trick to make it even more neat is to set the editor as borderless skin (a feature only present in the "professional" version of TinyMCE). No, it is not a hack, it is a siple adjustment to the CSS and totaly allowed by TinyMCE's EULA and Licensing. Simply add the following CSS to your page Stylesheet and it enjoy a borderless editor for free:
.tox-tinymce { border:none !important; }
Could not be easier than that.
Happy coding!
Upvotes: 1
Reputation: 4049
None of these solutions worked 100% for me. I needed the height to adjust on initialization and during edits. What I did is grab the height of the HTML element in the iFrame, and then applied the height to the iFrame with an extra 100px.
Here's my solution: (added img max-width for responsive images)
setup: function(editor) {
editor.on('init', function (e) {
$("#editor_textarea_ifr").contents().find('img').css("max-width","100%");
iframeHeight = $("#editor_textarea_ifr").contents().find("html").height();
$("#editor_textarea_ifr").css("height",iframeHeight + 100);
});
},
init_instance_callback: function (editor) {
editor.on('NodeChange', function (e) {
$("#editor_textarea_ifr").contents().find('img').css("max-width","100%");
iframeHeight = $("#editor_textarea_ifr").contents().find("html").height();
$("#editor_textarea_ifr").css("height",iframeHeight + 100);
});
}
Upvotes: 0
Reputation: 4692
The point is that TinyMCE generates an iframe in the place of the textarea, with this ID: originalID+"_ifr", and a table originalID+"_tbl" for holding the controls and the editor area.
document.getElementById(id+'_tbl').style.width='100%'
Change dinamically document.getElementById(id+'_ifr').style.height
to the height you want, through JS.
This is the script I'm using for this:
function toScreenHeight(id, minus) {
var height;
if (typeof(window.innerHeight) == "number") //non-IE
height = window.innerHeight;
else if (document.documentElement && document.documentElement.clientHeight) //IE 6+ strict mode
height = document.documentElement.clientHeight;
else if (document.body && document.body.clientHeight) //IE 4 compatible / IE quirks mode
height = document.body.clientHeight;
document.getElementById(id).style.height = (height - minus) + "px";
}
You can use the code and function calls inside onload
and onresize
body
events.
Upvotes: 14
Reputation: 17570
With version 4 and the option to use flexbox layout in the browser I did the following to get a full width,height editing experience of the parent div.
It should be easy to put the css into a file if you prefer adding it to your existing styles.
var css = '.tinycme-full .mce-edit-area {display:flex;flex-flow:column;} .tinycme-full .mce-edit-area iframe {flex:1 1 auto;} .tinycme-full {height:100%;} .tinycme-full .mce-tinymce.mce-container { width:100%;height:100%;border:0; } .tinycme-full .mce-panel{border:0} .tinycme-full .mce-container-body.mce-stack-layout {display: flex; flex-flow: column;height: 100%;} .tinycme-full .mce-stack-layout-item{ flex: 0 0 auto;} .tinycme-full .mce-edit-area{flex:1 1 auto;} ',
head = document.head || document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css';
if (style.styleSheet) {
style.styleSheet["cssText"] = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
The idea is that it make all the needed divs take up as much column space as needed to fill the parent 100% and its done by putting a div around your textarea: <div class="tinycme-full"> <textarea ... /></div>
No jquery or other dependencies are needed andd it now fills the parent 100%.
Upvotes: 2
Reputation:
SyCoDeR is right but I followed a slightly different path though probably with the same results.
/*Container, container body, iframe*/
.mce-tinymce, .mce-container-body, #code_ifr {
min-height: 100% !important;
}
/*Container body*/
.mce-container-body {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
/*Editing area*/
.mce-container-body .mce-edit-area {
position: absolute;
top: 69px;
bottom: 37px;
left: 0;
right: 0;
}
/*Footer*/
.mce-tinymce .mce-statusbar {
position: absolute;
bottom: 0;
left: 0;
right: 0;
}
Revised because TinyMCE changes the id's with menu/toolbar additions or deletions. This works no matter what you do with it.
Upvotes: 1
Reputation: 8520
None of the above were working for me in TinyMCE v4, so my solution was to calculate the height based on the toolbars/menu bar/status bar, and then set the height of the editor, taking those heights into consideration.
function resizeEditor(myHeight) {
window.console.log('resizeEditor');
myEditor = getEditor();
if (myEditor) {
try {
if (!myHeight) {
var targetHeight = window.innerHeight; // Change this to the height of your wrapper element
var mce_bars_height = 0;
$('.mce-toolbar, .mce-statusbar, .mce-menubar').each(function(){
mce_bars_height += $(this).height();
});
window.console.log('mce bars height total: '+mce_bars_height);
myHeight = targetHeight - mce_bars_height - 8; // the extra 8 is for margin added between the toolbars
}
window.console.log('resizeEditor: ', myHeight);
myEditor.theme.resizeTo('100%', myHeight); // sets the dimensions of the editable area
}
catch (err) {
}
}
}
In my case, I wanted the editor window to match the width and height of the actual window
, since the editor would come up in a popup. To detect changes and resize, I set this to a callback:
window.onresize = function() {
resizeEditor();
}
Upvotes: 3
Reputation: 33
I'm using pure css solution to achieve this (tinyMCE 4.0.20).
Set iframe height to 100%:
tinymce.init({ height: '100%' })
Add styles to auto-resize iframe container:
.mce-tinymce { height: auto; width: 100%; position: absolute; left: 0; top: 0; bottom: 0; }
.bq-editor .mce-container-body { height: 100%; }
.bq-editor .mce-edit-area { position: absolute; top: 57px; bottom: 0; width: 100%; height: auto; }
Note: I have one toolbar line, and top: 57px; in .bq-editor .mce-edit-area is toolbar padding.
Upvotes: 1
Reputation: 93621
The wrapper of iframe (its ID finish by _ifr) is the first parent of span that it has application as role . Thus, To get the wrapper :
$('span[role=application]').parents(':eq(0)')
So to Resize height:
$('[id$=_ifr]').css('height',$('span[role=application]').parents(':eq(0)').css('height'))
To resize width
$('[id$=_ifr]').css('width',$('span[role=application]').parents(':eq(0)').css('width'))
Upvotes: 0
Reputation: 127
I had the same problem, after reading this thread I ended up with this code
init_instance_callback: function (inst) {
setTimeout(function () {
document.getElementById(inst.id + '_ifr').style.height= (document.getElementById("theContainerDiv").offsetHeight-85) + 'px';
},1000);
},
I resize the "_ifm" element instead of the "_tbl", since resizing the "_tbl" didn't resize the edit area for me. Then I leave some space for the toolbar and statusbar by making the "_ifr" 85 pixels shorter then the container div.
I had to use setTimeout to make it work, maybe because I have an animation that displays the container element.
Upvotes: 1
Reputation: 10326
Nowadays, you should use the autoresize plugin that comes with tinyMCE. You will have to call tinyMCE like this (jQuery version):
$('.tinymce').tinymce({
theme : 'advanced',
plugins : 'autoresize',
width: '100%',
height: 400,
autoresize_min_height: 400,
autoresize_max_height: 800,
});
I made the experience, that it may be helpful to manually call the resizing in the init_instance_callback
to provide the correct height on init. Add this parameter to the passed options, if you need this:
init_instance_callback: function (inst) { inst.execCommand('mceAutoResize'); }
Upvotes: 56
Reputation: 1411
in tinymce 3.4.6, set
width:'100%'
in init option will solve the problem.
Upvotes: 10
Reputation: 736
If you're doing tiny MCE dynamically via JS, you can run into timing issues where the MCE editor is not yet available for style adjustments. To combat this, you can use an old school timeout.
In this example, I'm using a "j" namespace for JQuery. If your editor is in a fluid div that changes size, you may want include this in a $(window).resize(function() { }); listener.
setTimeout(function(){
$j('.mceEditor').css('width','100%').css('minHeight','240px');
$j('.mceLayout').css('width','100%').css('minHeight','240px');
$j('.mceIframeContainer').css('width','100%').css('minHeight','240px');
$j('#'+[INSERT TEXTAREA ID HERE]+'_ifr').css('width','100%').css('minHeight','240px');
},500)
Upvotes: 4