Dynamically change ckeditor dialog - javascript

I'm trying to modify the contents of a dialog field based on another field. I've tried the replace method, but I'm throw this error: The editor instance "edit-body-und-0-value" is already attached to the provided element.
The basic goal is to add a class to the table. Using the table dialog I figured if I could fill in the advCSSClassess default value, then replace the editor, I'd now have a dialog in with the class attached.
Here's my plugin code:
CKEDITOR.on('dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName === 'table' ) {
var tableProperties = dialogDefinition.getContents( 'info' );
var advancedTab = dialogDefinition.getContents( 'advanced' );
var classField = advancedTab.get( 'advCSSClasses' );
classField['default'] = 'stackable';
tableProperties.add({
type: 'checkbox',
id: 'stackTable',
label: 'Make table responsive',
'default': false,
onClick: function( button ) {
classField[ 'default' ] = 'stackable';
var thisEditor = CKEDITOR.instances;
CKEDITOR.replace('edit-body-und-0-value', thisEditor);
}
});
}
});
I've been able to hack it in like this in the click handler, but that doesn't seem sustainable.:
var classInput = $("label:contains('Stylesheet Classes')").attr('for');
$('#' + classInput).val('stackable');
I've used this and this for reference.

Since this question got a new request, here's the code that I ended up with. This is old enough that I can't remember the details, but I hope this helps.
CKEDITOR.on('dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName === 'table' ) {
var tableProperties = dialogDefinition.getContents( 'info' );
tableProperties.add({
type: 'checkbox',
id: 'stackTable',
label: 'Make table stackable on mobile. Does not work with header row.',
'default': false,
onClick: function( button ) {
var classInput = CKEDITOR.dialog.getCurrent().getContentElement('advanced', 'advCSSClasses').getElement().$;
$('#' + classInput.id).find('input').val('sy-stacktable');
}
});
}
});

Related

How to change a Ckeditor 4 Field Label?

I have no idea where to look to figure this out. I'm trying to change a select elements label that's automatically generated with ckeditor. I've looked through the documentation, but I cannot find a solution to modifying the label. Instead of saying align, I need it to say something like, "FOO Align" I'm at a loss here. I've got the parent divs id. I've tried doing the following
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(function() {
document.getElementById('cke_79_label').innerHTML = 'FOO Alignment';
});
As Well as,
function alignmentLabelReplace() {
document.getElementById('cke_79_label').innerHTML
= 'FOO Alignment';
}
So to kind of condense the overall goal is to change the label of a ckeditor select box. The ckeditor select box is within the table element, that pops up in a modal. How do I manipulate this?
EDIT: I'm trying to take this stackoverflow article to fix to my purposes.
I've wrote this up, but. Still no luck.
CKEDITOR.dialog.add( 'dialogDefinition', function ( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName == 'table' || dialogName == 'tableProperties'){
return {
contents: [
{
id: "cmbAlign",
type: "select",
label: 'Table Alignment',
}]
};
}
});
So. I got ahold of a senior dev with the company I work for and we found a solution. I've tested it on my environment, it works for me. I've tried to write up some explanatory text as well for future individuals. Please forgive me if my words or syntax is incorrect.
This bit of documentation may help as well.
(function () {
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName == 'table' || dialogName == 'tableProperties'){
//Get info tab
console.log(dialogDefinition);
// So through this we get the contents of the table ui.
var infoTab = dialogDefinition.getContents( 'info' );
console.log(infoTab);
//no that we've got the table dialed down a bit more
// we're able to see the various elements.
//now, I've made a variable selectLabel, where I take infoTab apply .get
// with the id 'cmbAlign'
var selectLabel = infoTab.get('cmbAlign');
//then as we can see here, i take the variable selectLabel
//target the array element in square brackets, ['label']
// set the new varaiable, and it works!
selectLabel['label'] = 'Table Alignment';
}
});
})();

ckeditor default target link=" _blank" not work properly

