CKEditor cannot get current instance from iframe - javascript

CKEditor 4 or above
I have form > textarea with CKEditor enabled and functioning.
I have iframe in modal dialog and inside iframe is button with insert_media() javascript function.
function insert_media( element ) {
// get element html decode
element = htmlspecialchars_decode( element, 'ENT_QUOTES' );
// htmlspecialchars_decode is external function.
// CKEditor insert element ---------------------------------------------
// use .insertElement()
var CKEDITOR = window.parent.CKEDITOR;
var element = CKEDITOR.dom.element.createFromHtml(element);
// body_value is name of textarea
// this code only works with specific textarea NOT current active textarea
//CKEDITOR.instances.body_value.insertElement(element);
var current_instance_ckeditor = window.parent.test_current();
// CKEditor insert element ---------------------------------------------
// close modal dialog at parent window
window.parent.close_dialog();
// done
return false;
}// insert_media
and this is javascript in main page html
function close_dialog() {
$('#media-modal').modal('hide');
}// close_dialog
function test_current() {
console.log( CKEDITOR.currentInstance.name );
}
The problem is i cannot get current active CKEditor to insert element with insertElement command.
CKEDITOR.currentInstance is undefined or null
window.parent.CKEDITOR.currentInstance is undefined or null
How to get current active CKEditor from iframe?
file for test: http://www.megafileupload.com/en/file/420060/test-ckeditor-zip.html

If CKEDITOR.currentInstance is null/undefined, then none editor instance is active. It means that you moved focus out of editor to the place which is not recognised as its part.
However, if you're using CKEditor's dialogs (do you?) editor instance should always be active, when this dialog is opened for it. If this is your case, then you need to provide us a working example, because it's hard to guess what can be wrong.
Second option is that you don't use CKEditor's dialogs and then you have to take care of registering that iframe to the CKEditor's focusManager, although this is tricky so you rather should not use 3rd party's dialogs with CKEditor.
Edit The test_current function works fine when I click "test" button, but editor has to be focused. But after 200ms from the moment you click button editor will be blurred and you won't be able to get it from currentInstance. To avoid blurring editor when clicking button you need to register it in focusManagers (of both editors if it will be used with both).

I'd do it like this
var ck_instance_name = false;
for ( var ck_instance in CKEDITOR.instances ){
if (CKEDITOR.instances[ck_instance].focusManager.hasFocus){
ck_instance_name = ck_instance;
return ck_instance_name;
}
}

CKEditor is null/undefined as Reinmar said.
Now i can find the way to work with current instance even if you clicked outside CKEditor.
Here is sample files for test.
http://www.megafileupload.com/en/file/448409/test-ckeditor-zip.html
What i do is ...
Add global variable for current instance in javascript (in html)
On click button for open modal dialog, get current instance and set to global variable in choice 1.
On click insert button in iframe in modal dialog, get window.parent.current_instance variable and use as texteditor id. (var parent_cke_current_id = window.parent.current_instance_id;)
Now do what ever you want with clicked CKEditor instance. for example (CKEDITOR.instances[parent_cke_current_id].insertElement(element);)
Thank you Reinmar.

Related

Jquery can't seem to target contents of modal

I wish to append some content within form within a modal and so have created:
$('.simple_form').append("<p><a href='google.com'>Apply now</a></p>");
However, this does not appear to work -the HTML above deosnt not append, not do I see any errors in the console.
I can do other stuff on the page - append the text anywhere else, just not to part of the modal.
The site is using the Near Me platform, an example site of which is here: https://desksnear.me/
I am just trying to affect the modal that appears when you click Log In at the top right.
Would anyone know why this isn't working and what I could do to get back on track?
I think the modal gets created anew every time you click the Log In button. So the .simple_form changes get overwritten before they can be seen.
There isn't an ideal solution to this problem if you can't tap into an event that occurs when the modal is opened and all the content in it has been initialized. I would suggest using an interval to repeatedly check if the modal is visible (for some capped amount of time, in case something fails), and then insert your HTML code at that point.
$('.nav-link.header-second').click(function() {
var token = setInterval(function(modal) {
if (modal.hasClass('visible')) {
$('.simple_form').append("<p><a href='google.com'>Apply now</a></p>")
clearInterval(token)
}
}, 10, $('.modal-content'))
// set a limit on the interval in case of failure
setTimeout(clearInterval, 2000, token)
})
Wrap it in document ready, the element must be there when the code executes(assuming you already have the element with class .simple_form as hidden)
$(document).ready(function(){
$('.simple_form').append("<p><a href='google.com'>Apply now</a></p>");
});

Finding if `body` tag has class on Pop-up Window

I have a webpage where you can blow up the content into a pop up window using window.open.
The pop-up will have a class on its body called pop-up. Important to note, both windows use the same JavaScript file where it handles the click events.
I want to know if I am clicking in the pop-up or in the main (parent) window. Since the HTML is going to be basically the same.
Here is how I am attempting to do this. I maintain a global variable of the last clicked element and this seems to work:
$(document).click(function(event) {
window.lastElementClicked = event.target;
g_lastClicked = window.lastElementClicked;
});
I know this is good because when I check the tagName of the last clicked element it is always correct.
Then when I want to check "Where Am I" I wanted to do this:
var fromPopup = $(g_lastClicked).closest("body").hasClass("pop-up"); // the line in question
alert(fromPopup);
if (fromPopup) {
// unrelated; I need a check to do resizing if I am in the pop-up
var height = $(window).height();
$("#cvApplication").height(height - 120);
}
So it will check the last element, traverse up the DOM to the body and see if it has the class. I get false every time in the above alert. Is my logic wrong? Or is there a completely different way I need to be doing this?
They're separate windows, there's no need to track an "active" element. Each window has its own copy of the script and its own variables, event handlers, etc.
All you need in your code is
if ($(document.body).hasClass("pop-up")) { // Without the . before pop-up
// This code is running in the pop-up
} else {
// This code is running in the main window
}
I haven't checked the rest of your code, but you do not use a . when checking if an element has a class.
var fromPopup = $(g_lastClicked).closest("body").hasClass(".pop-up");
should be
var fromPopup = $(g_lastClicked).closest("body").hasClass("pop-up");

