Highlight text with TinyMCE - javascript

Currently I have a textarea using TinyMCE: http://fiddle.tinymce.com/D2gaab
I want to highlight the text between the opening/closing braces. Does someone know if this is possible, and how I can do this?

You could consider inserting a <mark> tag, or another element with inline styling. Also, maybe only insert when the selection has any length.
editor.addButton('spintax', {
text: 'Spintax',
icon: false,
onclick: function () {
editor.focus();
if (editor.selection.getContent().length) {
editor.selection.setContent("{<mark>" + editor.selection.getContent() + '</mark>}');
}
}
});
http://fiddle.tinymce.com/E2gaab

Related

Open Ace.js code editor and select content on click

I have a page containing multiple instances of ace.js editors, all on read-only, displaying code.
I wish to open the editor like so and highlight its content to allow my user to easily copy it, like so:
My current approach does not show the wanted result, it does open an editor with the code inside of it BUT its height is not at the size of its content:
Heres's how I do it:
function openCodeEditor(event, domElement, language) {
event.preventDefault();
getInstance().then((ace) => {
ace.edit(domElement, {
mode: `ace/mode/${language}`,
theme: 'ace/theme/monokai',
startLineNumber: 1,
trim: true,
});
});
}
// STARTS HERE
// Called on page load to highlight each block of code
function syntaxHighlight(domElement, language, showGutter) {
return getInstance().then((ace) => {
ace.require('ace/ext/static_highlight')(domElement, {
mode: `ace/mode/${language}`,
theme: 'ace/theme/monokai',
startLineNumber: 1,
showGutter,
trim: true,
});
// Catch clicks here, and open the editor for selection
domElement.addEventListener('click', (event) =>
openCodeEditor(event, domElement, language)
);
});
}
Does anyone of you have recommendations or perhaps my approach is faulty?
Thank you !
You can set the height of editor to be same as the height of replaced element.
var editor = ace.edit(null, {
value: domElement.textContent,
theme: 'ace/theme/monokai',
mode: `ace/mode/${language}`,
});
editor.container.style.height = domElement.clientHeight + "px"
domElement.replaceWith(editor.container)
but if the goal is simply to allow copying, selecting contents of domElement should work too.

text parsing then highlighting in textarea in javascript

