CKEDITOR 4: remain editor height when toggling toolbar - javascript

I use the classic version of ckeditor 4. The system I'm working with is a self-written CMS. That means I've got multiple cases where I need the ckeditor. Some of them are having the resizing-option/plugin enabled. In addition, most of them have an enabled toolbar.
When I resize the editor, the height of it changes (of course :D). In this case, it is intentional by the user. But when I toggle the toolbar, the height changes a lot, which is not intentional or wanted by the user.
Is there a possibility to let the editor remain its resized height when expanding or collapsing the toolbar? In the end, the editor in total should remain at the same height, no matter if the toolbar is expanded or collapsed.
Hope I described my problem comprehensibly :)
Collapsed: 280px
Expanded: 329px
Both states should have 280px

Store the height just before collapsing or expanding the toolbar and reapply it afterwards. For a CKEditor instance called editor1:
let ckHeight;
CKEDITOR.instances.editor1.on('beforeCommandExec', function(evt) {
if (evt.data.name == 'toolbarCollapse') {
ckHeight = evt.editor.container.$.offsetHeight;
}
});
CKEDITOR.instances.editor1.on('afterCommandExec', function(evt) {
if (evt.data.name == 'toolbarCollapse') {
evt.editor.resize(evt.editor.container.$.offsetWidth, ckHeight);
}
});

Related

Show the button at the table bottom even when the window is very small

I have a table sorter html page, the sample is here.
$('table').tablesorter({
theme: 'blue',
widgets: ['zebra', 'scroller'],
widgetOptions: {
scroller_height: 400
}
});
How can I make the bottom button visible even when the windows height is very small (say, can only show one or two rows)? Ideally scroller_height can be some type like $(window).height()/2 and it can automatically update when the window is resized.
The expected is that even when the window is small, the bottom button appears in the screen without scroll action.
If you want to make the scroller window dynamically adjust its height, there are two demos on the main wiki page under Widgets > Scroller.
http://jsfiddle.net/Mottie/txLp4xuk/2/
http://jsfiddle.net/Mottie/abkNM/8037/
Essentially, all you need to do is adjust the outer scroll window height
$('.tablesorter-scroller-table').css({
height: '',
'max-height': height + 'px'
});
Here is the demo you shared updated, and has a minimum height set to 100px.
I'd say that there are a few ways to achieve what you want, and one easy way is to:
create a function that checks the visibility of your table versus the viewport;
Code below:
function checkVisible() {
var bottom_of_table = $("#mytable").offset().top + $("#mytable").outerHeight();
var bottom_of_screen = $(window).scrollTop() + $(window).height();
if(bottom_of_screen > bottom_of_table){
$("#buttons-container").removeClass('bottom-fixed');
}
else {
$("#buttons-container").addClass('bottom-fixed');
}
}
If it exceeds the viewport, add a CSS class to your buttons container that fixes it to the bottom of the screen. Otherwise, remove this class and display the button container normally, at the bottom of the table.
You'd want to run this function-check on load and on window resize, as follows:
$(document).ready(function() {
checkVisible();
$(window).on('resize', checkVisible);
});
I've updated your fiddle: http://jsfiddle.net/12nt19vg/12/show/
Try resizing the window and let me know if this is the behavior you're looking for.
EDIT: Incorporating your additional spec in the comments, I've added an outer div to your buttons container and modified your CSS to visually create the effect that I think you're looking for.
Please take a look at this fiddle: http://jsfiddle.net/12nt19vg/27/show/

How to force a drop-down to move down on IE 11?