how to interact with ckeditor, by catching and handling events

I am new to ckeditor, I have hard time figuring this issue out.
due to my html design; if I try to use the link editor dialog while my ckeditor is maximized, it just doesn't show up, I understand that ckeditor is the top most object in my html page and the link dialog comes underneath it. if now I bring ckeditor to its normal state I will be able to see and use the link dialog.
my idea is to slightly override the link button click event as follows:
if the editor is in full screen mode, bring it back to the normal state. and keep a flag somewhere so that when I close the link dialog, I can decide whether to bring back the ckeditor to a maximized mode again. now this is easy logic except that I do not know how to override the click event of the link button and keep it work as expected.
here's what I have:
$().ready(function () {
var editor = $('#txa').ckeditor();
CKEDITOR.plugins.registered['link']=
{
init : function( editor )
{
var command = editor.addCommand( 'link',
{
modes : { wysiwyg:1, source:1 },
exec : function( editor ) {
if(editor.commands.maximize.state == 1 ){
alert("maximized");
//....here bring back the editor to UN-maximized state and let the link button event click do the default behavior
}
else
{
alert("normal state");
}
//2 is normal state
//1 is maximized
}
}
);
editor.ui.addButton( 'link',{label : 'YOUR LABEL',command : 'link'});
}
}
});
html part to make the exemple work:
<div>
<textarea id="txa">
</textarea>
</div>
TO BE SHORT:
http://jsfiddle.net/Q43QP/
if the editor is maximized, bring it to normal state then show the link dialog.
Use editor.execCommand('maximize') to toggle the state of the editor window.
http://jsfiddle.net/Q43QP/2/

RadScheduler update interval

I'm using RadScheduler for my project. In the scheduler, I need a periodical update, so in my javascript, I set interval for a method that call rebind() on the RadScheduler for every 60 seconds. The problem is that, when my user open the advanced form, the rebind() method makes the form disappear. How can I detect AdvancedForm opening and closing event so that I can stop /restart the timer ?
Thank you in advance.
While there is an event for when the RadScheduler opens its Edit form, called OnClientFormCreated, there is not one for when the edit form closes. There are ways to do this though, but you have do add some additional code.
When you think about it there are several different items that can lead to the form closing - the user can click on the close icon at the top right (or left, depending on your orientation) of the window, they can click cancel, or they can hit save.
Keeping that in mind, we can take a look at this demo, which shows the Advanced Edit Form in action, and also has some JavaScript pre-written for us.
Within the schedulerFormCreated() function we can do the following:
function schedulerFormCreated(scheduler, eventArgs) {
// Create a client-side object only for the advanced templates
var mode = eventArgs.get_mode();
if (mode == Telerik.Web.UI.SchedulerFormMode.AdvancedInsert ||
mode == Telerik.Web.UI.SchedulerFormMode.AdvancedEdit) {
// Initialize the client-side object for the advanced form
var formElement = eventArgs.get_formElement();
var cancelButton = $("[id$='_CancelButton']");
cancelButton.on("click", formClosed);
var templateKey = scheduler.get_id() + "_" + mode;
....
And then we have the formClosed event:
function formClosed(eventArgs) {
}
in formClosed you can just create your logic for resuming the timer, while in schedulerFormCreated you can directly call the function that stops the timer right after that if-statement.
In case you're wondering what we're doing here we're simply grabbing an instance of the jQuery object representing the element with an id that ends with _CancelButton (we're not interested in the beginning part) and then just binding to the click event using the .on() jQuery function.
To get an instance of the save button you just have to use _UpdateButton, and for the close icon it is _AdvancedEditCloseButton. Keep in mind that any element that ends with these substrings will be selected, so if you want to be more specific I recommend inspecting the elements of your advanced form using FireBug or the Chrome Dev tools to get their ID and plug that into the selector above.
This should allow you to get the functionality you're looking for.

A few jQuery questions

First of all, here is the site I am working on.
I am trying to get a modal window to pop-up when elements in the Flash are clicked on. Which at this point I have about 90% working when you click on the warrior image. Below is a list of issues I am still trying to solve that I hope you can help me with...
The modal background doesn't fill up
the whole page like it should.
I cannot get the close button to work
I need to set the vidname variable in
both the Flash and Java to load in a
dynamic HTML file. Depending on which
image is clicked on. My naming
convention will probably be something
like vid-1.html, vid-2.html, etc.
If you need to look at the .js file you can view it at /cmsjs/jquery.ha.js
Below is the ActionScript I currently have...
var vidname = "modal.html";
peeps.vid1.onRelease = function() {
getURL('javascript:loadVid(\'' + vidname + '\');');
};
Well I have one for you.
Your current close code is
$('#modalBG, #modalClose').click(function(){
closeModal();
});
If you click the background after a video loads you'll see that the modal does close. The reason your close button does not work is because #modalClose does not exist in the DOM when you are binding to the click function.
You need to either rebind the modalClose element when you modify the DOM or use live. If you use live you just need to change your click code to this:
$('#modalBG, #modalClose').live("click", (function(){
closeModal();
});

Categories