How can I call a plugin function without a toolbar button?
I have an external floating toolbar integrated in my cms. I insert images, videos and other pieces of static code with the InsertHTML() API of CKEditor.
Now I need to insert also video from URL, and there is the fantastic oembed plugin. How can I fire that plugin using a button in my cms without the toolbar button?
I load the plugin in my config, and I try to create this function:
function oembed() {
// Get the editor instance that we want to interact with.
var editor = CKEDITOR.instances.editor1;
var url = 'http://www.youtube.com/watch?v=AQmbsmT12SE'
var wrapperHtml = jQuery('<div />').append(editor.config.oembed_WrapperClass != null ? '<div class="' + editor.config.oembed_WrapperClass + '" />' : '<div />');
// Check the active editing mode.
if ( editor.mode == 'wysiwyg' )
{
// Insert HTML code.
// http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml
editor.embedCode(url, editor, false, wrapperHtml, 650, 400, false);
}
else
alert( 'You must be in WYSIWYG mode!' );
}
The result is this:
Uncaught TypeError: Object [object Object] has no method 'embedCode'
Is there any way to create a new API like "InsertHTML" to call plugin functions without toolsbar buttons?
EDIT
Maybe I can use the createFakeElement API.
http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-createFakeElement
I add the class fakegallery to my doc.
I use this code but nothing happens:
function Fake()
{
var editor = CKEDITOR.instances.editor1;
var element = CKEDITOR.dom.element.createFromHtml( '<div class="bold"><b>Example</b></div>' );
alert( element.getOuterHtml() );
editor.createFakeElement( element, 'fakegallery', 'div', false );
}
I found this post looking for the answer...
Checked out the link provided in the answers here [ http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-fire ], scrolled down to execCommand
This worked for me and only requires that you know the name of your plugin, so it'll always work. Obviously, you may need to change "editable" to your editor instance.
CKEDITOR.instances['editable'].execCommand('YOUR_PLUGIN_NAME_HERE');
If above fails, HACK:
This would work (first line of code below), but requires you to look at the source to find the correct #. If you have 1 custom plugin, no big deal. But if you have a dozen or more, like me, this is annoying, and could change as more plugins are added.
CKEDITOR.tools.callFunction(145,this);
Hope this helps!
Read this:
http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-fire
editor.fire( 'MediaEmbed', data);
I think that this is the structure that your data needs to have:
var data = {title : 'Embed Media',
minWidth : 550,
minHeight : 200,
contents :
[
{
id : 'iframe',
expand : true,
elements :[{
id : 'embedArea',
type : 'textarea',
label : 'Paste Embed Code Here',
'autofocus':'autofocus',
setup: function(element){
},
commit: function(element){
}
}]
}
]}
I'm not secure but this will help you on the way.
Look at the Source code of the plugin to find the available commands.
The command name that i specified above is the only one that your plugin haves.
EDIT - Manual inserting
var div = editor.document.createElement('div');
div.setHtml("<embed src=" + url +" width=" + width +" height=" + height + ">");
editor.insertElement(div);
You can add every attribute you like, Type?? maby? Autofocus??
Related
I got rid of the O365 bar and the edit bar (#s4-ribbonrow) on my site for styling purposes. I want the user to still be able to use the functionality that the "quick edit" button provides when they select a list item. How can i implement the same functionality in a custom button on my page?
Open SharePoint quick edit mode for view
SharePoint uses this method :
EnsureScriptParams('inplview', 'InitGridFromView', 'VIEW ID');return false;
So, your sample anchor element:
<a onclick="EnsureScriptParams('inplview', 'InitGridFromView', SP.ListOperation.ViewOperation.getSelectedView());return false;">TEST</a>
Use SP.ListOperation.ViewOperation.getSelectedView() to get view ID in older sharepoints, or use _spPageContextInfo.viewId in SharePoint Online
Open SharePoint edit item dialog
Use SP.ListOperation.Selection.getSelectedItems() to get selected items from view.
click button handler should look something like this:
if (SP.ListOperation.Selection.getSelectedItems().length === 1) {
var itm = SP.ListOperation.Selection.getSelectedItems()[0];
var _url = _spPageContextInfo.siteServerRelativeUrl + '/' + _spPageContextInfo.layoutsUrl + '/listform.aspx?PageType=6&ListId=' +_spPageContextInfo.pageListId + '&ID=' + itm.id;
console.log(_url);
var options = {
title: "Edit item",
width: 500,
height: 600,
showClose: true,
allowMaximize: true,
autoSize: true,
url: _url
};
SP.UI.ModalDialog.showModalDialog(options);
}
The hardest part is generating proper url:
PageType=6 means editform, value of 4 means dispform
To properly link to listform.aspx page you need to use some of _spPageContextInfo properties like list id, server relative url and layouts folder url
I try to edit my images in the tinymce editor,
I already have an image into it, i try to edit the path of this image to change it dinamically with :
tinymce.activeEditor.selection.getNode().src = '/my/path/'
and it works, the image is edited but when i get the html content of my editor, the src still is the old image.
is there an other way to change the source of the image?
there's an easy way to do this, here take a look :
Create your custom file browser using file_browser_callback : myFileBrowser, in your tinymce.init.
Then in your callback function
function myFileBrowser(field_name, url, type, win) {
tinyMCE.activeEditor.windowManager.open(
{
file: './test.html',
title: 'My File Browser',
width: 420, // Your dimensions may differ - toy around with them!
height: 400,
resizable: 'yes',
close_previous: 'no',
},
{
window: win,
input: field_name,
},
);
return false;
}
by doing this you tell tiny mce to open a new popup wich is the file 'test.html', and you send to your popup two parameters
window : win, input : field_name.
Then in your test.html you can get those parameters like this :
var args = top.tinymce.activeEditor.windowManager.getParams();
this will give you an object with your parameters and value. you can now use a little jquery or whatever you want to replace the field of your image value with the path of your new image. and then close your popup.
Hope i helped you.
I am using CKEditor on a website and I need to be able to put a special data attributes on some of the links created through the editor. The user would indicate that they need the special attribute put on the link by checking a checkbox in the link dialog. I have managed to add a checkbox to the link dialog with the following code:
CKEDITOR.on('dialogDefinition', function(ev) {
if (ev.data.name == "link") {
var info = dialog.getContents("info");
info.elements.push({
type: "vbox",
id: "urlOptions",
children: [{
type: "hbox",
children: [{
id: "button",
type: "checkbox",
label: "Button",
commit: function(data) {
data.button = this.getValue()
console.log("commit", data.button, data);
},
setup: function(data) {
this.setValue(data.button);
console.log("setup", data.button, data);
}
}]
}]
});
}
});
Now I have two problems. The first one is that despite me adding the code in the commit and setup functions that should save the state of the checkbox, it's not working. It's as if the data can't hold any other parameters but the ones there by default.
The second problem is that I don't know how to add / remove the data attribute on my links. It seems to me that I should be doing that in my onOk callback on the dialog, however, the link dialog already has an onOk callback, so I'm not sure how I should be proceeding. I, of course, do not want to modify any of CKEditor's files directly.
How can I accomplish these things?
You best option is to modify the plugin. So you need to open the source code and find the file links.js in c:\ckeditor_3.6.5\ckeditor\_source\plugins\link\dialogs\
The source code is quite big (40k) but here you can modify the dialog however you want. When you finish just copy it to your plugins folder, and compress it: http://jscompress.com/
I have done what you need myself. The whole uncompressed file is here: https://gist.github.com/3940239
What you need to do:
First add this line just before the dialog "browse" button is appended. Approx. in line: 547:
{
id: "button",
type: "checkbox",
label: "Button",
setup: function (data) {
this.allowOnChange = false;
if (data.button)
this.setValue(data.button);
this.allowOnChange = true;
},
commit: function (data) {
data.button = this.getValue()
this.allowOnChange = false;
}
},
This part is actually your code. I just copied and pasted it.
Then, go to the onOk function, approx. in line 1211: and after commitContent add this code:
this.commitContent( data );
//My custom attribute
if (data.button)
attributes["custom-attribute"] = "button";
else
attributes["custom-attribute"] = "";
This will modify your link adding the attribute to the element such as text
That's it. Although, you may also like to load the current status of the checkbox. Then, go to the function parseLink . Approx. line 179 to load the attributes:
...
if ( element )
{
retval.button = element.getAttribute('custom-attribute');
var target = element.getAttribute( 'target' );
...
I am exploring the same thing now. What I have decided to do at this point is to:
Get a base ckeditor install without the link plugin
create my own fork of the link plugin, and add my changes to it, then activate and use this plugin within the group that link normally shows up in.
...working with it as a custom plugin (albeit a copy of the original) should alleviate the problem of upgrading. You just simply do not use the original link plugin at all. Copy and rename it, and use your custom copy instead.
Hey guys in my recent project i have used the valums file uploader for ajax based file uploading as i found it best with my requirements but now i am stuck at one point and that is i want to remove the drag and drop functionality from that i have searched internet for hours but nothing found helpful. Is there any way to remove this part from plugin? Here is my code
uploader = new qq.FileUploader({
element: $('#file-uploader')[0],
action: base_url + 'assets/scripts/server-side/server-side-uploader.php',
debug: true,
});
You can define your own template without the drag and drop section e.g. I have:
template: '<div class="qq-uploader">' +
'<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
'<div class="qq-upload-button">Upload Proof</div>' +
'<ul class="qq-upload-list"></ul>' +
'</div>',
Remove the following line from the template to disable drag and drop functionality
'<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
I can not agree with the accepted answer for this question. In case of deleting of line
'<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
qq uploader gives throw new error('element not found ' + type), so that is not the solution for sure - noone wants to see javascript errors on page (at least me).
The easiest way, I think, to get rid of that drop area is to hide the div with css: just do
.qq-upload-drop-area {
display: none;
}
This works fine for me. No errors, no div block.
var uploader = new qq.FileUploader({
....
});
qq.attach(document, 'dragenter', function(e) {
$('.qq-upload-drop-area').hide();
});
Use FileUploaderBasic instead. qq.FileUploader actually extends FileUploaderBasic, and adds the list support and drag/drop stuff. FileUploaderBasic only implements the button and validation.
var uploader = new qq.FileUploaderBasic({
// pass the dom node (ex. $(selector)[0] for jQuery users)
element: document.getElementById('file-uploader'),
// path to server-side upload script
action: '/server/upload'
});
If you want to use some of the other features that FileUploaderBasic doesn't have (like lists), just extend qq.FileUploaderBasic in a separate JavaScript file referenced after fileupoader.js, like so:
var qq = qq || {};
qq.extend(qq.FileUploaderBasic.prototype, {
//override uploader stuff by just creating a function with the same name,
//like this function that creates the upload button
_createUploadButton: function(element){
var self = this;
//make whatever modifications you want here
return new qq.UploadButton({
element: element,
multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(),
onChange: function(input){
self._onInputChange(input);
}
});
}
});
this worked for me
jQuery('.qq-upload-drop-area').remove();
Just make the text color transparent
.ajax__fileupload_dropzone {color:transparent;}
I have a situation on CKEditor that I would like to resolve. I use a jQuery color picker to add background color to a DIV tag. Then I allow the user to edit the Div tag contents using CKEditor. However, I noticed that there isn't a simple way to take the div tag's background color and then make that as the background color of the CKEditor when the editor loads up.
I have read up on bodyClass and bodyId and do not think that these solve my problem. I do not have a class element but an inline style declaration like
<div class="tp-header" style="background-color:#CCCCCC;">content</div>
I invoke the CKEditor as follows:
var editorId = 'editor1';
var instance = CKEDITOR.instances[editorId];
var color = $('.' + headerElementClass).css('background-color');
if (instance) { CKEDITOR.remove(instance); }
$('#' + editorId).ckeditor({ toolbar: 'BasicHtml', height: '100px', width: '500px', fullPage: false, bodyClass : 'background-color:' + color });
$('#' + editorId).val($('.' + headerElementClass).html());
Notice the failed usage of bodyClass. Is there any way to do this? I have scourged around the site for answers but couldn't find one. I hope someone here has the answer.
I was thinking about this and I came up with a much simpler solution.
I'm not using the CKEditor jQuery adapter, so you may need to modify it to fit your situation.
I did test it using the standard JavaScript integration approach.
Quick Overview:
Set the variables.
Create the editor instance.
Insert this "addCss" function call:
CKEDITOR.instances[editorId].addCss( 'body { background-color: '+color+'; }' );
That's all there is to it. Here's a sample based on your code:
// I added the "id" attribute:
<div id="editor1" class="tp-header" style="background-color:#CCCCCC;">content</div>
// Declare the variables, I added "headerElementClass".
var headerElementClass = "tp-header";
var color = $('.' + headerElementClass).css('background-color');
var editorId = 'editor1';
// Create the instance.
var instanceOne = CKEDITOR.replace( editorId,
{
toolbar: 'Basic',
height: '100px',
width: '500px',
fullPage: false,
customConfig : 'yourCustomConfigFileIfUsed.js'
});
// Insert the "addCss" function call:
instanceOne.addCss( 'body { background-color: '+color+'; }' );
The addCss function call can be moved to your config file if you prefer (place it outside the editorConfig function).
Be Well,
Joe
Leaving the more complicated approach, someone might find the concepts useful.
You could use ( bodyClass: 'nameOfClass' ), then assign a value to the background-color property of that class. But that's difficult because you have a dynamic background color.
To assign the background color dynamically you could do something like this:
Starting with your code and continuing the use of jQuery:
var editorId = 'editor1';
var instance = CKEDITOR.instances[editorId];
var color = $('.' + headerElementClass).css('background-color');
// Create a unique body id for this instance "editor1" ( bodyIdForeditor1 )
var idForBody = 'bodyIdFor' + editorId;
if (instance) { CKEDITOR.remove(instance); }
// Use bodyId instead of the original bodyClass assignment
$('#' + editorId).ckeditor({
toolbar: 'BasicHtml',
height: '100px',
width: '500px',
fullPage: false,
bodyId : idForBody
});
$('#' + editorId).val($('.' + headerElementClass).html());
// After both the document and editor instance are ready,
// assign the background color to the body
// Wait for the document ready event
$(document).ready(function(){
// Wait for the instanceReady event to fire for this (editor1) instance
CKEDITOR.instances.editor1.on( 'instanceReady',
function( instanceReadyEventObj )
{
var currentEditorInstance = instanceReadyEventObj.editor;
var iframeDoc=null;
// Create a function because these steps will be repeated
function setIframeBackground()
{
// The CKEditor content iframe doesn't have a Name, Id or Class
// So, we'll assign an ID to the iframe
// it's inside a table data cell that does have an Id.
// The Id of the data cell is "cke_contents_editor1"
// Note that the instance name is the last part of the Id
// I'll follow this convention and use an Id of "cke_contents_iframe_editor1"
$("#cke_contents_editor1 iframe").attr("id", "cke_contents_iframe_editor1");
// Now use the iframe Id to get the iframe document object
// We'll need this to set the context and access items inside the iframe
$('#cke_iframe_editor1').each(
function(){ iframeDoc=this.contentWindow.document;}
);
// Finally we can access the iframe body and set the background color.
// We set the Id of the body when we created the instance (bodyId : idForBody).
// We use the iframe document object (iframeDoc) to set the context.
// We use the "color" variable created earlier
$('#' + idForBody, iframeDoc).css("background-color", color);
}
// Call the function to set the color when the editor instance first loads
setIframeBackground();
// When the user switches to "source" view mode, the iframe is destroyed
// So we need to set the color again when they switch back to "wysiwyg" mode
// Watch for the "mode" event and check if we're in "wysiwyg" mode
currentEditorInstance.on( 'mode', function()
{
if(currentEditorInstance.mode == 'wysiwyg')
setIframeBackground();
});
}
);
});
Be Well,
Joe
codewaggle's answer is a good one, but if you want to set inline styles on the editor's <body> element, you can do that too, using:
editor.document.getBody().setStyle()
or
editor.document.getBody().setStyles()
However, you'll need to redo this every time after calling editor.setData() and after the user switches back to wysiwyg mode (from source mode), because these things re-create the editor iframe. To do all that, set your styles using a function, say setEditorStyle, in which you check first that editor.mode==='wysiwyg' (editor.document is null otherwise), then add that function as an event listener for the instanceReady and mode events; and perhaps also the contentDom event if you ever call setData() and don't want to call it manually afterwards.
See some other StackOverflow answers here and here
Dynamic Body Color change CKEditor
Expert Suggestion