I have the following drop-down :
<select>
<option></option>
<option>Closed</option>
<option>Open</option>
</select>
with the associated style:
select {
font-family: Cursive;
width:200px;
position: relative;
z-index: 100;
padding-right: 25px;
}
My problem is that the drop-down is moving upward on IE 11:
Where as on chrome it is working fine.
Any idea ?
Like mentioned in the comments, select menus are very browser specific and hard to style. Some even send the options into the twilight zone where they are seemingly not even a part of the window and any events will return null. It might not be worth trying to get this to look the same across browsers, also because of the mobile implementations, but I happened to be making something like this for no apparent reason. As it coincides with your question I might as well post it.
It's not the prettiest thing when it comes to HTML and CSS because it requires four additional elements - one wrapper (commonly used for styling select boxes with overflow hidden but I took a slightly different approach because I thought it looked better) and three absolutely placed elements. One is a styled button, another will hide the scrollbar that appears and the third is a minor hack.
Most important thing is that the user will not be able to click the select menu itself. When this happens, most is lost because after that it's limbo. For that the third element will be used. It will be put on top of the select box. Then when it's clicked, instead of directly opening the menu it will be faked by changing the size of the select element. The div covering the right side also serves another purpose. It's initially placed at the bottom and by getting it's offset we'll know the height of the box. This will be used to resize the button and set the correct size for the overlaying div.
Looks to be behaving quite predicatbly on all major Windows desktop browsers. For the mobile implications this script uses a touch support feature test and reverts to normal layout if that is the case. Could probably be tweaked (with a screen size check) to not exclude trackpad users.
Demo
Not too much relevant CSS. But important to style body background the same as the bar on the right. Transparency is used so the actual menu isn't visible before the image for the button loads.
$(function() {
var hub = $('#box'), list = $('select'),
impel = $('#open'), commit = $('#mark'), tract = $('#refer'),
zenith = tract.position().top,
extent = list.children().length, active;
if (touch()) {
impel.add(commit).add(tract).remove();
hub.fadeTo(0,1);
return;
}
impel.add(commit).height(zenith);
tract.addClass('bar');
hub.fadeTo(0,1).on('mouseup click', function(e) {
e.stopPropagation();
});
commit.mouseup(function() {
flip();
show();
active = true;
});
list.add(impel).click(function() {
flip();
active = !active;
if (active) show();
else hide();
});
$(window).click(function() {
if (active) {
flip();
hide();
active = false;
}
});
function show() {list.attr('size', extent)}
function hide() {list.removeAttr('size')}
function flip() {commit.toggle()}
function touch() {
return 'ontouchstart' in window
|| navigator.maxTouchPoints > 0
|| navigator.msMaxTouchPoints > 0;
}
});

Angular-gridster doesn't work on small screens

The problem
I noticed that angular-gridster stops working if the browser window is minimized to the point there's not much space around the gridster tiles (see image 2). However, gridster works alright when maximizing the window, and the elements are draggable and resizable again.
Progress
I modified the $scope.gridsterOpts object in the relevant controller and ensured that pushing, floating, swapping are all set to true, but that didn't solve the problem.
fiddle
In addition, I noticed that the same behavior could be found in
this fiddle - the "result" window has to be pretty big in height/width so the demo would work.
I do not include my project code as I think it's useless since I see this behavior in every demo of angular-gridster.
Did anyone experienced the same problem?
Thanks.
screenshot: working
screenshot: not working
This seems to be by design. As you can see here, angular-gridster has a so-called "mobile mode", meaning the plugin will stop working below a certain (configurable) screen width:
$scope.gridsterOpts = {
/// (...)
isMobile: false, // stacks the grid items if true
mobileBreakPoint: 600, // if the screen is not wider that this, remove the grid layout and stack the items
mobileModeEnabled: true, // whether or not to toggle mobile mode when screen width is less than mobileBreakPoint
/// (...)
};
The mobileBreakPoint is one more important think. The value of mobileBreakPoint 600 it means it will take half of the width in the screen if we set div width more then 600px it will work.If we need for minimum div width we need to change mobileBreakPoint value based on div width
$scope.gridsterOpts = {
mobileBreakPoint: 100, // if the screen is not wider that this,remove the grid layout and stack the items
};

TinyMce submenu's not sticking to toolbar when using fixed_toolbar_container and absolute position