Is there a neat way of highlighting texts in textarea on the fly while typing?
I would basically type in:
This is a [[note]] to do on friday.
on a textarea, then, using a highlighting library, I would call it in like this:
function FindAllNotes() {
var note = /^(?:\[{2}(?!\[+))(.+)(?:\]{2}(?!\[+))$/g
, input = ($(#textarea).val()).match(note);
$(#textarea).highlightWithinTextarea({
highlight: [input],
className: 'yellow'
});
}
$(#textarea).on('keyup', function () {
FindAllNotes();
});
But the problem is, everytime I type, it works and highlights notes enclosed in [[ ]], then I lose the cursor/focus on the textarea.
The plugin you linked to, can handle regular expression just as you want (although you should remove the ^ and $ from it, to not try to match the whole string).
$(function(){
$('.example').highlightWithinTextarea({
highlight: /(?:\[{2}(?!\[+))(.+)(?:\]{2}(?!\[+))/g,
className: 'highlight'
});
});
.example{
width:500px;
height:250px;
}
.highlight{
background-color:tomato;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://lonekorean.github.io/highlight-within-textarea/jquery.highlight-within-textarea.js"></script>
<link rel="stylesheet" href="http://lonekorean.github.io/highlight-within-textarea/jquery.highlight-within-textarea.css">
<textarea class="example">This is a [[note]] to do on friday.</textarea>
keep in mind that you need to include the css file from the plugin which wraps/aligns the textarea with the div text
You can use $("#textarea").focus(); to manually set the focus of a textbox. Maybe try calling this after your highlight function like the following:
$(#textarea).on('keyup', function () {
FindAllNotes();
$("#textarea").focus();
});

tinyMCE 4: add Class to selected Element

I created a tinymce menu item and what I want it to do is add a class to the selected text element. I cannot seem to figure out how to do this. Any suggestions?
Adding my menu item looks like this:
tinymce.PluginManager.add('button', function(editor, url) {
editor.addMenuItem('button', {
icon: '',
text: 'Button',
onclick: function() {
tinyMCE.activeEditor.dom.addClass(tinyMCE.activeEditor.selection, 'test'); //not working
},
context: 'insert',
prependToContext: true
});
});
I'd be very thankful for any helpful hint.
I found a solution that may not be perfect (for example, if you select part of a text then this doesn't work as I hoped), but for now it does what I want:
tinyMCE.activeEditor.dom.addClass(tinyMCE.activeEditor.selection.getNode(), 'test');
if I do this on a link, for example, the scripts add the classname "test" to my tag.
In order to be able to add a class to the editor you need a dom element in the editor to add the class to. Textnodes may not hold a class.
So i propose you insert a span element with the class you want to add wrapped around the actual selection. Be aware that this won't work if the selection leaps over paragraph boundaries (in this case you will need a bit more complicated code). Try this:
onclick: function() {
var ed = tinyMCE.activeEditor;
var content = ed.selection.getContent({'format':'html'});
var new_selection_content = '<span class="test">' + content + '</span>';
ed.execCommand('insertHTML', false, new_selection_content);
},
this works for me:
setup: function(editor) {
editor.ui.registry.addButton("addClassBtn", {
icon: "insertdatetime",
text: "Highlight ",
onAction: function (_) {
var newContent = "<span class='test'>" + editor.selection.getContent() + "</span>";
editor.selection.setContent(newContent);
}
}
}

TinyMCE Enable button while in read only mode

I have a TinyMCE 4.x instance where the text should be in read only mode. But I still have some buttons that I want to have enabled. For example, one button could provide a character count for the part of the text I've selected.
But when I turn on read only mode for TinyMCE all buttons are disabled. Can I enable just my buttons while still retaining read only mode?
It's probably too late for you but other people may pass by here.
I came up by writing this function
function enableTinyMceEditorPlugin(editorId, pluginName, commandName) {
var htmlEditorDiv = document.getElementById(editorId).previousSibling;
var editor = tinymce.get(editorId);
var buttonDiv = htmlEditorDiv.querySelectorAll('.mce-i-' + pluginName.toLowerCase())[0].parentElement.parentElement;
buttonDiv.className = buttonDiv.className.replace(' mce-disabled', '');
buttonDiv.removeAttribute('aria-disabled');
buttonDiv.firstChild.onclick = function () {
editor.execCommand(commandName);
};
}
It does the trick in 2 steps:
make the button clickable (remove mce-disabled CSS class and remove the aria-disabled property)
assign the good command to the click event
And in my editor init event I call the function.
editor.on('init', function () {
if (readOnly) {
editor.setMode('readonly');
enableTinyMceEditorPlugin(htmlEditorId, 'preview', 'mcePreview');
enableTinyMceEditorPlugin(htmlEditorId, 'code', 'mceCodeEditor');
}
});
Current version of TinyMCE for which I wrote this code is 4.4.3. It may break in a future version, specifically about the selectors to get and modify the good HTML elements.
Command identifiers can be found at this page otherwise you can also find them under tinymce\plugins\PluginName\plugin(.min).js
Here is a simple way to enable your custom toolbar button and attach a click event handler inside a read only TinyMCE editor using JQUERY:
//Initialize read only Tinymce editor so that Lock button is also disabled
function initReadOnlyTinyMCE() {
tinymce.init({
selector: '#main'
, toolbar: 'myLockButton'
, body_class: 'main-div'
, content_css: 'stylesheets/index.css'
, readonly: true
, setup: function (readOnlyMain) {
readOnlyMain.addButton('myLockButton', { //Lock button is disabled because readonly is set to true
image: 'images/lock.png'
, tooltip: 'Lock Editor'
});
}
});
}
function displayReadOnlyTinyMCEwithLockButtonEnabled() {
var edContent = $('main').html();
$("#main").empty();
initReadOnlyTinyMCE(true);
tinyMCE.activeEditor.setContent(edContent);
//enable the lock button and attach a click event handler
$('[aria-label="Lock Editor"]').removeClass("mce-disabled");
$('[aria-label="Lock Editor"]').removeAttr("aria-disabled");
$('[aria-label="Lock Editor"]').attr("onclick", "LockEditor()");
}
function LockEditor() {
alert("Tiny mce editor is locked by the current user!!");
//Write your logic to lock the editor...
}
I couldn't find an easy way to do this. The simplest way is to remove the contenteditable attribute from the iframe body instead and substitute a read only toolbar set. It also means that people will still be able to copy content from the editor.
$("iframe").contents().find("body").removeAttr("contenteditable");
How about this :
editor.addButton('yourButton', {
title: 'One can Enable/disable TinyMCE',
text: "Disable",
onclick: function (ee) {
editor.setMode('readonly');
if($(ee.target).text() == "Disable"){
var theEle = $(ee.target).toggle();
var edit = editor;
var newBut = "<input type='button' style='opacity:1;color:white; background-color:orange;' value='Enable'/>";
$(newBut).prependTo($(theEle).closest("div")).click(function(e){
edit.setMode('design');
$(e.target).remove();
$(theEle).toggle();
});
}
}
});
You can try to run the code below:
$("#tinymce").contentEditable="false";
if you have more than one editors, you can use their id like below
$("#tinymce[data-id='idOfTheEditor']").contentEditable="false";

Jquery text input acting funny

I have the following jQuery to modify a table cell when clicked -- it will enable a user to fill out a text input and on enter, return to the normal <td>.
HTML-
<td class="delivered">
{{ title.delivery_date|date:"Y-m-d" }}
</td>
JS -
$("td.delivered").click(function () {
if ($(this).find('#inp').length == 0) {
var before = $(this).text();
var title_id = $(this).parent().attr('id');
var status_type = 'delivery-date'
$(this).html($("<input/>", {
id: 'inp',
style: 'width:70px;',
placeholder: 'YYYY-MM-DD',
change: function () {
selectdone(this, title_id, status_type);
}
}));
$("#inp").focus();
$('#inp').val(before);
}
});
The above js works, but there is a quirk about it.
Even though the input element is 70px, it seems to scroll as if the text width were 200px or so. This makes it so that you are unable to see the placeholder after first clicking the td. How would I make it such that that the cursor is always flush left and the text input is 70px in every which way.
Update: This is what the input looks like after entering text and sending it via POST: u'status': [u'\t\t\t\t\t\t\t\t\t\t\t2012-01-01']. In other words, it seems to be starting with 11 tabs in the text input! Why does this occur and how would I get rid of this?
You could wrap your input box in a div with width:70px;overflow:hidden so you're sure that you won't see any scrollbars.

Categories

Resources