Listen on ckeditor widget events - javascript

I have tried to extend the simple box widget tutorial
(http://docs.ckeditor.com/#!/guide/widget_sdk_tutorial_1) with some events but I don't really get it.
One of my goals is to trigger an event if an editable (eg. the simplebox-title) field within the widget get focused.
But unfortunately I'm only able to listen if the widget itself get focused:
editor.widgets.add('simplebox', {
// definitions for
// button, template, etc
init: function() {
this.on('focus', function(ev){
console.log('focused this');
});
}
});
or if the data is changed:
CKEDITOR.plugins.add('simplebox', {
// my plugin code
init: function (editor) {
editor.widgets.on( 'instanceCreated', function( evt ) {
var widget = evt.data;
widget.on('data', function(evt){
console.log("data changed");
});
});
}
//even more code
});
How do I listen to editable fields within widgets?
Another challenge for me is to fire an event if the widget is removed. Maybe someone also know how to listen to this event too?

How do I listen to editable fields within widgets?
There are no events for editable fields within widgets. They behave like the main editable, so when you change something in them the editor#change event is fired.
Another challenge for me is to fire an event if the widget is removed.
There's the widget#destroy event, but you will not find it very useful. The reason is that widgets are not always destroyed as you delete them because there are many ways to do so.
If you pressed backspace while having a widget selected, then yes - this event is fired, because deletion is made directly on the widget. However, it is fired after the widget was deleted.
If you select the entire content of editor and press backspace, then the browser deletes it, because the browser handles this key in this case. Therefore, CKEditor implements a small garbage collector which checks from time to time which widget instances were removed and destroys them. You can increase the frequency by calling editor.widgets.checkWidgtes() more often - e.g. on editor#change, but it won't change anything. In both cases the event is fired after the widget is deleted.

Related

Populate selectize.js field without triggering item_add event

How do you selectize.addItem("value") without triggering item_add?
I have a tags field that’s dependent on another selection. I need to automatically fill in tags whenever that other selection is changed, and then I need to have a listener run code whenever the user adds or removes a tag. I can’t figure out how to add the tags programmatically without triggering the item_add event, but I don’t want it triggering before the user’s even touched the tags.
(There is addItem(…, silent), but unless I’m mistaken, that only stops it from triggering the change event.)
Sample code:
$('#input-tags').selectize({
onItemAdd: function() {
alert("This should only appear by user action");
}
});
$tags = $('#input-tags')[0].selectize;
$tags.addItem("awesome");
$tags.addItem("neat");
JSFiddle
One solution (and the only one I know of) is to remove the event listeners before the addItems and add them back afterwards. That hardly seems ideal, though, especially if it needs to be done more than once.
You can convert your code to register the add callback after adding all initial values:
$('#input-tags').selectize();
$tags = $('#input-tags')[0].selectize;
$tags.addItem("awesome");
$tags.addItem("neat");
// Register the listener once you have initialized the selectize component.
$tags.on('item_add', function() {
alert("This should only appear by user action");
});

What event should be used for handling drag and drop of rows in dojo dgrid?

I have a dojo dgrid with DnD support. I want to handle the event when user drags and drops rows of the grid. I was not able to find a list of all events that are supported by dgrid.
I am able to work with other events listed in the Working with Events section such as
grid.on('.dgrid-header .dgrid-cell:click', function (event) {}
however, I cannot find the name of the event to be used for drag&drop.
What is the name of this event?
As mentioned in the link shared by you (Working with Events section), dgrid does not have any events related to dnd.
However, the dndSource which is extension of dojo/dnd/source has a set of event which you can use to listen.
on(grid1.dndSource, "Drop", function(){
//do something
});
You could also use the dojo/topic to listen to some of the topics published by the dnd.Manager.
topic.subscribe("/dnd/drop", function(){
//do something
});
Below are the list of topic you can listen:
/dnd/source/over
/dnd/start
/dnd/drop/before
/dnd/drop
/dnd/cancel

How to listen for widget selection in CKEditor?

I'm adding custom widget via CKEDITOR.instances[editorId].insertHtml() (inside angular app),
and I need to react to widget selection, possibly deselection.
I see that widget fires events such as select, deselect, focus and blur but I can't find out how to set listeners on each widget.
Could this be done inside of plugin's init function?
Thanks
You can either listen to this directly or indirectly.
The direct listener will need to use the widget.repository#instanceCreated event to be able to listen on widget#blur event on all created widgets:
editor.widgets.on( 'instanceCreated', function( evt ) {
var widget = evt.data;
// You can check at this point whether you want to observe this kind of widget
// e.g. check widget.name.
widget.on( 'blur', function() {
// Fired when widget is deselected.
} );
} );
The indirect method will use the editor#selectionChange event to observe selection changes and widget.repository.focused property to check which widget is now selected (or not):
var lastFocused = null;
editor.on( 'selectionChange', function() {
if ( lastFocused && lastFocused !== editor.widgets.focused ) {
// The lastFocused widget just lost focus.
}
lastFocused = editor.widgets.focused;
} );
Both methods are ok for most cases. First may consume slightly more memory if you expect bazillion of widgets :D.
BTW. Widget can be both focused and selected. The difference is that multiple widgets can be selected at one time, while only one can be focused (then it has that blue outline). In most cases you'll be interested in the focused widget.

Synchronising browser events in JS

This is a bit of an abstract question, but I've been pondering its usefulness, and maybe it's either already been solved or inspires someone to do something based on it.
Well recently I ran across an issue whereby three browser events were fired, all as the result of a single user interaction: click, blur and focus. When the user clicks from one input to another, these events occur; and a similar set occur when the user tabs from one to another.
The trouble I had was that they fired in this order: blur, focus, click. It meant that, if the blur event caused DOM changes, the click event could be affected. I really wanted click, blur, focus - but that's not what the browser gave me.
I figured a general utility could be produced, capturing and cancelling browser events, then synchronising them and firing a single handler for all three. Perhaps extending the Event class so that the event could be reinstated.
Is there a more abstract design pattern I can use here? Something that will allow me to set up an arbitrary number of event listeners, and then fire a single event when all are complete? Does it have an implementation already? All advice welcome.
Dont need to break head around this! you can always trigger these events Programmatically
Note: object referenced here is any element selected using javascript selector.
Initially onBlur & onFocus do event.preventDefault which allows onClick to do its job first
var clicked=false;
object.onblur = function(e) {
if (!clicked) {
e.preventDefault
}
};
object.onfocus = function(e) {
if (!clicked) {
e.preventDefault
}
};
inside click event undo the above preventions and trigger the events in the order you wanted
object.onclick=function(){
clicked=true;
//Do anything
object.unbind('blur'); //this do undo prevent default
object.unbind('focus'); //this do undo prevent default
object.blur(); //in order you want
object.focus();
//make sure to put condition if click clicked
};
Thats it ! Hope it helps

How to call JS to click a table element

Assume I get a table element with ID="emTab", how do I call JS to click it?
Thanks.
document.getElementById("emTab").onclick = function() {
// your code goes here
};
See element.onclick
To trigger click event
document.getElementById("emTab").click();
See element.click
The click method is intended to be
used with INPUT elements of type
button, checkbox, radio, reset or
submit. Gecko does not implement the
click method on other elements that
might be expected to respond to
mouse–clicks such as links (A
elements), nor will it necessarily
fire the click event of other
elements.
Non–Gecko DOMs may behave differently.
When a click is used with elements
that support it (e.g. one of the INPUT
types listed above), it also fires the
element's click event which will
bubble up to elements higher up the
document tree (or event chain) and
fire their click events too. However,
bubbling of a click event will not
cause an A element to initiate
navigation as if a real mouse-click
had been received.
Cross browser way
If you can use jQuery then it would be
$("#emTab").trigger("click");
Firing events cross-browser - http://jehiah.cz/archive/firing-javascript-events-properly
its simple using JQuery
$('#emTab').click(functionToCall);
while in JS
document.getElementById('emTab').onclick = function() {};
for details on DOM events:
http://www.howtocreate.co.uk/tutorials/javascript/domevents

Categories