CKEditor dialog event after page/tab is opened - javascript

I'm making a custom plugin for CKEditor (4.4.7), that extends default image plugin. Inside the plugin I need an event like "when the page/tab becomes visible".
I know about CKEDITOR.dialog's event selectPage. It fires before the actual page (tab) is shown. What I need is an event, that would fire AFTER the page is selected AND visible. I went throughout the docs, but I didn't find anything. Are there any workarounds?
(Not sure if it's not just my ignorance, but I think that ckeditor lacks more events, than just this one.)

Ok, so here is my ugly workaround (inside dialog on show):
I get the DOM id of a child element of the tab(page) using
var childElementId = dialog.getContentElement('tabCkeditorId', 'childElementCkeditorId').domId;
Using jquery I find the closest element with attribute name="tab/page ckeditor id", because I haven't found any way the ckeditor could tell me the DOM id of a tab/page element directly.
var tabId = $("#"+childElementId).closest('[name="tabCkeditorId"]').attr('id');
Well and finally:
$('body').on('mouseover focusin keydown', '#'+tabId, function(event) {
...
});
It is not a truly on page "changed" event, but for my cause it works.

By after page/tab opened, you mean the dialog box is opened, then you (as this is pretty old que) or anyone else trying to achieve this can use below,
editor.on( 'blur', function( dialogShowEvent ) {
alert('Test');
});
More can be found here - https://ckeditor.com/old/forums/Support/Blur-and-focus-fired-when-openingclosing-dialogs

Related

Detect any change in editor content - CKeditor 5, via javascript

I've looked at the CKEditor 5 documentation, but still can't work out how to get a simple javascript alert('hello') to fire when any balloon editor region is clicked on in my page. Any clues very much appreciated!
Okay, so the answer is actually very simple, just bind an on click event to the element, in this case via the CKEditor class, using JQuery as below:
$(document).on('click', '.ck-editor__editable_inline', function(e) {
// do something
})

Dojo dialog close event on X (top-right)

Im using Dojo to create a simple dialog to create a user in a system. The problem is I get the error:
Tried to register widget with `id==user_submit` but that `id` is already registered
user_submit, is a Dojo button I have to finish the form inside the dialog. When I close the dialog by clicking it and submitting the form there is no problem in opening the dialog again (in the click event on the button I have this line of code:
dijit.byId("user_submit").destroy();
but if I close the dialog through the [x]-link / button in the top-right corner I don't destroy the button and then can't open the dialog again without reloading the page.
How do I get Dojo to destroy the button or how to a overload the click-event on [X]-link / button, so I can write the destroy command for the button?
"Developer shouldn't override or connect to this method" for "onCancel" see documentation.
A better solution is:
var myDialog = new Dialog({
id: "myDialogId1",
onHide: function() {
myDialog.destroy()
}
});
Found a solution. by using dojo.connect().
myDialog.connect(myDialog, "hide", function(e){
dijit.byId("user_submit").destroy();
});
Would have postet this shortly after i posted the quistion, but I didn't have enough points, so here is the answer again, just a little late :-)
IIRC, the onClose extension event gets called when you click on the X thing, so you could try putting your cleanup code there.
You could also consider sidesteping the issue entirely. Perhaps you don't need to destroy the widget and could instead reuse the same one? You could also do a widget existence test before you create it again, destroying the old version if its still alive.
You can override onCancel() method as stated above or you can attach event to the
dijit.dialog.closeButtonNode domElement.
dijit.dialog.closeButtonNode is the name of data-dojo-attach-point attribute for close button.
Exp:
dojo.on(dijit.Dialog.closeButtonNode, "click", function(evt){
//add your logic here
});
When pressing the X on the top of the dialog the "onCancel" event is triggered.
Dispose of the element there.

tinyMCE textarea focusout event?

I am working on existing project. I have to detect tinyMCE focusout/blur event to save it automatically via AJAX. I found following existing working code:
// reinit tinymce
$($("#chapterBill div:.module-container")[indexAfter]).find('textarea').each(function(i){
editorId = $(this).attr('id');
tinymce.EditorManager.execCommand('mceAddControl',true, editorId);
});
Can someone tell me that how to capture tinyMCE textarea focusout/blur event ?
Thanks
You do not want to capture textarea focus/blur. Tinymce hides the former textarea and creates a contenteditable iframe in which you can enter/edit content. This content gets written to the former hidden textarea from time to time (eventbased).
In order to capture focusout/blur on the editor you need to set a handler for this on the editors iframe.
Put this code into your tinymce init
setup : function(ed) {
ed.onInit.add(function(ed, evt) {
tinymce.dom.Event.add(ed.getDoc(), 'blur', function(e) {
// Do something when the editor window is blured.
alert('blur!!!');
});
});
},
I too was working on a solution in order to save tinyMCE content dynamically via AJAX. Many answers instruct to set this option in the init, however this convenience was not available to me, due to the fact that the code was being used across several systems. I required a page specific solution, which I was able to implement like so:
$( window ).load(function(){
tinymce.get('id').on('blur', function(e) {
var content = tinymce.get('id');
console.log(content);
});
});
With id being the id attribute set on your textarea element.

Locating an element in a 'Facebox' box

Heres my link:
http://tinyurl.com/6j727e
If you click on the link in test.php, it opens in a modal box which is using the jquery 'facebox' script.
I'm trying to act upon a click event in this box, and if you view source of test.php you'll see where I'm trying to loacte the link within the modal box.
$('#facebox .hero-link').click(alert('click!'));
However, it doesn't detect a click and oddly enough the click event runs when the page loads.
The close button DOES however have a click event built in that closes the box, and I suspect my home-grown click event is being prevented somehow, but I can't figure it out.
Can anyone help? Typically its the very last part of a project and its holding me up, as is always the way ;)
First, the reason you're getting the alert on document load is because the #click method takes a function as an argument. Instead, you passed it the return value of alert, which immediately shows the alert dialog and returns null.
The reason the event binding isn't working is because at the time of document load, #facebox .hero-link does not yet exist. I think you have two options that will help you fix this.
Option 1) Bind the click event only after the facebox is revealed. Something like:
$(document).bind('reveal.facebox', function() {
$('#facebox .hero-link').click(function() { alert('click!'); });
});
Option 2) Look into using the jQuery Live Query Plugin
Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated.
jQuery Live Query will automatically bind the click event when it recognizes that Facebox modified the DOM. You should then only need to write this:
$('#facebox .hero-link').click(function() { alert('click!'); });
Alternatively use event delegation
This basically hooks events to containers rather than every element and queries the event.target in the container event.
It has multiple benefits in that you reduce the code noise (no need to rebind) it also is easier on browser memory (less events bound in the dom)
Quick example here
jQuery plugin for easy event delegation
P.S event delegation is pencilled to be in the next release (1.3) coming very soon.

