TinyMCE editor fixed size with no scrollers? - editor

At the moment I have this:
tinyMCE.init({
// General options
mode : "exact",
elements : "fkField, lkField, ukcField, khField",
theme : "advanced",
plugins : "table",
width : "300",
height: "185",
// Theme options
theme_advanced_buttons1 : "fontsizeselect, bold,italic,underline,bullist, cleanup, |,justifyleft,justifycenter,justifyright",
theme_advanced_buttons2 : "tablecontrols",
theme_advanced_buttons3 : "",
theme_advanced_buttons4 : "",
theme_advanced_toolbar_location : "bottom",
theme_advanced_toolbar_align : "center",
theme_advanced_resizing : false
});
This gives me a editor with the size of 300x185.
Now in this editor, I would like to do so you can only write until the editor is full. (without the scroller)
So you are unable to enter more text, and the scroller should not appear (disable scrolling)
Right now you can at the bottom of inside the editor just make new line and it will add the scroller <- which i do not want to happen
How can i do this? Is this unpossible? I have made research for some time now, but maybe it's just me searching wrong..
Thanks

add in a ccs file the following code
.mceContentBody{
overflow-y:hidden!important;
}
and add the path of css file in content_css attribut of tinymce
content_css : /path/to/css/file.ss

You will need to write an own plugin. Check the editor height on each Keystroke (you may use the built in tinymce event onKeyUp). If the heigth changes remove the last inserted code.
EDIT: Howto get the current editor iframe heigth
var currentfr=document.getElementById(editor.id + '_ifr');
if (currentfr.contentDocument && currentfr.contentDocument.body.offsetHeight) { //ns6 syntax
currentfr.height = currentfr.contentDocument.body.offsetHeight + 26;
}
else if (currentfr.Document && currentfr.Document.body.scrollHeight) { //ie5+ syntax
currentfr.height = currentfr.Document.body.scrollHeight;
}

I got it to work by adding this to my extra tinyMCE CSS file:
IFRAME {overflow:hidden;}
Previously, the scrollbars were only off in Firefox. This fixes it for Chrome as well. However, it does add a gray bar the side of a scrollbar at the bottom, so I need to enlarge the height of my text editor.

for me it worked by just adding rules to a regular stylesheet, it wasn't needed to add a css file to content_css attribute (example is in scss)
.my-tinymce-container {
width: 200px;
.mce-edit-area {
height: 200px;
overflow-y: hidden;
}
}

A lot simpler and easy solution would be:
tinymce.init({
selector: '#container',
},
init_instance_callback: function (ed) {
tinymce.activeEditor.getBody().style.overflow = 'hidden'
},
});
Explanation:
In Init callback get the body for TinyMCE and change style as required.
In this case to remove scrollbar overflow = 'hidden'.

Related

Add class/id to path in TinyMCE4

Quick question:
Is there a way to add class and/or ID of the elements in the path of TinyMCE status bar under content?
TinyMCE has no such capability built into its status bar. If you wanted to add that you could do so by modifying the code. I would note that with any type of longer ID or Class labels that status bar will get filled up quickly which is why it does not do so by default.
The Elements in the Statusbar have a bunch of classes from Tiny Editor, you can examine it in the browser (chrome or firefox) with f12.
From there, it is no problem to override the current styling with some code like
.mce-statusbar.mce-container {
position : relative;
height : 0;
margin-top : -20px;
opacity : 0.5;
background-color :#fff;
border : 1px solid #333;
}
Beside, you can manipulate the code, where content is written in the Statusbar. See Plugin Wordcount for example. They are using some code like this to update the statusbar and enter a class name:
if (statusbar) {
Delay.setEditorTimeout(editor, function () {
statusbar.insert({
type: 'label',
name: 'wordcount',
text: ['Words: {0}', getCount()],
classes: 'wordcount',
disabled: editor.settings.readonly
}, 0);
editor.on('setcontent beforeaddundo undo redo keyup', debouncedUpdate);
}, 0);
}

How to change the default position of button tooltips in CKEditor 5

