Unable to catch CKEditor change event - javascript

I looked through many threads at SO, but could not find an answer that solves my problem. So, I define a CKEditor instance like so:
var editor = $('#test-editor');
editor.ckeditor(function() {}, {
customConfig: '../../assets/js/custom/ckeditor_config.js',
allowedContent: true
});
However I do not know how can I catch change event. This is what I tried:
var t = editor.ckeditor(function() {
this.on('change', function () {
console.log("test 1");
});
}, {
customConfig: '../../assets/js/custom/ckeditor_config.js',
allowedContent: true
});
editor.on('change', function() {
console.log("test 2");
});
t.on('change', function() {
console.log("test 3");
});
All these three attempts ended in failure. I should add, that I do not want to loop through all editors on a page, I just want to address one particular editor rendered at component with #test-editor. How can I do that?

The jQuery ckeditor() method returns a jQuery object, which exposes only 5 events of CKEditor in its event handling. In order to use other events, you need to use the CKEditor.editor object by accessing the editor property of the jQuery object.
So, you need to use something like this:
var myeditor = $('#test-editor').ckeditor({
customConfig: '../../assets/js/custom/ckeditor_config.js',
allowedContent: true
});
myeditor.editor.on('change', function(evt) {
console.log('change detected');
});

Related

jQuery global/local event execution order

I have a panel widget with a button. Clicking the button should execute some global actions related to all such widgets and after that execute some local actions related to this widget instance only. Global actions are binded in a separate javascript file by CSS class like this:
var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
});
return {
init: function ()
{
handleWidgetButton();
}
};
}
}();
jQuery(document).ready(function()
{
App.init();
});
And in the html file local script is like this:
$("#widgetBtn1234").click(function (e)
{
// do smth local
});
Currently local script is executed first and global only after while I want it to be the opposite. I tried to wrap local one also with document.ready and have it run after global but that doesn't seem to change the execution order. Is there any decent way to arrange global and local jQuery bindings to the same element?
The problem you're having comes from using jQuery's .ready() function to initialize App, while you seem to have no such wrapper in your local code. Try the following instead:
var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
});
return {
init: function ()
{
handleWidgetButton();
}
};
}
}();
$(function()
{
App.init();
});
Then in your local JS:
$(function() {
$("#widgetBtn1234").click(function (e)
{
// do smth local
});
});
Note that $(function(){}) can be used as shorthand for $(document).ready(function(){});. Also, make sure your JS file is located before your local JS, as javascript runs sequentially.
Alternatively, you can use setTimeout() to ensure everything's loaded properly:
(function executeOnReady() {
setTimeout(function() {
// Set App.isInitialized = true in your App.init() function
if (App.isInitialized) runLocalJs();
// App.init() hasn't been called yet, so re-run this function
else executeOnReady();
}, 500);
})();
function runLocalJs() {
$("#widgetBtn1234").click(function (e)
{
// do smth local
});
};
How about this instead:
var widget = $("#widgetBtn1234").get(0);//get the vanilla dom element
var globalHandler = widget.onclick; //save old click handler
// clobber the old handler with a new handler, that calls the old handler when it's done
widget.onclick = function(e){
//do smth global by calling stored handler
globalHandler(e);
//afterward do smth local
};
There might be a more jqueryish way to write this, but I hope the concept works for you.
-------VVVV----keeping old answer for posterity----VVVV--------
Why not something like this?
var App = function ()
{
var handleWidgetButton = function ()
{
$('.widgetBtn').on('click', function (e)
{
// do smth global
if(this.id === 'widgetBtn1234'){
//do specific things for this one
}
});
return {
init: function ()
{
handleWidgetButton();
}
};
}
}();
Please excuse any syntax errors I might have made as I haven't actually tested this code.
Check out my simple JQ extension I created on jsbin.
http://jsbin.com/telofesevo/edit?js,console,output
It allows to call consequentially all defined personal click handlers after a global one, handle missed handlers case if necessary and easily reset all personal handlers.

how to pass parameter in jquery using .on?

Good Day, this maybe a silly question :) how can I pass a parameter to an external javascript function using .on ?
view:
<script>
var attachedPo = 0;
$this.ready(function(){
$('.chckboxPo').on('ifChecked', addPoToBill(attachedPo));
$('.chckboxPo').on('ifUnchecked', removePoToBill(attachedPo ));
});
</script>
external script:
function addPoToBill(attachedPo){
attachedPo++;
}
function removePoToBill(attachedPo){
attachedPo--;
}
but Im getting an error! thanks for guiding :)
You need to wrap your handlers in anonymous functions:
$('.chckboxPo')
.on('ifChecked', function() {
addPoToBill(attachedPo);
})
.on('ifUnchecked', function() {
removePoToBill(attachedPo);
});
You can also chain the calls to on as they are being attached to the same element.
If your intention is to count how many boxes are checked, via passing variable indirectly to functions try using an object instead like this:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/pBkhX/
var attachedPo = {
count: 0
};
$(function () {
$('.chckboxPo')
.on('change', function () {
if ($(this).is(':checked')) {
addPoToBill(attachedPo);
} else {
removePoToBill(attachedPo);
}
$("#output").prepend("" + attachedPo.count + "<br/>");
});
});
function addPoToBill(attachedPo) {
attachedPo.count++;
}
function removePoToBill(attachedPo) {
attachedPo.count--;
}
If it is not doing anything else you can simplify the whole thing to count checked checkboxes:
$(function () {
var attachedPo = 0;
$('.chckboxPo')
.on('change', function () {
attachedPo = $(".chckboxPo:checked").length;
});
});
"DOM Ready" events:
you also needed to wrap it in a ready handler like this instead of what you have now:
$(function(){
...
});
*Note: $(function(){YOUR CODE HERE}); is just a shortcut for $(document).ready(function(){YOUR CODE HERE});
You can also do the "safer version" (that ensures a locally scoped $) like this:
jQuery(function($){
...
});
This works because jQuery passes a reference to itself through as the first parameter when your "on load" anonymous function is called.
There are other variations to avoid conflicts with other libraries (not very common as most modern libs know to leave $ to jQuery nowadays). Just look up jQuery.noConflict to find out more.

