How do I add styles using CKEditor Custom drop down plugin - javascript

So I added this plugin which gives me the code to have a dropdown menu on my CKeditor toolbar, which holds all my styles which apply themselves on click. See code:
CKEDITOR.plugins.add( 'tokens',
{
requires : ['richcombo'], //, 'styles' ],
init : function( editor )
{
var config = editor.config,
lang = editor.lang.format;
// Gets the list of tags from the settings.
var tags = []; //new Array();
//this.add('value', 'drop_text', 'drop_label');
tags[0]=["[contact_name]", "Name", "Name"];
tags[1]=["[contact_email]", "email", "email"];
tags[2]=["[contact_user_name]", "User name", "User name"];
// Create style objects for all defined styles.
editor.ui.addRichCombo( 'tokens',
{
label : "Insert tokens",
title :"Insert tokens",
voiceLabel : "Insert tokens",
className : 'cke_format',
multiSelect : false,
panel :
{
css : [ config.contentsCss, CKEDITOR.getUrl( editor.skinPath + 'editor.css' ) ],
voiceLabel : lang.panelVoiceLabel
},
init : function()
{
this.startGroup( "Tokens" );
//this.add('value', 'drop_text', 'drop_label');
for (var this_tag in tags){
this.add(tags[this_tag][0], tags[this_tag][1], tags[this_tag][2]);
}
},
onClick : function( value )
{
editor.focus();
editor.fire( 'saveSnapshot' );
editor.insertHtml(value);
editor.fire( 'saveSnapshot' );
}
});
}
});
So what this code does is just insert whatever is in the tags ["[contact_name"] so when you click on "Name" in the dropdown, it just drops [contact_name] in the text editor. I want to know how I make each tag a specific function which adds css to whatever is selected in the text editor. For example have a function called 'Red Font' and whatever < p > font exists it turns red.

CKEDITOR.replace( 'editorId', {
extraPlugins: 'tokens'
});
add this code and replace the editor id with your editor id.
that's it.