My ckeditor version is 4.4.7
I want to change the default target to every link of the text that I add to ckeditor and I found this code
CKEDITOR.on('dialogDefinition', function(ev) {
try {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if (dialogName == 'link') {
var informationTab = dialogDefinition.getContents('target');
var targetField = informationTab.get('linkTargetType');
targetField['default'] = '_blank';
}
} catch (exception) {
alert('Error ' + ev.message);
}
});
CKEDITOR.on('instanceReady', function(ev) {
var editor = ev.editor,
dataProcessor = editor.dataProcessor,
htmlFilter = dataProcessor && dataProcessor.htmlFilter;
htmlFilter.addRules({
a: function(element) {
element.attributes['target'] = "_blank";
}
});
});
I added this code to link.js file of ckeditor folder and it's working
but not correctly
I mean if I copy the text that have a link from word to editor,it doesn't add target_blank to a href automatically
but I have to click 'edit link' on it and see the default target already on _blank
then I click ok and save then it works.
but I want it to auto set target="_blank" on every link that I copy from word.
anyone can help?
thanks.
Where did you put your code?
I changed
type : 'select',
id : 'linkTargetType',
label : commonLang.target,
'default' : 'notSet',
in _source\plugins\link\dialogs\link.js to
type : 'select',
id : 'linkTargetType',
label : commonLang.target,
'default' : '_blank',
and this works fine.
Editing inside plugin files is not an ideal solution.
The best solution would be to add this to your js file
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if ( dialogName == 'link' ) {
var targetTab = dialogDefinition.getContents( 'target' );
var targetField = targetTab.get( 'linkTargetType' );
targetField[ 'default' ] = '_blank';
}
});
I added this code to link.js file of ckeditor folder and it's working but not correctly
You use this code directly on HTML page were you initialize the editor and not in link.js file:
var editor = CKEDITOR.replace( 'editor1', { });
CKEDITOR.on('dialogDefinition', function(ev) {
...

'dialogDefinition' event is not called for any dialog while initialization of CKEDITOR?

I am using dialogDefinition event to change the definition of the image2 dialog of the Enhanced Image plugin.I am using this code -
CKEDITOR.appendTo("editor1" ,
{
on: {
dialogDefinition: function (ev) {
console.log("Inside dialog definition");
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
if (dialogName == 'image2') {
console.log("Inside Upload");
dialogDefinition.removeContents('Upload');
dialogDefinition.addContents({
title: "Upload",
id: "upload",
label: "Upload",
elements: [{
type: "html",
html: "<form>{%csrf_token%}<input id='imageupload' type='file' name='files[]'/></form>"
}]
});
}
},
},
However when I click on any dialog, this event is not called as the console message did not get printed and the definition of image2 dialog did not change.
Is there any way to find out why this event is not called or how to make it work?
Note that dialogDefinition event belongs to CKEDITOR, not CKEDITOR.editor. The right way to listen on dialogDefinition is like:
CKEDITOR.on( 'dialogDefinition', function( ev ) {
var dialogName = ev.data.name;
var dialogDefinition = ev.data.definition;
...
});

How to change data produced by CKEditor dialog

I want to do some stuff with the image that is added using Image toolbar button in CKEditor.
I actually want to get the url and modify if required.
How can I do it?
I am able to do that stuff using dataFilter but only when image is directly pasted into the
editor. But dataFilter rule doesn't execute when image is added using default Image button in editor.
CKEDITOR.replace( 'idContent' );
CKEDITOR.on( 'instanceReady', function( e ) {
CKEDITOR.instances.idContent.dataProcessor.dataFilter.addRules( {
elements: {
"img": function (element) {
var imageSrcUrl = element.attributes.src;
// Do some stuffs here.
}
}
} );
} );
I achieved my purpose using following code
CKEDITOR.on( 'dialogDefinition', function( ev ) {
// Take the dialog name and its definition from the event data
var dialogName = ev.data.name,
dialogDefinition = ev.data.definition;
if ( dialogName == 'image' ) {
var onOk = dialogDefinition.onOk;
dialogDefinition.onOk = function( e ) {
var input = this.getContentElement( 'info', 'txtUrl' ),
imageSrcUrl = input.getValue();
//! Manipulate imageSrcUrl and set it
input.setValue( imageSrcUrl );
onOk && onOk.apply( this, e );
};
}
});

javascript change event fires when page loads - how to avoid this?

I have a form with chained select boxes. The zend controller sets the default values for these select boxes (values come from the db). I am a jquery novice.
$form->setDefaults($data);
a jquery file is loaded :
$(document).ready(function(){
// set up the chained select
$("#region").remoteChained("#country", "/ws/regionstructure");
$("#province").remoteChained("#region", "/ws/regionstructure");
$("#town").remoteChained("#province", "/ws/regionstructure");
});
The problem is that when the page loads it is triggering the change event for country and resetting all of the selects.
Here is the remoteChained jquery code that is being called:
/*
* Remote Chained - jQuery AJAX(J) chained selects plugin
*
* Copyright (c) 2010-2011 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
*/
(function($) {
$.fn.remoteChained = function(parent_selector, url, options) {
return this.each(function() {
/* Save this to self because this changes when scope changes. */
var self = this;
var backup = $(self).clone();
/* Handles maximum two parents now. */
$(parent_selector).each(function() {
$(this).bind("change", function() {
/* Build data array from parents values. */
var data = {};
$(parent_selector).each(function() {
var id = $(this).attr("id");
var value = $(":selected", this).val();
data[id] = value;
});
$.getJSON(url, data, function(json) {
/* Clear the select. */
$("option", self).remove();
/* Add new options from json. */
for (var key in json) {
if (!json.hasOwnProperty(key)) {
continue;
}
/* This sets the default selected. */
if ("selected" == key) {
continue;
}
var option = $("<option />").val(key).append(json[key]);
$(self).append(option);
}
/* Loop option again to set selected. IE needed this... */
$(self).children().each(function() {
if ($(this).val() == json["selected"]) {
$(this).attr("selected", "selected");
}
});
/* If we have only the default value disable select. */
if (1 == $("option", self).size() && $(self).val() === "") {
$(self).attr("disabled", "disabled");
} else {
$(self).removeAttr("disabled");
}
/* Force updating the children. */
$(self).trigger("change");
});
});
/* Force updating the children. */
$(this).trigger("change");
});
});
};
/* Alias for those who like to use more English like syntax. */
$.fn.remoteChainedTo = $.fn.remoteChained;
})(jQuery);
I don't see any issue with removing the change event, but the way that plugin works seems highly inefficient. I refactored this (untested), so give this a go and see how it works for you.
You can call it like so:
$( "#region" ).remoteChained( { parentSelector: "#country", url: "/ws/regionstructure" } );
$( "#province" ).remoteChained( { parentSelector: "#region", url: "/ws/regionstructure" } );
$( "#town" ).remoteChained( { parentSelector: "#province", url: "/ws/regionstructure" } );
This shouldn't trigger the change event. If you find you need to do this, you can do something like this:
$( '#region' ).trigger( 'change' );
Here is the new plugin code. Let me know if you have any issues with it:
( function( $ ) {
$.fn.remoteChained = function ( options ) {
var defaults = { },
settings = $.extend( { }, defaults, options );
return this.each( function () {
var el = $( this ),
parent = $(settings.parentSelector),
data = { };
parent.each( function () {
var el = $(this);
data[ el.attr( 'id' ) ] = el.find( ':selected' ).val();
});
parentSelector.bind( 'change.remotechanged', function ( e ) {
var request = $.ajax( { url: settings.url, data: data } );
request.done( function ( response ) {
var newOption;
el.find( 'option' ).remove();
for ( var key in response ) {
if ( !response.hasOwnProperty( key ) ) {
continue;
}
newOption = $( '<option />' )
.val( key )
.append( response[ key ] );
key === 'selected' && newOption.attr( 'selected', 'selected' );
newOption.appendTo( el );
}
if ( el.find( 'option' ).length === 1 && el.val() === '' ) {
el.attr( 'disabled', 'disabled' );
} else {
el.removeAttr( 'disabled' );
}
});
});
});
};
})( jQuery );

Categories