Gazillion
Gazillion

Reputation: 4812

Accessing CKEditor Dialog HTML Elements

I'm having a tough time figuring out what I must do to access certain UI Elements in the CKEditor in a plugin I am modifying.

Essentially I am adding internal links to their link dialog where links I split up between sections and publications. When a user picks a section from a select drop down the publications from that section are populated in a different drop down.

The following code is being modified from the link.js file in the plugin folder. I cut out all the unnecessary bits and left out what I thought was relevant. As you can see in the code below I am defining a select dropdown with the id of 'section' followed by the 'item' dropdown. How do I access the 'item' dropdown, to populate it, in the onChange function of the section dropdown?

I have my ajax code all figured out and working if I hardcode the IDs that end up getting populated in the ID tag on runtime but this changes from editor to editor so I can't rely on hardcoded values.

{
 type :  'vbox',
 id : 'internalOptions',
 children :
 [
  {
   id : 'section',
   type : 'select',
   items :
   [
   ],
   setup : function( data )
   {
    //populate sections here
   },
   onChange : function (data)
   {
    //populate items here
   },
  },
  {
   id : 'item',
   type : 'select',
   items :
   [
   ],
   setup : function( data )
   {
   },
  }

 ]
}

EDIT: The problem I have is that the CKEditor will change every ID so they are unqiue. Though I name the dropdown "section" CKEditor calls it 176_section but it isn't always the same INT hence why I need to figure out how to grab it during the setup phase.

Upvotes: 7

Views: 15986

Answers (5)

Erik Melkersson
Erik Melkersson

Reputation: 1007

As AlfonsoML pointed to, the getContentElement is what you are looking for.

I'm adding some more code to complete it

You must know the id of the dialog page too. (It's outside your example code) I.e. the id of the "top" element in the relevant dialog page (your field may be on another page than the first if you have several pages in the dialog).

For example if the contents of the dialog js-file are:

...
contents : [
  {
    id : 'info',
    label : 'blabla',
    elements :
      ...

Then you use "info" as the dialog name.

In the local functions you may use the code:

var dialog = this.getDialog();
var sectionElement = dialog.getContentElement( 'info', 'section' );

The getContentElement in CKEditor is handling the translation between the names the the actual id.

Upvotes: 1

Andy Ford
Andy Ford

Reputation: 8490

The 'id' property is for internal reference in your javascript. It does not apply an id to the generated html element.

I've used a very hacky workaround that may or may not work in all situations, but the idea is you store a reference to the id that ckeditor automagically applies.

{
    id : 'txtCredit', /* not CSS ID attribute! */
    type : 'text',
    label : 'Credit',
    className : 'imageCredit',

    elemId : null, /* to store a reference to ckeditor's automagically generated id */

    setup : function() {

        // get the id that ckeditor generated for this element and store as an object property
        this.elemId = this.getInputElement().getAttribute('id');

        // now we can reference the element by the id we stored above. Hacky? Yeah probably
        var inputElem = document.getElementById(this.elemId);

    }
}

Upvotes: 4

simon
simon

Reputation: 63

I also find a solution. I changed the conctructor of the element type in /_source/core/dom/element.js

    CKEDITOR.dom.element = function( element, ownerDocument )
    {
        if ( typeof element == 'string' )
        element = ( ownerDocument ? ownerDocument.$ : document ).createElement(element );
    this.real_dom_element = element;
    // Call the base constructor (we must not call CKEDITOR.dom.node).
    CKEDITOR.dom.domObject.call( this, element );
};

Now, if you get a hold on the CKEDITOR.dom.element object you can just get the domElement by accessing object.real_dom_element

In the defenition of the UI elements you can add a onLoad function, you get the object.real_dom_element and add an attribute like this:

onLoad : function()
{
   $(this.getElement().blicsm_element).attr("myID", "link_url");
}

Later you can access the field like this (example with jQuery)

$('div[myID="link_url"]').find("input");

So you have 3 steps: 1. Change the CKEDITOR.dom.element constructor so you can access the real dom element 2. Add a onLoad event to the field you want to access later on and ad a custom attribute 3. Access the element by the custum attribute you've set in the onLoad

I did it like this and it works. Maybe there are simpler solutions, but I had a stuggle finding a solution, so I'm happy I found this.

Cheers

Upvotes: 0

AlfonsoML
AlfonsoML

Reputation: 12690

If you want to get the DOM object of an element in a CKEditor dialog you can use getElement on the CKEditor element.

And to get the CKEditor element, use getContentElement on the dialog

Upvotes: 6

Stephen
Stephen

Reputation: 18964

I know how you can grab #176_section using jQuery. If you only know section and not the prefix, try this selector:

Assuming the element is a select box:

$('select[id*="_section"]')

That will grab all select boxes that have an id that contains "_section".

Have a look at this: http://api.jquery.com/attribute-contains-selector/

If you aren't using jQuery, the vanilla javascript is a bit more verbose, but not too hard to grasp:

var selects = document.getElementsByTagName("select");
for (var i = 0; i < selects.length; i++) {
    if(selects[i].id.indexOf("_section")) {
        // Your select box is here.  Do something with it.
    }
}  

The latter method was modified from this answer: Getting elements by a partial id string in javascript

Upvotes: 0

Related Questions