Having a small issue with tooltips in the editor, read the api but can't understand what it is saying and I can't seem to find examples anywhere that I can understand either.
I have set up a Classic Editor build, and all the buttons on the toolbar have tooltips with the default position below the button, I want to be able, just for this one instance of the editor, to change the tooltip position to above the buttons instead. The instance is set up like this:
ClassicEditor.create( document.querySelector( '#content' ) )
.then( editor => {
console.log( 'Editor was initialized', editor );
this.annEditorInstance = editor;
} )
.catch( err => {
console.error( err.stack );
} );
That creates an editor instance that is set up exactly as I want, except for the issue with the tooltip. How do I change this? Thanks in advance.
There are two approaches to the problem:
CSS
Tooltips elements have either .ck-tooltip_s or .ck-tooltip_n class. By default all CKEditor 5 tooltips have the former so you could override it in your styles and make it act like the later:
<style>
.ck.ck-tooltip.ck-tooltip_s {
bottom: auto;
top: calc(-1 * var(--ck-tooltip-arrow-size));
transform: translateY( -100% );
}
.ck.ck-tooltip.ck-tooltip_s .ck-tooltip__text::after {
top: auto;
bottom: calc(-1 * var(--ck-tooltip-arrow-size));
transform: translateX( -50% );
border-color: var(--ck-color-tooltip-background) transparent transparent transparent;
border-width: var(--ck-tooltip-arrow-size) var(--ck-tooltip-arrow-size) 0 var(--ck-tooltip-arrow-size);
}
</style>
JS
The UI of the editor is an MVC(VM) structure. The position of the tooltip can be controlled using the JS and the Button#tooltipPosition property ('s' or 'n').
E.g. you can access the toolbar UI elements using editor.ui.view.toolbar and change their properties:
editor.ui.view.toolbar.items.map( item => item.tooltipPosition = 'n' )
but note that not all toolbar items are buttons. Some, for instance, are dropdowns so you'd need to use item.buttonView.tooltipPosition = 'n' in that case. So unless you really want to use JS, I'd go with a simple CSS solution.

How can I dynamically resize a select2 input to be the same width as the selected option?

I'm building a 'natural language' search form using a series of inline select inputs, using jQuery Select2 for styling. The widths of the Select2 inputs appear to be set to the width of the selected option on initialisation, which is great. I just can't work out how to get the width to update when the selected option is changed. Any ideas?
Many thanks!
Try to add this to yor CSS file:
.select2-container {
width: 100% !important;
}
It solved my resize problems with select2
(Edited: I do not use placeholders)
You can use window resize function.
Example:
// Fix select2 width
$(window).on('resize', function() {
$('.form-group').each(function() {
var formGroup = $(this),
formgroupWidth = formGroup.outerWidth();
formGroup.find('.select2-container').css('width', formgroupWidth);
});
});
I know this is an old post However, I had an issue when I used NMC's code.
As I can't comment on his answer, after using his code I had some annoying scrollbars appearing after using the select2 dropdowns, to fix this I used width auto instead.
.select2-container {
width: auto !important;
}
Just had to do something like this for a site
$(e).on("select2:closing", function(e) {
if (e.hasOwnProperty('params') &&
e.params.hasOwnProperty('args') &&
e.params.args.hasOwnProperty('originalEvent') &&
e.params.args.originalEvent.hasOwnProperty('target')) {
var newWidth = $(e.params.args.originalEvent.target).width();
var id = $(e.params.args.originalEvent.target).attr('id');
var container = $("span[aria-labelledby=\""+id.split("-result")[0]+"-container"+"\"]");
$(container).parents('span.select2').width(newWidth + 21);
}
});
This is probably not fool-proof and is tied to the current API. But it gets the width of the element in the dropdown before the dropdown closes and then applies that to the container.
One thing of note, you may need to float the dropdown items to get their real size.
.select2-results__option {
float: left;
clear: both;
}
$('.select2-search__field').attr('style','width:auto');
$('.select2-search__field[placeholder=""]').attr('style','width:10px');
For dynamically resize a select2 you can use width: 'style' option as below:
$('#field_'+field.name).select2({
placeholder: "select a option...",
maximumSelectionLength: 1000 ,
allowClear: true,
...
width: 'style',
data: data
});
And next you have to use style="width:100%;" as attribute for your select tag.
<select class="input-element-item fontsize13" id="select2" style="width:100%;" >
<option></option>
</select>
For other than problems of responsive width, read the documentation of Select2. Everything is explained.
https://select2.org/appearance#container-width
<select class="js-example-responsive" style="width: 50%"></select>
$(".js-example-responsive").select2({
width: 'resolve' // need to override the changed default
});

Styling Panels of a Firefox Addon

