Custom plugin with DOM manipulation CKEditor 4.x - javascript

I am developing one custom plugin for the CKEditor 4.7 which do a simple think take in case user select some stuff it will put it in a div with specific class, else it will put a div with same class just with text like 'Add content here'
I try to use some functions according to CKEditor docs but have something really wrong.
here is the code for the plugin folder name=> customdiv, file=> plugin.js
CKEDITOR.plugins.add('customdiv', {
icons: 'smile',
init: function (editor) {
editor.addCommand( 'customdiv',{
exec : function( editor ){
var selection = editor.getSelection();
if(selection.length>0){
selection='<div class="desktop">'+selection+'</div>';
}else{
selection='<div class="desktop">Add your text here </div>';
}
return {
selection
};
}
});
editor.ui.addButton( 'Customdiv',
{
label : 'Custom div',
command : 'customdiv',
toolbar: 'customdiv',
icon : this.path + 'smile.png'
});
if (editor.contextMenu) {
editor.addMenuGroup('divGroup');
editor.addMenuItem('customdiv', {
label: 'Customdiv',
icon: this.path + 'icons/smile.png',
command: 'customdiv',
group: 'divGroup'
});
editor.contextMenu.addListener(function (element) {
if (element.getAscendant('customdiv', true)) {
}
});
}
}
});
According to some docs it have to return the result good.
Also this is how I call them in my config.js file
CKEDITOR.editorConfig = function (config) {
config.extraPlugins = 'templates,customdiv';
config.allowedContent = true;
config.toolbar = 'Custom';
config.toolbar_Custom = [
{ name: 'divGroup', items: [ 'Customdiv' ] },
{name: 'document', items: ['Source', '-', 'Save', 'Preview', '-', 'Newplugin']},
/* MOre plugins options here */
];
};
Note: the official forum was close and moved here :(
UPDATE
I have change the function like this
exec : function( editor ){
var selection = editor.getSelection();
if(selection.length>0){
selection='<div class="desktop">'+selection+'</div>';
CKEDITOR.instances.editor1.insertHtml( selection );
}else{
selection='<div class="desktop">Add your text here </div>';
CKEDITOR.instances.editor1.insertHtml( selection );
}
}
This makes it work for the else part, but still can't get the selected one.
UPDATE 2
After change of the if I can get data if is selected, but when I do insert selected between <div> I face a problem.
var selection = editor.getSelection();
give like result an object, and I funded out a more complex function and I get collected data like this
var selection = editor.getSelection().getNative();
alert(selection);
from this in alert I see the proper selection and not just object,but when I insert it like
CKEDITOR.instances.editor1.insertHtml('<div class="desktop">' + selection + '</div>');
it just put all selected in one line and not adding the div, new div for else case working with this syntax.
UPDATE 3
The problem now is this function
CKEDITOR.instances.editor1.insertHtml('<div>' + selection + '<div>');
it delete all existing HTML tags even if I add just selection without <div> I am not sure if this is because of the way I insert data or way I collect data, just in alert when I collect data I see correct space like in the editor.

user select some stuff it will put it in a div with specific class
If you want to check if selection is not empty, please instead of selection.length>0 try using !selection().getRanges()[0].collapsed.
If you need something more advanced you could also try using
!!CKEDITOR.instances.editor1.getSelection().getSelectedText() to see if any text was selected and !!CKEDITOR.instances.editor1.getSelection().getSelectedElement() to see if any element like e.g. image, tabl,e widget or anchor was selected.
EDIT:
If you need selected HTML please use CKEDITOR.instances.editor1.getSelectedHtml().getHtml();
Please also have a look at CKEditor documentation:
https://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml
https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_dom_documentFragment.html#method-getHtml
https://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getSelectedText
https://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getSelectedElement

Related

Single check box selection with jquery datatable

In jquery datatable, single check box should be selected.
This link is working fine.
But above link is using jquery.dataTables 1.10.16 version. And I am using jquery.dataTables 1.9.4.
Can the same functionality as listed in example given above be possible with jquery.dataTables 1.9.4 instead of jquery.dataTables 1.10.16?
In the same page which you give the link, there are many explanation about to using "single check" oparetion.
At the end of the listed attachment, you can see the referanced .js file is
https://cdn.datatables.net/select/1.2.5/js/dataTables.select.min.js
In your page, you should add this file referance after dataTable.js.
I think, the version of jquery is not important. The important file is "dataTables.select.js"!
Secondly, you must update your dataTable maker codes like the sample below;
$(document).ready(function() {
$('#example').DataTable( {
columnDefs: [ {
orderable: false,
className: 'select-checkbox',
targets: 0
} ],
select: {
style: 'os',
selector: 'td:first-child' // this line is the most importan!
},
order: [[ 1, 'asc' ]]
} );
} );
UPDATES :
Why dont you try to write your own selector function?
for example;
$(document).ready(function() {
$('#example').DataTable( {
/// put your options here...
} );
$('#example').find("tr").click(function(){ CheckTheRow(this); });
} );
function CheckTheRow(tr){
if($(tr).find("td:first").hasClass("selected")) return;
// get the pagination row count
var activePaginationSelected = $("#example_length").find("select").val();
// show all rows
$("#example_length").find("select").val(-1).trigger("change");
// remove the previous selection mark
$("#example").find("tr").each(function(i,a){
$(a).find("td:first").removeClass("selected");
$(a).find("td:first").html("");
});
// mark the picked row
$(tr).find("td:first").addClass("selected");
$(tr).find("td:first").html("<i class='fa fa-check'></i>");
// re turn the pagination to first stuation
$("#example_length").find("select")
.val(activePaginationSelected).trigger("change");
}
Unfortunately, legacy data table does not support or have that select extension.
Workaround:
Create checkbox element inside 'mRender' callback.
Bind action to the checkbox. (This can be done inside the fnRowCallback or outside as in my example in below fiddle
https://jsfiddle.net/Rohith_KP/dwcatt9n/1/
$(document).ready(function() {
var userData = [
["1", "Email", "Full Name", "Member"],
["2", "Email", "Full Name", "Member"]
];
var table = $('#example').DataTable({
'data': userData,
'columnDefs': [{
'targets': 0,
'className': 'dt-body-center',
'mRender': function(data, type, full, meta) {
return '<input type="checkbox" value="' + $('<div/>').text(data).html() + '">';
}
}],
'order': [1, 'asc']
});
$('#example tr').click(function() {
if ($(this).hasClass('row_selected'))
$(this).removeClass('row_selected');
else
$(this).addClass('row_selected');
});
});
Also, I suggest you to upgrade your datatable version. Then you can use that select extension.
Can the same functionality as listed in example given above be possible with jquery.dataTables 1.9.4 instead of jquery.dataTables 1.10.16?
Yes.
But, not using the Select Extension since it requires at least version 1.10.7.
For 1.9.4, a possible solution would be:
$(document).ready(function() {
$('#example').find("td input[type='checkbox']").click(function() {
selectRow(this);
});
var table = $('#example').DataTable();
function selectRow(clickedCheckBox) {
var currentPage = table.fnPagingInfo().iPage;
// Being unchecked
if (!$(clickedCheckBox).is(':checked')) {
$(clickedCheckBox).removeAttr('checked');
getRow(clickedCheckBox).removeClass('selected');
return;
}
var selectEntries = $("#example_length").find("select");
var showEntriesCount = selectEntries.val();
var totalRows = table.fnGetData().length;
// If show entries != totalRows append total rows opiton that can be selected
if (totalRows != showEntriesCount)
selectEntries.append($('<option>', {
value: totalRows,
text: totalRows
}));
// Display all rows
selectEntries.val(totalRows).trigger("change");
// Removes all checked attribute from all the rows
$("#example").find("td input[type='checkbox']").each(function(value, key) {
getRow(key).removeClass('selected');
$(key).removeAttr('checked');
});
// Check the clicked checkBox
$(clickedCheckBox).prop('checked', true);
getRow(clickedCheckBox).addClass('selected');
// Re set the show entries count
selectEntries.val(showEntriesCount).trigger("change");
// If added, Remove the additional option added to Show Entries
if (totalRows != showEntriesCount)
selectEntries.find("[value='" + totalRows + "']").remove();
// Go to the page on which the checkbox was clicked
table.fnPageChange(currentPage);
}
function getRow(element) {
return $(element).parent().parent();
}
});
The above will require fnPagingInfo to take the user back to initial page. I haven't tested the solution on large dataset, tested it on a table with 150 rows, but should work fine on larger datasets too.
JSFiddle
Have you tried below code and I checked and it is working fine, you need to update styles and scripts:
You havr to update the latest styles and scripts to achieve latest functionality.
Single check box selection with jquery datatable

Predefined buttons in CKEditor Mathjax plugin

CKEditor's Mathjax plugin contains several elements in the dialog: one textarea (id: equation) and one div (id: preview).
https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/mathjax/dialogs/mathjax.js
When some mathjax code is entered in the textarea, the formula is written in the div. I am trying to add several predefined buttons that add usual formulae mathjax text to the textarea, so users only have to populate these formulae.
Adding a button into the elements works nice, but I can only access to change the div element. Accessing the textarea does not work, it seems that is not available in any scope at all.
id: 'info',
elements: [
{
id: 'testButton',
type: 'button',
button: 'aaaa',
onClick: function() {
// Changing the ID value does work
preview.setValue('Test');
// but changing the textarea does not.
// equation.setValue('Test');
// document.getElementById('equation').setValue('Test');
}
},
{
id: 'equation',
type: 'textarea',
label: lang.dialogInput,
onLoad: function() {
var that = this;
if ( !( CKEDITOR.env.ie && CKEDITOR.env.version == 8 ) ) {
this.getInputElement().on( 'keyup', function() {
// Add \( and \) for preview.
preview.setValue( '\\(' + that.getInputElement().getValue() + '\\)' );
} );
}
},
Sorry if this is a simple question, but how can I access to equation textarea?
After much reading, it seems that this is a way, not sure it's the best way though.
onClick: function() {
this._.dialog.setValueOf("info","equation","TEST");
}

Froala editor custom dropdown with dynamic values

I am using Froala and I am stuck creating a custom drop down with dynamic option sets in it. I have used their common way to create the drop down but that is useless if we have to fetch the values from db.
I want to make a "Templates" dropdown with 10 options to select which will be created dynamically.
Currently we create a custom drop down this way,
options: {
'Template One': function(e){
_this.editable('insertHTML', "<p>This is template one</p>", true);
},
}
I want this to be dynamic, meaning I will fetch the names and content of the templates from database and add them in the option set accordingly.
something like,
options : {
$.each(alltemplates, function(i, h){
i: function(e){ /// "i" will be the name of the template fetched from db
_this.editable('insertHTML', h, true); // h is the html fetched from db
},
})
}
which will create the drop down dynamically. Any help please ?
Expanding on #c23gooey's answer, here's what we came up with for a similar problem (inserting dynamically-generated mail-merge placeholders).
var commandName = 'placeholders',
iconName = commandName + 'Icon',
buildListItem = function (name, value) {
// Depending on prior validation, escaping may be needed here.
return '<li><a class="fr-command" data-cmd="' + commandName +
'" data-param1="' + value + '" title="' + name + '">' +
name + '</a></li>';
};
// Define a global icon (any Font Awesome icon).
$.FroalaEditor.DefineIcon(iconName, { NAME: 'puzzle-piece' });
// Define a global dropdown button for the Froala WYSIWYG HTML editor.
$.FroalaEditor.RegisterCommand(commandName, {
title: 'Placeholders',
type: 'dropdown',
icon: iconName,
options: {},
undo: true,
focus: true,
refreshAfterCallback: true,
callback: function (cmd, val, params) {
var editorInstance = this;
editorInstance.html.insert(val);
},
refreshOnShow: function ($btn, $dropdown) {
var editorInstance = this,
list = $dropdown.find('ul.fr-dropdown-list'),
listItems = '',
placeholders = editorInstance.opts.getPlaceholders();
// access custom function added to froalaOptions on instance
// use a different iteration method if not using Angular
angular.forEach(placeholders, function (placeholder) {
listItems += buildListItem(placeholder.name, placeholder.value);
});
list.empty().append(listItems);
if (!editorInstance.selection.inEditor()) {
// Move cursor position to end.
editorInstance.selection.setAtEnd(editorInstance.$el.get(0));
editorInstance.selection.restore();
}
}
});
We ran this method by Froala support and were told:
The editor doesn't have any builtin mechanism for using dynamic
content when showing the dropdown, but your solution is definitely a
good one.
Use the refreshOnShow function to change the options dynamically.

CKEditor Remove (selected) from label on click

I have created a simple plugin to move some of the formatting buttons to a dropdown button. The dropdown button has both an icon and a label. The plugin works as intended except that when clicked on the label shows both the intended text as well as adding "(selected)" to the end.
Here is the button default view (the formatting button):
And here is how it looks when clicked on:
Here is the code for the plugin:
CKEDITOR.plugins.add( 'sf_formatting', {
init: function( editor ) {
var format = {};
editor.addMenuGroup( 'format_group' );
format.indent = {
label: 'Increase Indent',
group: 'format_group',
command: 'indent',
order: 6
};
format.outdent = {
label: 'Decrease Indent',
group: 'format_group',
command: 'outdent',
order: 7
};
editor.addMenuItems( format );
editor.ui.add( 'Formatting', CKEDITOR.UI_MENUBUTTON, {
label: 'Formatting',
// Disable in source mode.
modes: {
wysiwyg: 1
},
icon: 'dropdown',
onMenu: function() {
var active = {};
// Make all items active.
for ( var p in format )
active[ p ] = CKEDITOR.TRISTATE_OFF;
return active;
}
} );
}
});
I have a second issue
The outdent (decrease indent) only appears when the text has been indented. In the main menu it is always there but greyed out. How can I force the outdent button to always be visible in the dropdown box but not accessible.
Here is a screenshot of the dropdown when the text has been indented:
I'd be really grateful for any help.
I managed to create a hack to make this work as no one seems to know the answer.
In the language file, the relevant entry is "%s (Selected)". %s is replaced by the menu title in the plugin code.
I just removed the "(Selected") and now it works fine FOR MY USE.
It may break other things I am unaware of, but it works for me

Plugin for CKeditor to add multiple styles

Codewaggle's answer here got me started and I also have looked at Reinmar's answer, but I can't quite put this together.
I want to create a plugin with five custom spans (correction, deletion, suggestion...etc.) that I can then add to my CSS and have a button to apply each style using CKeditor in Drupal 7.
I don't want to use the drop-down for styles and prefer to have buttons with icons for each class added.
I used the basicstyles plugin as a jumping off point, but I have never done anything in javascript before so I am really in the dark.
I have added
config.extraPlugins = 'poligoeditstyles';
to the config file and set up the file structure of my plugin according to the guide on the CKeditor.
I assume that if all has gone according to plan I should see a button to drag into my toolbar, but, alas! No joy. I can see nothing added to my CKeditor toolbar when I add content or on the configuration page in Drupal:
admin/config/content/ckeditor/edit/Advanced
Am I missing something? Any help would be appreciated!
Here's my plugin code:
/**
* POLIGO edit styles plug-in for CKeditor based on the Basic Styles plugin
*/
CKEDITOR.plugins.add( 'poligoeditstyles', {
icons: 'correction,suggestion,deletion,commendation,dontunderstand', // %REMOVE_LINE_CORE%
init: function( editor ) {
var order = 0;
// All buttons use the same code to register. So, to avoid
// duplications, let's use this tool function.
var addButtonCommand = function( buttonName, buttonLabel, commandName, styleDefiniton ) {
// Disable the command if no definition is configured.
if ( !styleDefiniton )
return;
var style = new CKEDITOR.style( styleDefiniton );
// Listen to contextual style activation.
editor.attachStyleStateChange( style, function( state ) {
!editor.readOnly && editor.getCommand( commandName ).setState( state );
});
// Create the command that can be used to apply the style.
editor.addCommand( commandName, new CKEDITOR.styleCommand( style ) );
// Register the button, if the button plugin is loaded.
if ( editor.ui.addButton ) {
editor.ui.addButton( buttonName, {
label: buttonLabel,
command: commandName,
toolbar: 'poligoeditstyles,' + ( order += 10 )
});
}
};
var config = editor.config,
lang = editor.lang;
addButtonCommand( 'Correction', 'That's a mistake', 'correction', config.coreStyles_correction );
addButtonCommand( 'Suggestion', 'That's OK, but I suggest...', 'suggestion', config.coreStyles_suggestion );
addButtonCommand( 'Deletion', 'You don't need that', 'deletion', config.coreStyles_deletion );
addButtonCommand( 'Commendation', 'Great job!', 'commendation', config.coreStyles_commendation );
addButtonCommand( 'Dontunderstand', 'I don't understand what you mean', 'dontunderstand', config.coreStyles_dontunderstand );
}
});
// POLIGO Editor Inline Styles.
CKEDITOR.config.coreStyles_correction = { element : 'span', attributes : { 'class': 'correction' }};
CKEDITOR.config.coreStyles_suggestion = { element : 'span', attributes : { 'class': 'suggestion' }};
CKEDITOR.config.coreStyles_deletion = { element : 'span', attributes : { 'class': 'deletion' }};
CKEDITOR.config.coreStyles_commendation = { element : 'span', attributes : { 'class': 'commendation' }};
CKEDITOR.config.coreStyles_dontunderstand = { element : 'span', attributes : { 'class': 'dontunderstand' }};
Shot in the dark here but have you added your button to your config.toolbar in your initialization or config somewhere else - see http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Toolbar

Categories