CKEDITOR.replace( 'editor', {
extraPlugins: 'tokens' // why tokens see below
});
because you have given
CKEDITOR.plugins.add( 'tokens',
{
requires : ['richcombo']
..

Related

Generating TinyMCE drop-down menu dynamically

I am trying to create toolbar button in TinyMCE with options that are derived from the array. I've followed the examples on Tiny's website and the button is getting generated as expected. Here is the code:
var mergeFields = {one: "first", two: "second", three: "third"};
tinymce.init({
selector: 'textarea',
menubar: false,
toolbar: 'mergefields',
setup: function (editor) {
editor.ui.registry.addMenuButton('mergefields', {
text: 'Merge Fields',
fetch: function (callback) {
var items = [];
for (var fieldName in mergeFields) {
var menuItem = {
type: 'menuitem',
text: mergeFields[fieldName],
onAction: function() {
// The problem: this function always inserts the last element of the array
// instead of the expected fieldName associated with this menuItem
editor.insertContent(fieldName);
},
};
items.push(menuItem);
}
callback(items);
},
});
}
});
<script src="https://cloud.tinymce.com/5/tinymce.min.js?apiKey=XXXXX"></script>
<textarea>Editor</textarea>
The problem happens when one of the options is selected and the anonymous function assigned to onAction property is executed -- it always inserts "three" into the document (presumably because after running through the whole array, fieldName is set to "three"). How can I make the onAction handler insert the right value into the document?
This needs to work in TinyMCE 5.
I've found a similar question here: Adding custom dropdown menu to tinyMCE and insert dynamic contents, but it was referring to TinyMCE 4 and unfortunately the provided answer does not work for TinyMCE 5.
Thanks for your help!
I had the same problem.
I solved it using value+onSetup
https://jsfiddle.net/stvakis/tjh7k20v/8/
var mergeFields = {
one: "first",
two: "second",
three: "third"
};
tinymce.init({
selector: 'textarea',
menubar: false,
toolbar: 'mergefields',
setup: function(editor) {
editor.ui.registry.addMenuButton('mergefields', {
text: 'Merge Fields',
fetch: function(callback) {
var items = [];
for (var fieldName in mergeFields) {
var menuItem = {
type: 'menuitem',
text: mergeFields[fieldName],
value:fieldName,
onSetup: function(buttonApi) {
var $this = this;
this.onAction = function() {
editor.insertContent($this.data.value);
};
},
};
items.push(menuItem);
}
callback(items);
},
});
}
});

Toolbar config doesn't work with inline CKEditor

I try to apply a very simple toolbar config to an inline CKEditor. The goal is to only show a Bold button, but it doesn't work. Why?
CKEDITOR.inline(el.get(0),
{
toolbar:
[
{ name: 'basicstyles', items: [ 'Bold' ] }
]
});
https://jsfiddle.net/adrianrosca/q6x6s6ga/
I've forked and updated your fiddle: https://jsfiddle.net/Comandeer/q6x6s6ga/30/
$( function() {
var el = $( '#editor1' );
el.attr( 'contenteditable', true );
CKEDITOR.inline( el.get( 0 ),
{
toolbar: [ [ 'Bold' ] ]
} );
} );
There were two problems with your code:
You did not take into account fact that CKEditor automatically converts all [contenteditable=true] elements into its instances and you must disable it first. Therefore it's easier to add [contenteditable] right in your JS code and then create an inline editor.
Your syntax for the toolbar was wrong. The configuration option takes array or string as a parameter – not object.
Edit: version with CKEDITOR.disableAutoInline https://jsfiddle.net/Comandeer/q6x6s6ga/31/
The problem was in waiting for onload event. If you just put that code on the end of body, everything is working fine.
You can solve updating the CKEDITOR source, i.e.
http://cdn.ckeditor.com/4.5.7/standard/ckeditor.js
And editing your code as follows:
$(function()
{
var el = $("div");
CKEDITOR.disableAutoInline = true;
for (var inst in CKEDITOR.instances) {
CKEDITOR.instances[inst].destroy();
}
CKEDITOR.inline(el.get(0),
{
toolbar:
[
{ name: 'basicstyles', items: [ 'Bold' ] }
]
});
});

`format` callback in newest version of jQuery UI selectmenu

I want to make <select> replacement with custom text formatting using jQuery UI Selectmenu.
Third and fifth selects in this fiddle are good examples of what I am trying to achieve:
http://jsfiddle.net/fnagel/GXtpC/
In the fiddle, there is defined function addressFormatting(), which takes the original option text and returns html output which will be used for rendering the selectmenu. This function is passed as a callback in the selectmenu initialization:
$('select').selectmenu({
format: addressFormatting
});
I am using jQuery UI Selectmenu 1.11.4. The problem is that the format callback option is not present in this version.
This is a portion of code from jQuery UI Selectmenu version 1.5.0pre, used in the provided fiddle:
$.widget("ui.selectmenu", {
options: {
appendTo: "body",
typeAhead: 1000,
style: 'dropdown',
positionOptions: null,
width: null,
menuWidth: null,
handleWidth: 26,
maxHeight: null,
icons: null,
format: null, // <<<<<<<<<<<< FORMAT OPTION IS PRESENT <<<<<<<<<<<<
escapeHtml: false,
bgImage: function() {}
},
And this is the portion of code from newer version that I am using:
var selectmenu = $.widget( "ui.selectmenu", {
version: "1.11.4",
defaultElement: "<select>",
options: {
appendTo: null,
disabled: null,
icons: {
button: "ui-icon-triangle-1-s"
},
position: {
my: "left top",
at: "left bottom",
collision: "none"
},
width: null,
// callbacks
change: null,
close: null,
focus: null,
open: null,
select: null
},
format option is not present here, and using it in the initialization has no effect.
In the API documentation, there is _renderItem() method, whose name suggest it could be used to add custom formatting to the select, but it has private scope, so I can't use it from outside of the widget. There is also public create() method, but I am not sure if I can or if I should use it to change the structure of created selectmenu.
As mentioned format option has been removed from the selectmenu before it was a part of the jquery-ui library. There is a way to inject custom code into the selectmenu widget and overwrite functions that handle this functionality.
// Create objects that you want inside the menu list
var RenderItem = function(item) {
return $('<div/>')
.addClass('ui-menu-item-wrap')
.append(
$('<span/>')
.addClass('ui-menu-item-header')
.text(item.label + ' (' + item.km + " km)")
).append(
$('<span/>')
.addClass('ui-menu-item-description')
.text(item.desc)
);
};
// Extend functions in the selectmenu plugin
$.widget("ui.selectmenu", $.ui.selectmenu, {
// Input middleware to the _setText function, that will build
// jQuery objects to render
_renderItem: function( ul, item ){
var li = $( "<li>" ),
wrapper = $( "<div>", {
title: item.element.attr( "title" )
} );
if ( item.disabled ) {
this._addClass( li, null, "ui-state-disabled" );
}
// Insert middleware
this._setText( wrapper, RenderItem(item));
return li.append( wrapper ).appendTo( ul );
},
// Overwrite this function to add custom attribute values from the option
_parseOption: function( option, index ) {
var optgroup = option.parent( "optgroup" );
return {
element: option,
index: index,
value: option.val(),
label: option.text(),
desc: option.attr('data-desc'), // Custom <option> value saved to item
km: option.attr('data-km'), // Custom <option> value saved to item
optgroup: optgroup.attr( "label" ) || "",
disabled: optgroup.prop( "disabled" ) || option.prop( "disabled" )
};
},
// Overwrite this function to append a value, instead of inserting text
// So that the jQuery element is handled correctly.
_setText: function(element, value) {
if (value) {
element.append(value);
} else {
element.html(" ");
}
}
});

Need to retain dynamically created option in combo box using Knockout.js

I have a codeset that dynamically creates an "option" in a select box. But, since we're using Knockout, when I go to SELECT that newly created option, and click on it, it gets removed, e.g. DISAPPEARS! Poof!!!!
So, here's the create script:
function createNewGroup()
{
var htmlSelect = document.getElementById('groups');
var optionValue = document.getElementById('newgroupname');
if (optionValue.value === '')
{
alert('Please enter group name.');
optionValue.focus();
return false;
}
if (isOptionAlreadyExist(htmlSelect, optionValue.value))
{
optionValue.value = "";
alert('Group name already exists.\n\nPlease try again.');
optionValue.focus();
return false;
}
var selectBoxOption = document.createElement("option");
selectBoxOption.value = optionValue.value;
selectBoxOption.text = optionValue.value;
htmlSelect.add(selectBoxOption, null);
optionValue.value = "";
alert("New group has been added successfully.");
optionValue.focus();
return true;
};
Since this is a KNOCKOUT observable, how to keep it in the box when I select it, moreover, how do I send that new value back to JSON object. Here's an example of that:
{"groups":[
{
"groupname" : "Administrator",
"attr" : { "id" : "li.attr.node_1",
"href" : "#",
"data-bind" : "click: grpMgmt('Administrator');" }
},
{
"groupname" : "Guest",
"attr" : { "id" : "li.attr.node_2",
"href" : "#",
"data-bind" : "click: grpMgmt('Guest');" }
}
]
}
Hence, the admin user can create a new user so it can look like this:
{"groups":[
{
"groupname" : "Administrator",
"attr" : { "id" : "li.attr.node_1",
"href" : "#",
"data-bind" : "click: grpMgmt('Administrator');" }
},
{
"groupname" : "Guest",
"attr" : { "id" : "li.attr.node_2",
"href" : "#",
"data-bind" : "click: grpMgmt('Guest');" }
}
],
"users":[
{
"groupname" : "Joes Users",
"attr" : { "id" : "li.attr.node_1",
"href" : "#",
"data-bind" : "click: grpMgmt('Joe');" }
}
]
}
OK, I'll stop writing for now... thanks...
If you're using knockout (which I can't actually see) all you need to do is bind your select box to an observable array and when you need to add a new item just push it onto the array and knockout will add it to the list for you.
Knockout should essentially replace that script you've included with a lot less, much more simplistic code.

Ckeditor:call a function on mouseover to a link in editor

I have to create a plugin that can produce the following markup
<a id='location' onmouseover="win(this)" href="#">Cityname</a>
for this I have made this plugin
CKEDITOR.plugins.add( 'geoloc',
{
init: function( editor )
{
editor.addCommand( 'link',
{
exec : function( editor )
{
style = new CKEDITOR.style(
{
element : 'span',
attributes : { 'id' : 'location' , 'onmouseover' : 'win(this)' , 'href' : '#'},
});
style.apply(editor.document);
}
});
editor.ui.addButton( 'Geoloc',
{
label: 'Add to geomap',
command: 'link',
icon: this.path + 'newplugin.png'
} );
}
} );
Problem:
It adds span tag as style but not anchor tag which I need.
Question:
How can I call win() method onmouseover to that link in the editor.? Where to put that methods code?

Categories

Resources