We would like to have a greater control of where and how we position the tinymce toolbar. We found this option fixed_toolbar_container which solves a lot for us but brings us an anoying problem. The documents say the fixed_toolbar_container (http://www.tinymce.com/wiki.php/Configuration:fixed_toolbar_container) can be used to have a fixed toolbar. But we actually would like to use it to be absolute so we can position it relative to it's container.
I created a JS Fiddle to demonstrate the problem: http://jsfiddle.net/ronfmLym/2/. When you open the toolbar by clicking on the text the toolbar will be positioned absolute. When you open a submenu (i.e. by clicking on "file") a submenu will open. Now when you start scrolling the submenu won't stick to the toolbar. This is because these submenu's get the mce-fixed class because we set the fixed_toolbar_container property.
<div class="element">
<div class="toolbar-container"></div>
<div class="content">
<p>Text</p>
</div>
</div>
Is there any way to make the submenu's stick to the toolbar when positioned absolute and scrolling? Keep in mind that we are switching to a fixed positioning when the toolbar is going off screen.
We thought we could maybe fix it by modifying the container element of de submenu's by using the piece of code below and overwriting the top-position of the submenu's and setting the positioner to absolute with css. But that seems to mess up the tooltips and tinymce doesn't recalculate the "left" css-property of the submenu's so the position in still off.
tinymce.ui.Control.prototype.getContainerElm = function() {
return document.getElementById('toolbar-container');
};
The only corresponding question I could find on stackoverflow was this one: TinyMCE push down submenus using fixed_toolbar_container, no answers there.
Tried wrapping the toolbar in a div and using position:relative; to try and hack it together, but didn't cooperate this time.
It appears that the toolbar actually is accounting for its position at the time of click. So your only conflict is if the opened toolbar is position:absolute and then changes to position:fixed or vice versa.
Your best [manual] bet would be to call a function at the same time that you change the position of the toolbar that:
Detects if any menus are open.
Changes the toolbar position.
Reopens the menus that were open.
The lazy (discouraged) fix would be to close all submenus whenever the position changes. This will fix the layout, but it will require the user to click once again to bring the menu back.
Sorry this isn't a silver bullet answer :(
This answer follows Brian John's suggestion:
I'm using this method to position any open mce-floatpanel (This is typescript, but it shouldn't be too hard to convert to ES or whatever you need.):
positionTinyMceDropdowns() {
// TODO: You'll need to replace all occurrences
// of this.mceWrapperElement with whatever is
// wrapping your TinyMCE. If you have only a
// single instance, you can just replace it
// with document
const button = <HTMLElement> this.mceWrapperElement.getElementsByClassName('mce-opened').item(0);
const items = document.getElementsByClassName('mce-floatpanel');
let wrapperNode: HTMLElement;
for (let i = 0; i < items.length; i++) {
const currentItem = <HTMLElement> items.item(i);
if (currentItem.style.display !== 'none') {
wrapperNode = currentItem;
break;
}
}
if (!wrapperNode || !button) {
return;
}
const styles = wrapperNode.style;
styles.display = 'block';
styles.position = 'absolute';
const bodyRect = document.body.getBoundingClientRect();
const buttonRect = button.getBoundingClientRect();
// get absolute button position:
let y = buttonRect.top - bodyRect.top;
y += 33; // toolbar line height;
styles.top = `${Math.floor(y)}px`;
}
The instances I found in which it needs to be called:
on window scroll (or if the editor is wrapped in a scrolling container, then whenever that scrolls)
on window resize (or if the editor is wrapped in a container that resizes without the window being resized, then whenever that container is resized)
So here's a sample for the simplest case in angular (again, adept to whichever js framework you're using):
import { HostListener } from '#angular/core';
// ...
#HostListener('window:resize', ['$event'])
#HostListener('window:scroll', ['$event'])
public onResize() {
this.positionTinyMceDropdowns();
}
Interestingly on iOS devices (and perhaps other mobile devices?) mce-floatpanel wasn't even positioned correctly after it had just been opened. So I had to add this:
tinymceConfig.setup = (editor: TinyMceEditor) => {
editor.on('init', () => {
const panel = this.mceWrapperElement.querySelector('.mce-tinymce.mce-panel');
if (panel) {
panel.addEventListener('touchend', () => {
this.positionTinyMceDropdowns();
});
}
});
};
I think the config setting fixed_toolbar_container is poorly explained in TinyMCE 6 documentation but when you correctly configure it, you'll find it will work much more nice (especially for inline mode) than the default configuration that tries to emulate position:sticky.
In practice, you want to fixed_toolbar_container set to a string that's CSS selector for the container, typically something like "#mycontainer".
After that, you can move the container element using its CSS properties, the TinyMCE user interface nicely follows around. (Modulo typical TinyMCE bugs, of course. For example, the submenus overflow to right with very narrow viewports.)
Note that TinyMCE positions stuff where it uses position:absolute relative to fixed_toolbar_container container and if you move that container around, in some cases you must execute editor.dispatch("ResizeWindow") to trigger TinyMCE to re-calculate the absolutely positioned elements.
See demo using custom container with position:sticky at https://jsfiddle.net/8bndv26t/1/.

Setting size of custom edit form for Kendo UI grid with AngularJS

I have a custom edit form for my Kendo UI grid, but I need to make it wider to fit my layout. The way I currently do it works, except for that the position of the Update and Cancel button does not get adjusted (= they wind up in the middle instead of to the right).
Here is how I adjust the size (by specify this in the edit field of the grid options):
edit: function (e) {
var popupWindow = e.container.getKendoWindow();
popupWindow.setOptions({
width: 640
});
}
Here is a plunker:
http://plnkr.co/edit/bRaFZFjrzR3IyeVrmulR
What is the best way to set the width of the edit form so that the buttons, etc. also get positioned correctly?
I got it working by setting the width of k-edit-form-container to auto:
edit: function (e) {
var popupWindow = e.container.getKendoWindow();
e.container.find(".k-edit-form-container").width("auto");
popupWindow.setOptions({
width: 640
});
Updated plunker: http://plnkr.co/edit/bRaFZFjrzR3IyeVrmulR
I found solution here: http://dojo.telerik.com/aVOj

Categories