Checking to see if a DOM element has focus

I've got a lightbox textbox that is displayed using an AJAX call from an ASP.NET UpdatePanel. When the lightbox is displayed, I use the focus() method of a textbox that is in the lightbox to bring focus to the textbox right away.
When in Firefox, the text box gains focus with no problem. In IE, the text box does not gain focus unless I use
setTimeout(function(){txtBx.focus()}, 500);
to make the focus method fire slightly later, after the DOM element has been loaded I'm assuming.
The problem is, immediately above that line, I'm already checking to see if the element is null/undefined, so the object already should exist if it hits that line, it just won't allow itself to gain focus right away for some reason.
Obviously setting a timer to "fix" this problem isn't the best or most elegant way to solve this. I'd like to be able to do something like the following:
var txtBx = document.getElementById('txtBx');
if (txtPassword != null) {
txtPassword.focus();
while (txtPassword.focus === false) {
txtPassword.focus();
}
}
Is there any way to tell that a text box has focus so I could do something like above?
Or am I looking at this the wrong way?
Edit
To clarify, I'm not calling the code on page load. The script is at the top of the page, however it is inside of a function that is called when ASP.NET's Asynchronous postback is complete, not when the page loads.
Because this is displayed after an Ajax update, the DOM should already be loaded, so I'm assuming that jQuery's $(document).ready() event won't be helpful here.
Try putting the javascript that sets focus at the end of the page instead of the beginning or having it fire after the page loaded event. That will help ensure that the DOM is completely loaded before setting focus.
I've used FastInit for this. JQuery $(document).ready() would also work.
You can try this:
Use the endRequest event of the PageRequestManager. That event fires once an Ajax update has finished.
Focus the textbox in the event handler
Here is some sample code:
<script type="text/javascript">
function onRequestEnd()
{
var txtBx = $get('txtBx');
txtBx.focus();
}
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onRequestEnd);
</script>
To focus the textbox initially you can use the pageLoad function (shortcut to the load event of the Application client-side object):
<script type="text/javascript">
function pageLoad()
{
var txtBx = $get('txtBx');
txtBx.focus();
}
</script>
you could try something like this [IE Specific]. (untested)
theAjaxCreatedElement.onreadystatechange = function() {
if ( this.readyState != "complete" )
return;
this.focus();
};
Another way might be to change the background color of the element with onfocus, then retrieve it with js check if it is what it should be, if not: refocus the element.
It seems that IE does not update the DOM until after the script has finished running. Thus, a loop testing for focus will not allow the DOM to update. Using setTimeout is probably the only working solution.
Your example with .focus() is a well known example, see e.g. this answer.
Have you tried adding the autofocus="autofocus" attribute to the textbox element you are calling via Ajax?
Normally, when I need certain additional JavaScript functionality to run on dynamic content, I'll simply add that JavaScript to the content being called as well.
That JavaScript will also execute after it's added to the DOM. I don't see a point in writing JavaScript to your parent file and then "listening" for changes to the DOM. Like you mentioned, setTimeout() is more of a hack than anything else for something like this :)
There are several things in IE, that does the trick:
If focusing element has different z-index - you can quickly set z-index to that of currently focused element (possibly setting hidden attribute), set focus, and then set it back to original z-index.
Try to blur() currently focused element.
If element is 'shimmed' - focus the 'shim' element.

Categories

Resources