CKEditor hook/event fired up on switching to/from source view - javascript

I try to convert a div tag into something I can drag and drop in CKEditor (as asked in another question).
Do you know how I can trigger the event when someone switches between source view and WYSIWYG mode?

I think this is what you are looking for:
CKEDITOR.on('instanceCreated', function(e) {
e.editor.on('mode', function(e){
// Do your stuff here
alert(e.editor.mode);
});
});

If you mean, you want to capture source mode changes , then you could try something like this:
//add this to your CKeditor’s config.js
$('textarea.cke_source').live('keyup', function() {
$(this)
.closest('.cke_wrapper')
.parent()
.parent()
.prev()
.ckeditorGet()
.fire('change');
});
This discussion might help as well: ckEditor
Hope it helps

CKEditor onChange plugin:
Get a notification (new event) whenever the content of CKEditor changes.
http://ckeditor.com/addon/onchange

I think you should write a plugin to make a fake element for the wysiwyg-view.
Ckeditor is able to recognize elements that need to be replaced with fake-elements.
I made a start for you:
(function() {
CKEDITOR.plugins.add('myPlugin', {
requires : ['fakeobjects'],
init: function(editor) {
var me = this;
var pluginName = 'myPlugin';
editor.addCommand(pluginName, new CKEDITOR.dialogCommand(pluginName));
editor.addCss( // your custom css for your placeholder here
'div.myPluginElement' +
'{' +
'border: 1px solid #a9a9a9;' +
'width: 70px;' +
'height: 50px;' +
'}'
);
},
afterInit : function(editor) {
var dataProcessor = editor.dataProcessor,
dataFilter = dataProcessor && dataProcessor.dataFilter;
if (dataFilter) {
dataFilter.addRules({
elements : {
div : function(element) {
if (typeof element.attributes['class'] !== 'undefined' && element.attributes['class'].indexOf('myPluginElement') != -1)
return editor.createFakeParserElement(element, 'myPluginElement', 'div', false);
else return;
}
}
});
}
}
});
})();

Related

Bind an event on a jquery generated element

My code is like this:
$('.flag-icon-dz').click(function() {
var lang = 'Arab';
var $frame = $('.goog-te-menu-frame:first');
if (!$frame.size()) {
console.log("Error: Could not find Google translate frame.");
return false;
}
$frame.contents().find('.goog-te-menu2-item span.text:contains(' + lang + ')').get(0).click();
$("li.ql-item.linkid188546").after("<li class='ql-item linkid18854777 closegoogle'><a href='#' class='btn-primary' target='_self'><i class='icon closegoogle ls-lang-frr' aria-hidden='true'></i></a></li>").fadeIn(500);
$('li.ql-item.linkid188546').fadeOut(500);
return false;
});
$('.closegoogle').click(function() {
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
});
The first function works great, but the second doesn't. I realize that if I copy/paste the second function in the console after the first one, it works too.
I tried a few solutions (callback / setTimeout / jquery deferred / jquery .when method...) I didn't try promise but I don't think I have to in my context. Maybe I didn't write these solutions good enough.
I finally try to put my event (click) directly the .before() which create my new element like this :
$('.flag-icon-dz').click(function() {
var lang = 'Arab';
var $frame = $('.goog-te-menu-frame:first');
if (!$frame.size()) {
console.log("Error: Could not find Google translate frame.");
return false;
}
$frame.contents().find('.goog-te-menu2-item span.text:contains(' + lang + ')').get(0).click();
$("li.ql-item.linkid188546").after("<li class='ql-item linkid18854777 closegoogle'><a href='#' class='btn-primary' target='_self'><i class='icon closegoogle ls-lang-frr' aria-hidden='true'></i></a></li>").fadeIn(500).click(function() {
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
});
$('li.ql-item.linkid188546').fadeOut(500);
return false;
});
But it doesn't work either.
Thanks for the help.
EDIT :
I finally found a kind of solution for my second click event (which isn't the best solution but i works) :
window.setInterval(function(){$('.closegoogle').on("click",function(){
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
}); }, 1000);
Thanks.
You need to use a delegated bind as the element does not exist before you try your binding:
$('#parent-element-of-closegoogle').on('click', '.closegoogle', function() {
$('.skiptranslate').contents().find('.goog-close-link > img').click();
$('li.ql-item.linkid18854777').fadeOut('fast').remove();
$('li.ql-item.linkid188546').fadeIn(500);
});
Please note that the #parent-element-of-closegoogle needs to be an element that already exists when you do the binding - this can be $(document) if you hjave no other element to bind to

JS function to remove tag

I have added a button to TinyMCE using the following JS code:
(function() {
tinymce.PluginManager.add('button_span', function( editor, url ) {
editor.addButton('button_span', {
text: 'Test Button',
icon: false,
onclick : function() {
editor.selection.setContent('<em>' + editor.selection.getContent() + '</em>');
}
});
});
})();
So, when user clicks the button, it wraps any highlighted words into <em> tags.
My question is, how do I make it so that if the highlighted words are already in <em> tag, then it should remove the tag. I am guessing we need to adjust the onclick function.
Maybe give this a shot. I'm not very familiar with tinyMCE but this should work in general. Also, you'll want to expand this to check to see if there is also an '', and the replaces will vary based on that, this is just to get you started, but like I said, should be the basis of what your trying to do I think.
onclick : function() {
var contents = editor.selection.getContent();
if (contents.indexOf('<em>') >= 0) {
contents.replace('<em>', '');
contents.replace('</em>', '');
editor.selection.setContent(contents);
} else {
editor.selection.setContent('<em>' + editor.selection.getContent() + '</em>');
}
}

How to Show Dynamically Added Element

I'm trying to create tooltips with title attribute and jQuery but can't find method to show dynamically added element.
HTML
some page
CSS
.tooltip {
    …
display: none; /* I's needed for hard coded tooltips */
…
}
jQuery
$(function () {
if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
                //That's it. My tooltip has been created, but it has not been shown
$(el + ' .tooltip').show('fast');
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
$(el + ' .tooltip').hide('fast').remove();
el.prop('title', el.data('title'));
}
);
}
});
As mentioned by others, $(el + ' .tooltip').show('fast'); is probably wrong.
The el is an object, not a string to concat', one way is to use el.find('.tooltip').show().
The other way is to use the context option: $('.tooltip', el).show();
You need to have correct code to find new element:
$('.tooltip', el).show('fast');
Your current one probably endup searching for something like [object] .tooltip or similar string depending on how JavaScript decides to convert HTML element to string.
As others have mentioned el.find('.tooltip').show() and el.find('.tooltip').hide().remove(); solve the problem.
Also, in HandlerOut function, you el was not declared. Fiddle here
$(function () {
//if (window.matchMedia('(min-width: 980px)').matches) {
$('.dfn').hover(
function () {
var el = $(this);
var txtTitle = el.prop('title');
el.append('<p class="tooltip">' + txtTitle + '</p>');
//That's it. My tooltip has been created, but it has not been shown
el.find('.tooltip').show()
el.data('title', el.prop('title'));
el.removeAttr('title');
}, function () {
var el = $(this);
el.find('.tooltip').hide().remove();
el.prop('title', el.data('title'));
}
);
//}
});

