Multiple TinyMCE editors, but only one toolbar? - javascript

I've looked around the forum, but cannot seem to find a definite answer to this problem...
I'm using jQuery and TinyMCE on our website. I've gone through the docs of TinyMCE, but am still getting lost I'm afraid. We're doing an interface that requires edit-in-place in multiple places in the page. The only thing is, each of these will have all the editing choices from TinyMCE in one toolbar at the top. So, to recap it, it's multiple editors (that each have no toolbars of their own, just a place to edit or select the text) and only one toolbar at the top of the page to control whichever textbox is active at the time.
How could this be achieved? Is it even possible? Any help, any push in the right direction, any hints/tips/knowledge at all on this problem would be a great, great help.
Thanks, James

I did with the 3.x version like this (it's Prototype syntax):
First, I created a toolbar wrapper (in my case I attached it with position:fixed at top of the document:
<div id="externalToolbarWrapper"></div>
Then I set the setup function in the tinyMCE-settings (for each editor) like this:
[...]
theme_advanced_toolbar_location : "external",
setup : function(ed) {
ed.onInit.add(function(ed, e) {
ed.onPostRender.add(function(ed, cm) {
var toolbar = $(ed.id + '_external');
// inserts the external toolbar in the external wrapper
$('externalToolbarWrapper').insert(toolbar.hide());
});
ed.onRemove.add(function(ed) {
if($(ed.id + '_external')) {
// removes external toolbar
$(ed.id + '_external').remove();
}
});
});
}
This worked in my case - the editors show/hide the toolbars on activation/deactivation.

I know there is a way to show the toolbar when a textarea is focused into, and then hide on textarea blur event - so that could be one route.
I do a similar sort of thing (with multiple textareas) where i load in demand the tinyMCE, so something like loading on demand and then destroy when finished with (blur event) might be what you're after.
I can't give you all of my code as it's actually part of my employer's I.P, but here is a rough outline to it, hopefully should help. The tinyMCE_GZ is part of the gzip which is off the tinyMCE site.
isTinyMCE_Loaded = false;
jQuery('.my-textarea').one("click", function(){
BuildWYSIWYG.Full(jQuery(this));
})
BuildWYSIWYG.OnDemand: function(callback){
tinyMCE_GZ.init({
plugins : 'style,table,advhr,advimage,advlink,insertdatetime,preview,searchreplace,contextmenu,paste,fullscreen,visualchars,nonbreaking,xhtmlxtras,safari,tinybrowser',
themes : 'simple,advanced',
languages : 'en',
disk_cache : true,
debug : false
}, function(){
isTinyMCE_Loaded = true;
callback();
});
};
BuildWYSIWYG.Full: function(el){
settings.elements = jQuery(el).attr("id");
// Build advanced wysiwyg
if (isTinyMCE_Loaded){
tinyMCE.init(settings);
} else {
BuildWYSIWYG.OnDemand(function(){
tinyMCE.init(settings);
});
}
}

There might be another way. Take a look at this example. http://tinymce.moxiecode.com/examples/example_23.php
You can use the links at the bottom (Show,Hide,Bold,Get Contents etc) as a menu (may require some styling). Then, get the id of the textarea currently in focus and pass it to the menu (#current) and use it to change that textarea.
To achieve what you are describing:
First disable all the indivudual TinyMCE menu items.
Once they are disabled, create your own TinyMCE menu in HTML and style it accordingly.
Determine which TinyMCE textarea in focus
Apply the actions from your new menu to the Textarea that is focused
Now for some code (may require some debugging...)
First, Initialize TinyMCE and disable menus.
tinyMCE configs
({
mode : "textareas",
theme : "advanced",
editor_selector : "editable"
theme_advanced_buttons1 : "",
theme_advanced_buttons2 : "",
theme_advanced_buttons3 : "",
theme_advanced_toolbar_location : "botton",
theme_advanced_statusbar_location : "bottom" });
I think you can also edit the _addToolbars function in tiny_mce/themes/advanced/editor_template_src.js and then pack it.
Then determine the text area that is currently in focus using jQuery bind:
$().ready(function() {
var current;
$('.editable').focus(
current = this.id;
);
$('.editable').blur(
//maybe hide the menu (?)
);
}
Then create the HTML with our textareas and the menu
<form method="post" action="somepage">
<div id="independent_menu">
<!-- The Menu, Please Style Accordingly -->
[Show]
[Hide]
[Bold]
[Get contents]
[Get selected HTML]
[Get selected text]
[Get selected element]
[Insert HTML]
[Replace selection]
</div>
<!-- The Text Areas -->
<textarea class="editable" id="one">Some Text Here</textarea>
<textarea class="editable" id="two">Yet another text area</textarea>
<textarea class="editable" id="three">Final Text Area</textarea>

I did this with an older version of tinymce:
http://tinymce.moxiecode.com/punbb/viewtopic.php?id=10197
http://examples.dtbaker.com.au/code/tinymce/
Haven't re-produced this with the latest version though :(
But basically there's two ways to do it, either:
1) Create your own menu that calls tinymce arguments on the active tinymce editor.
2) Set the tinymce toolbar/menu to be external, so that it appears when you focus an editor. Then using CSS you position each toolbar to appear in the same place. So it looks like there is a single toolbar but in fact it is multiple toolbars appearing in the same place.
Hope that helps.

I am providing solution for this question in case anyone still comes here for one. You can use execCommand to execute various styles of text you like while clicking on your custom buttons. For example:
// bold, italic and underline
$('#bold').click(function(){
tinymce.execCommand('Bold');
});
$('#italic').click(function(){
tinyMCE.execCommand('Italic');
});
$('#underline').click(function(){
tinyMCE.execCommand('Underline');
});
//commands for left align, right align and center align
$('#l-a').click(function(){
tinyMCE.execCommand('JustifyLeft');
});
$('#c-a').click(function(){
tinyMCE.execCommand('JustifyCenter');
});
$('#r-a').click(function(){
tinyMCE.execCommand('JustifyRight');
});
//commands for inserting ul or ol
$('#ul').click(function(){
tinyMCE.execCommand('InsertUnorderedList');
});
$('#ol').click(function(){
tinyMCE.execCommand('InsertOrderedList');
});
where #bold, #italic, #ul etc. are ids of the html elements which you are using to do implement styling. For example:
<button id="bold">B</button>
This button will bold the text, no matter the text is in which instance of tinymce.
Though the only drawback with this functionality is that you will have to do a lot of work for showing the effect on particular button when its on or off. If you are not concerned with that then this will do the trick.
I hope it helps...

Related

Manual drop down menu iron-icon change on-click for paper menu in Polymer

I'm trying to use a paper-menu with paper-submenu such that when I open the submenu, the header(paper-menu)'s icon (up arrow) changes to a down arrow.
Of course I would like this to return back when the submenu is no longer visible.
I'm currently working with this, but it's been cobbled together from what I have seen online.
HTML/Polymer
<paper-submenu>
<paper-drawer-icon-item icon="settings" class="menu-trigger">Settings<iron-icon
class="menu-dropdown" icon="{{_icon(expanded)}}"></iron-icon></paper-drawer-icon-item>
<paper-drawer-item class="menu-content" style="text-align:right;">Settings info
</paper-drawer-item>
</paper-submenu>
JS
_icon: function (expanded) {
return expanded ? 'hardware:keyboard-arrow-up' : 'hardware:keyboard-arrow-down';
},
Any help is appreciated.
You can use paper-submenu's property opened which indicates if is menu opened or not. Exactly what you need. So something like:
<paper-submenu opened="{{opened}}">
<paper-drawer-icon-item icon="settings" class="menu-trigger">Settings<iron-icon
class="menu-dropdown" icon="{{_icon(opened)}}"></iron-icon></paper-drawer-icon-item>
<paper-drawer-item class="menu-content" style="text-align:right;">Settings info
</paper-drawer-item>
</paper-submenu>
and don't forget to define opened property in your custom element (you call this property whatever you want. Just replce binding with another property opened="{{ some property }}".
opened: {
type: Boolean,
value: false
}
That js function you wrote is good approach

Squarespace - How to display description/custom text on index thumbnail on hover

Basically, I want to be able to show title and some text on hover on all my index thumbnail like this website.
http://www.timboelaars.nl/
However, in the current squarespace template that I am using (I believe it's called York), the markup is only grabbing the page title and therefore displaying the page title on hover. (See the below code block, you can see the page title in there, that's the only thing that the template displays on Hover)
<div class="index-item-text-wrapper">
<h2 class="index-item-title">
<a class="index-item-title-link" href="/google-shopping/" data-ajax-loader="ajax-loader-binded"><span class="index-item-title-text">**PAGE TITLE**</span></a>
</h2>
</div>
There's no field for me to put any HTML so I am seeking help to use javascript to manually inject custom HTML markup to every single thumbnail, then show them on hover.
TL;DR I want to be able to display more than just the title on hover (ideally my own HTML markup so I can customize the style) on my thumbnails but that's not supported by the template.
Here is my website http://shensamuel.com/
I am really weak at Javascript and I've searched for a solution for this problem for quite long. Any help will be much appreciated!
Thanks!
The following Javascript can be used to insert text for each tile on the page. The code would be inserted using the footer code injection area (unless you're using Developer Mode in which case you'd insert it with the rest of your scripts).
<script>
(function() {
var tiles = document.getElementsByClassName('index-section');
var thisTile;
var titleText;
var description;
var parent;
var i, I;
for (i=0, I=tiles.length; i<I; i++) {
thisTile = tiles[i];
titleText = thisTile.getElementsByClassName('index-item-title-text')[0];
parent = thisTile.getElementsByClassName('index-item-text-wrapper')[0];
description = document.createElement('span');
description.className = 'index-item-description-text';
switch(titleText.innerHTML.toLowerCase()) {
case "google shopping":
description.innerHTML = "Some custom text.";
break;
case "hana":
description.innerHTML = "More text that's custom.";
break;
case "wali":
description.innerHTML = "Custom text here.";
break;
case "cypress":
description.innerHTML = "Type anything you want.";
break;
case "ryde":
description.innerHTML = "Just another bit of text.";
break;
default:
description.innerHTML = "";
}
parent.appendChild(description);
}
})();
</script>
Observe the pattern in the code in order to add new tiles or edit existing ones. You will see that the script attempts to match (a lower case version of) the 'title' text and then inserts text based on each title. This allows you to add more in the future by repeating this 'case' pattern. Of course if you ever change the title of a tile you'd have to correspondingly change this Javascript code.
You can then style the description by inserting CSS via the Squarespace CSS Editor (or via your base.less file if using Developer Mode). For example:
.index-item-description-text {
display: block;
font-size: 1.2em;
color: #FFFFFF
}
Note that while there is an alternative method that would use each tile's respective URL to do an AJAX query and obtain meta data about each project (and therefore allow you to use the Squarespace content manager to insert this 'description'), that method seems unnecessarily complex for your case.
Update 8/17/2016: Regarding AJAX and how to disable AJAX loader in Squarespace: Jason Barone has suggested adding this snippet to your Code Injection > Footer to disable the "AJAX" pageloader. He noted that it will disable the smooth, AJAX transitions between pages, but will allow custom Javascript like usual.
<script>
//Credit: Jason Barone, http://jasonbarone.com/
window.Template.Constants.AJAXLOADER = false;
</script>
Also, some templates have an option to disable AJAX within the style editor (image credit: SSSUPERS):
Update 9/28/2016:
It has been reported that the code provided above no longer disable AJAX. However, some newer templates have added an 'Enable AJAX Loading' setting that can be toggled off.

Shrinking a Table in JavaScript

Never used JavaScript Before and I'm trying to fix this form in share point.
I want this text box to be small (like 1 row), until the user clicks it and then it should expand into a larger text box with like 10 rows. I apologize if this has been answered before, I don't even know what I should be looking for. Here is code I have that doesn't work, but does pop up an error message(I did not write this code):
alert(DescriptionID);
document.getElementById(DescriptionID).addEventListener("onmouseover", function(){
document.getElementById(DescriptionID).rows= "10";
});
document.getElementById(DescriptionID).addEventListener("onmouseout", function(){
document.getElementById(DescriptionID).rows= "1";
});
EDIT:
Here is what the current code will display:
EDIT2:
Thanks to a ton of help from you guys/gals I am close to finished! I can now understand it significantly better at least! Here is a picture of the code. The object is actually an "ms-formbody" ???
AND ANOTHER EDIT:
So here is the error i'm getting after using Johhny's code:
If you are using jQuery, this might work for you:
HTML:
<textarea id="expandingTextarea" rows="1">Enter Text</textarea>
JavaScript:
$(document).ready(function() {
$('#expandingTextarea').on('mouseover', function() {
$(this).attr('rows', '10');
});
$('#expandingTextarea').on('mouseout', function() {
$(this).attr('rows', '1');
});
});
I created an example here.
Update:
Using a click event to change/toggle to row count:
$(document).ready(function() {
$('#expandingTextarea').on('click', toggleExpand);
function toggleExpand() {
var oldRowCount = $(this).attr('rows');
var newRowCount = parseInt(oldRowCount) === 1 ? 10 : 1;
$(this).attr('rows', newRowCount);
}
});
Demo here.
In fact, you don't need JS to achieve what you want. CSS can do it for you.
<!--html-->
<textarea class="descr">This is description</textarea>
/*css*/
.descr {height: 20px;}
.descr:hover, .descr:focus {height: 120px;}
alter the height instead of the "rows" property.
open up the page in chrome, open the developer tools (View->Developer->Developer Tools) and then use "inspect" to select the text area you want to manipulate.
try playing around with the css of that element. then, write your javascript to change just the property that you want.
https://developer.chrome.com/devtools
The code you showed looks fine but DescriptionID should contain the ID of the description box. You can check what it is by right clicking on the description form and clicking "inspect element". Then assign var DescriptionID = "someID" at the beginning of the code.
Also, you might consider altering the height, not the rows.
If the form doesn't have an ID, look for an option to change the HTML and add one. If you don't have such an option, it's still possible to achieve what you want to do but you have to look beyond getElementById.

Is it possible to put a link within an anchor's title attribute? [duplicate]

Is there a way to put actual html code inside a title attribute on a table row element? My goal is to pop-up not only text but some info-graphics along with it, so a mouseover event thats not a modal would be great. Am I going in the wrong direction?
This table is already using jquery datatables but I don't believe it can do that sort of event.
<tr title='This activity will be open to registration on April 31st' >
.....
</tr>
Nope. You'd need to create your own title substitute with JavaScript.
No.
HTML can't be placed in an attribute.
If the goal is to have a pop-up with rich content, then you need to handle this via javascript. In addition, from an accessibility standpoint, you likely don't want to put that amount of content into the title attribute anyways, so going the JS route is going to solve a few problems for you. Google 'JS Tooltip' for dozens of options.
Native tooltips do not use HTML. jQuery UI tooltips would be very useful here.
Demo: http://jqueryui.com/tooltip/
EDIT: You would need to use the content option to use markup instead of the title attribute.
$(".text")
.tooltip({ content: '<b style="color: red">Tooltip</b> <i>text</i>' });
Here's a Fiddle demonstrating this: http://jsfiddle.net/acbabis/64Q2m/
You can use jquery ui tooltip plugin for showing custom title
There is no direct way to render HTML code written inside a tooltip. However, if you are using jQueryUI (or, if you can) then the code below will show the HTML effect (render) and not the HTML code in the tooltip.
Requirements: jQuery, jQueryUI.js, jQueryUI.css
HTML Code:
<tr data-title='This activity will be open to registration on <b>April 31st</b>'>.....</tr>
JavaScript:
$(function() {
$( document ).tooltip({
items: '[title], [data-title]',
track:true,
content: function(){
var element = $( this );
if ( element.is( "[title]" ) ) {
return element.attr( "title" );
}
if ( element.is( "[data-title]" ) ) {
return element.attr( "data-title" );
}
}
});
});
Instead of focusing on the title attribute, enclose a popup message with tags inside the target <td></td> (table data element). Then put a class in that td to control the div with CSS, hiding it first, then making its contents visible when the mouse hovers over the specific table data element. Something like this:
<tr><td class="info-tooltip">This activity will be open to registration on April 31st <div>[ *the contents you would want to popup here* ]</div></td></tr>
Your CSS then might be something like:
td.info-tooltip div {
display:none;
}
td.info-tooltip:hover {
position:relative;
cursor:pointer;
}
td.info-tooltip:hover div {
position:absolute; /* this will let you align the popup with flexibility */
top: 0px; /* change this depending on how far from the top you want it to align */
left: 0px; /* change this depending on how far from the left you want it align */
display:block;
width: 500px; /* give this your own width */
}
Using Bootstrap Tooltips one can do the following
<span title="Some <b>bold words</b>" data-toggle='tooltip' data-html='true'>this has an html supported tooltip</span>
for me it happens automatically but you might need to trigger it with javascript.
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
docs
I think a good option is to put that content inside a data attribute, something like this:
<div data-tooltip="Some information I want to show">
Actual content
</div>
And then, write a simple jQuery plugin that shows that content inside an element upon hover over.

jQuery TextExt: max height and scrollbar

I'm using the jQuery TextExt plugin (http://textextjs.com/) to create an input field where the user can enter languages as tags, similar to the Facebook way of entering Tags.
Overall, the plugin works great.
However, I have hit a snag, which I can't seem to overcome. I am using TextExt on an Input field, like this:
<script type="text/javascript">
$('#id_languages').textext({
plugins : 'tags prompt suggestions arrow autocomplete',
tagsItems : ['English'],
suggestions : languages, //variable set earlier
prompt : 'Add more here...',
});
</script>
Which works as it should. Now, the more tags I add, the more the input field grows (as expected).
However, at some point, it grows beyond the height that is acceptable in my given layout.
Is there a working way of specifying the max height of the input element using TextExt, plus adding a vertical scrollbar, without having the Suggestions dropdown pop up inside the div with the scrollbar?
I hope that makes sense, I'm a bit confused myself at the moment.
I've checked the source code, and there's no place it can be changed in order to accomplish what you need without a hack.
The closest answer to that is to limit the number of tags per input, which can be
done like described here: How to limit total number of inputs to textExt plugin?
$('#id_languages').textext({
plugins : 'tags autocomplete',
tagsItems : Sourcearray,
ext: {
tags: {
addTags: function(tags) {
if(checkLength()) {
$.fn.textext.TextExtTags.prototype.addTags.apply(this, arguments);
}
}
}
}
});
and here's the validation function checkLength():
function checkLength(){
if($("#id_languages").next().children().length < 4){
return true;
}
return false;
}
Where the number 4 is the number of tags allowed.
If this wouldn't be satisfactory, you will have to hack into textext.core.js and textext.plugin.tags.js and look for the following functions:
invalidateBounds(), preInvalidate() and postInvalidate() and play with the height manipulation.

Categories

Resources