call many functions on document change

I have few namespaces and I want to reinitialize function inside namespaces on document change in order to be reinitialized every time when the document is modified (*modified = adding/removing new sections on existing dom ).
I have tried this but not working so far:
;namespaceName= {
namespaceFunction1: function() {
$( selector ).on('click', function() {
//my first function run here
})
},
// ************second function in namespace***************/
namespaceFunction2: function() {
$(secondSelector).on('click', function() {
//my second function run here
})
}
}
$(document).on('change', namespaceName.namespaceFunction1() );
$(document).on('change', namespaceName.namespaceFunction2() );
Pls help, ty.
Try this...
$(document).on("DOMSubtreeModified", function () {
namespaceName.namespaceFunction1();
namespaceName.namespaceFunction2();
});
It fires your 2 functions on the DOMSubtreeModified event, which is basically what you were looking for - when the DOM changes.
sounds like you need to listen for the DOMSubtreeModified event like this:
$('body').bind('DOMSubtreeModified', function(){
//your code here
});

How do I override / extend a prototype.js class in a completely seperate .js file

I have a prototype.js class that I would like to extend to both add some new functions and override a couple of the functions already there.
in the example below I would like to add initAutocompleteNew and edit initAutocomplete to alert "new".
Varien.searchForm = Class.create();
Varien.searchForm.prototype = {
initialize : function(form, field, emptyText){
this.form = $(form);
this.field = $(field);
this.emptyText = emptyText;
Event.observe(this.form, 'submit', this.submit.bind(this));
Event.observe(this.field, 'focus', this.focus.bind(this));
Event.observe(this.field, 'blur', this.blur.bind(this));
this.blur();
},
//////more was here
initAutocomplete : function(url, destinationElement){
alert("old");
},
}
someone suggested but that doesn't work I think it's jQuery?
$.extend(obj_name.prototype, {
newfoo : function() { alert('hi #3'); }
}
This article should help out: http://prototypejs.org/learn/class-inheritance
It looks like you're defining your classes the 'old' way as described in the first example on that page. Are you using 1.7?
Assuming you are using 1.7, if you wanted to override or add methods to your class, you can use Class.addMethods:
Varien.searchForm.addMethods({
initAutocomplete: function(url, destinationElement) {
// Your new implementation
// This will override what was previously defined
alert('new');
},
someNewMethod: function() {
// This will add a new method, `someNewMethod`
alert('someNewMethod');
}
});
Here's a fiddle: http://jsfiddle.net/gqWDC/

Using unbind, I receive a Javascript TypeError: Object function has no method 'split'

I've written this code for a friend. The idea is he can add a "default" class to his textboxes, so that the default value will be grayed out, and then when he clicks it, it'll disappear, the text will return to its normal color, and then clicking a second time won't clear it:
$(document).ready(function() {
var textbox_click_handler = function clear_textbox() {
$(this).removeClass('default');
$(this).attr('value', '');
$(this).unbind(textbox_click_handler);
};
$(".default").mouseup(textbox_click_handler);
});
The clicking-to-clear works, but I get the following error:
Uncaught TypeError: Object function clear_textbox() { ... } has no method 'split'
what is causing this? How can I fix it? I would just add an anonymous function in the mouseup event, but I'm not sure how I would then unbind it -- I could just unbind everything, but I don't know if he'll want to add more functionality to it (probably not, but hey, he might want a little popup message to appear when certain textboxes are clicked, or something).
How can I fix it? What is the 'split' method for? I'm guessing it has to do with the unbind function, since the clearing works, but clicking a second time still clears it.
You can do it like this:
var textbox_click_handler = function(e) {
$(this).removeClass('default')
.attr('value', '')
.unbind(e.type, arguments.callee);
};
$(function() {
$(".default").mouseup(textbox_click_handler);
});
Or use the .one function instead that automatically unbinds the event:
$(function() {
$(".default").one('mouseup', function() {
$(this).removeClass('default').attr('value', '');
});
});
The unbind needs an event handler while you are specifying a function to its argument thereby giving you the error.
I am not sure if this is really different but try assigning the function to a variable:
var c = function clear_textbox() {
$(this).removeClass('default');
$(this).attr('value', '');
$(this).unbind('mouseup');
}
and then:
$(".default").mouseup(function(){
c();
});
if you don't want to completely unbind mouseup, check for the current state using hasClass(). No need to unbind anything.
$(document).ready(function() {
$('.default').bind('mouseup', function(e) {
var tb = $(this);
if(tb.hasClass('default')) {
tb.removeClass('default').val('');
}
});
});
Make sure you are unbinding mouseup:
function clear_textbox() {
$(this).removeClass('default');
$(this).attr('value', '');
$(this).unbind('mouseup');
}
$(function() {
$('.default').mouseup(clear_textbox);
});
Also I would write this as a plugin form:
(function($) {
$.fn.watermark = function(settings) {
this.each(function() {
$(this).css('color', 'gray');
$(this).mouseup(function() {
var $this = $(this);
$this.attr('value', '');
$this.unbind('mouseup');
});
});
return this;
};
})(jQuery);
so that your friend can simply:
$(function() {
$('.someClassYourFriendUses').watermark();
});

Categories

Resources