In Optimizely, basic jQuery click event not working

In Optimizely, I'm trying to do some basic click events. I know that Optimizely is only on jQuery 1.6, so using on(), off() for events is useless. To make sure, I'm using the most basic event handler click(function(){ ... }));, but even this is not working. I was told to use window.$ but in the click() this technique doesn't work either. Is the jQuery in Optimizely different?
I know there is some kind of issue between Optimizely and jQuery but please can someone shed me some light on this?
JS snippett:
(function(window.$) {
window.$.fn.tabbs = function(options) {
var settings = {
dir: 'top',
trigger: 'a',
target: '.tab-section',
selected: 'selected'
},
html = $('html');
window.alert('jquery object: ' + window.$);
if (html.hasClass('no-js')) {
html.removeClass('no-js').addClass('js');
} else {
html.addClass('js');
}
var classAction = function(obj, action, cls) {
window.$(obj)[action](cls);
};
window.$.extend(settings, options);
return this.each(function() {
var tabs = window.$(this),
tab = tabs.find(settings.trigger),
tabSection = window.$(settings.target),
tabsSystemContainer = tabs.closest('div');
switch(settings.dir) {
case 'left':
tabsSystemContainer.removeClass(settings.dir || 'top').addClass('left' || settings.dir);
break;
default:
tabsSystemContainer.removeClass('left' || settings.dir).addClass(settings.dir || 'top');
}
//this where I'm having problems
tab.click(function(e) {
var self = window.$(this);
e.preventDefault();
window.alert('Hello, inside tab click event...');
});
});
};
}(window.jQuery));
window.$('.tabs').tabbs();
You have a syntax error on line 1:
(function(window.$) {
should read
(function($) {
You can use whichever jQuery (>= 1.6) you like: just embed the one you want, and in Optimizely's Settings -> jQuery Settings, select "Do not include jQuery in project code", and things will work just fine. Be sure you include your own jQuery before the Optimizely script tag, though.

Use jQuery to create edit in place div and have new div available for edit just beneath it

I'm new to jQuery and would like to know if it is possible to create and edit-in-place div that I can click on, type some text, have it save and immediately have another div dynamically pop up beneath it that will allow the same capability to type in and save, so on and so forth. If anyone has any ideas it would be greatly appreciated.
$(document).ready(function() {
$('.edit_area').editable(function(value, settings) {
return (value);
}, {
type: 'textarea',
onblur: 'submit',
indicator: 'Saving...',
callback: function(value, settings) {
var thisData = $(value);
$.post('<%=Url.Action("SetPostieNotes", "Posties") %>',
'postieNotes=' + escape(thisData)
);
var divTag = document.createElement("div");
divTag.id = "div";
divTag.setAttribute("align", "center");
divTag.className = "edit_area";
divTag.innerHTML = "Test Dynamic Div.";
document.body.appendChild(divTag);
}
});
});
Use jEditable for the edit-in-place functionality, and use it's callback functions to spawn the new div below the existing one.
You're not really using all that jEditable has to offer, try something like this (I am unable to test this right now but it should give you some ideas):
$(function() {
$('.edit_area').editable('<%=Url.Action("SetPostieNotes", "Posties") %>', {
callback: function(v, settings) {
var new_div = $('<div />')
.addClass('edit_area')
.editable('<%=Url.Action("SetPostieNotes", "Posties") %>', settings);
$(this).after(new_div);
}
});
});
That should be all there is to it. You don't need to do the submitting yourself, that's what jEditable is for. Just supply the URL you wish to save to as the first parameter, and settings as the second.
I actually started by using jEditable and moved on to tectual's editables() plugin instead
Here is the code i'm using https://github.com/relipse/jQuery-Editable/blob/master/jquery.editable.js

Categories