So I created a Widget that the user clicks on and it opens up a Panel, I have a couple of Questions about the panel.
How Do I style the Panels borders, background color, etc..? I'm including an HTML file in it's contentURL, can I add CSS to alter it? If so how do I select it via CSS?
I also want to add a Close Button and keep the panel open always unless they click the close button.
On second thought, for the Add-on i'm trying to program it might be better if I make a window, is a window pretty stylable so I can make it look cooler?
Thanks for any help.
I don't think you can style panel borders. The panel border styles depend on the operating system and you cannot touch them. You can only really influence the inner area of the panel, effectively you get an iframe inside the panel that you can play with. E.g. to change the background your panel can contain:
<style type="text/css">
html
{
background-color: red;
}
</style>
You cannot, the panel is not a real HTML object, but a XUL window with an iframe or HTML inside.
I believe since Firefox 30 you can access to this object, you can read:
Avoid panel to autoHide in Firefox extension
Of course it's a kind of hack, looks like Mozilla is not really "open" ^^
I was able to modify the border of the panel:
/*run this first*/
var win = Services.wm.getMostRecentWindow('navigator:browser');
var panel = win.document.createElement('panel');
var screen = Services.appShell.hiddenDOMWindow.screen;
var props = {
noautohide: true,
noautofocus: false,
level: 'top',
style: 'padding:15px; margin:0; width:150px; height:200px; background-color:steelblue;border-radius:15px'
}
for (var p in props) {
panel.setAttribute(p, props[p]);
}
win.document.querySelector('#mainPopupSet').appendChild(panel);
panel.addEventListener('dblclick', function () {
panel.parentNode.removeChild(panel)
}, false);
panel.openPopup(null, 'overlap', screen.availLeft, screen.availTop);
So if you know the panel of your id just do this:
var sss = Cc['#mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
var css = '';
css += '#YourPanelIdHere { border-radius:15px; opacity:.5; border:1px solid red; }';
var cssEnc = encodeURIComponent(css);
var newURIParam = {
aURL: 'data:text/css,' + cssEnc,
aOriginCharset: null,
aBaseURI: null
}
var cssUri = Services.io.newURI(newURIParam.aURL, newURIParam.aOriginCharset, newURIParam.aBaseURI);
sss.loadAndRegisterSheet(cssUri, sss.USER_SHEET);
//sss.unregisterSheet(cssUri, sss.USER_SHEET);
That will style your panel. You don't have to use panel id in the style sheet, just anything that target your panel will do.

getting jQuery UI's datepicker to always open in a certain direction?

I'm using jQuery UI's datepicker control in a position: fixed toolbar at the bottom of my page. Occasionally, on random computers, the datepicker appears below the toolbar, which means it's off the page and impossible to view or interact with.
Is there a way to force the positioning of the datepicker control to always be above and to the right of its <input>?
The only way to be certain (for the jQueryUI version of datepicker) is to disable the functionality of the datepicker that tries to render inside the viewport. Here's a way to do it without modifying the source code files:
$.extend(window.DP_jQuery.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});
on later versions of JQuery UI try:
$.extend($.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});
That just nukes the _checkOffset function inside datepicker that makes it squirrelly. Then you can use the .ui-datepicker css to make sure it stays fixed if that's what you're after. More info at how-to-control-positioning-of-jqueryui-datepicker.
Problem is that element in position: fixed show top position 0px (check with: alert$('#datepicker2').position()).
Solution:
$('#datepicker').datepicker( {beforeShow: function(input) {
var x = 100; //add offset
var y = 20;
field = $(input);
left = field.position().left + x;
bottom = y;
setTimeout(function(){
$('#ui-datepicker-div').css({'top':'', 'bottom':bottom + 'px', 'left': left + 'px'});
},1);
}}
Test HTML:
<form style="position:fixed; bottom:0; width:100%" name="form1" method="post" action="">
<label>
<input style="left:300px; position:absolute; bottom:0" type="text" name="textfield" id="datepicker">
</label>
</form>
You could change the lines:
offset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0;
offset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight*2 - viewHeight) : 0;
...to read:
offset.left = $(inst.input).position().left + dpWidth;
offset.top = $(inst.input).position().top - dpHeight;
This loses flexibility, though. If your input happens to be at the top of the page, you'll have the opposite problem from before.
http://www.mindfiresolutions.com/Make-jQuery-datepicker-to-popup-in-different-positions-995.php
check this. I used this and was able to position the datepicker control in all browsers.
I had a similar problem. I have a page with date pickers potentially used at various placed on the page but also on a fixed header where the user can scroll the page both horizonally and vertically with the fixed header staying in place. The header also has a datepicker. So I can't do a global change of datepicker.
This is what I did. It is admittedly a kluge but it works so I thought it might help someone else. Hopefully in the future the jquery datepicker will add a position option.
beforeShow: function(input, inst) {
$("#ui-datepicker-div").css({ "visibility": "hidden", "display": "none" );
window.setTimeout(function() {
var leftPosition = parseInt($(window).width() / 2);
$("#ui-datepicker-div").css({ "position": "fixed", "top": 0, "left": leftPosition });
$("#ui-datepicker-div").css({ "visibility": "visible", "display": "inherit" );
}, 500);
}
From the documentation, it looks like you might be able to use the 'dialog' method of the datepicker plugin to achieve your desired outcome. However, using this most likely means that you will have to implement some of the glue that you would otherwise get out-of-the-box with datepicker, such as a callback handler to extract the date, etc.
I tried to mock up some code to see it in action and short of getting the datepicker to display, I couldn't quite get it working, though. Anyway, I wanted to point you to it in case you have better luck than I did.

Resources