1

For a new Project i would like to have an editor instance inside a modal popup (click on an object to add / edit details). I have my Custom Field that loads an editor like so:

$editor = JEditor::getInstance(Factory::getConfig()->get('editor'));
    $name = $id = 'marker-description';
    $contents ='';
    $width = '100%';
    $height='100px';
    $cols = 5;
    $rows = 10;
    $buttons=true;
    $asset = $author = null;
    $params = array();

    $modalEditor = $editor->display($name, $contents, $width, $height, $cols, $rows, $buttons, $id, $asset, $author, $params);

Then in the modal i'll add the editor to the echo, this part works fine and the editor is shown to. But you cannot write in some text. Only when disabling the editor (button below) you can enter some text into the given field. But this text is also not visible.

I came across my researches about this question here that is JCE related but i think the "issue" is the same. https://www.joomlacontenteditor.net/support/forum/105386-jce-in-uikit3-modal-not-focus-editable-in-editor-mode

I've tried to add the given js code based on my structure:

jQuery(document).ready(function($){
console.log('JQuery ready');
UIkit.util.on('#marker-modal', 'show', function () {
    console.log('Modal shown');
    $(document).trigger('subform-row-sort', '#marker-modal');
});
});

All events got fired well but i'm not sure what this "subform-row-sort" will do.

This is the structure of the echo:

$modal = '<div id="marker-modal" class="uk-modal-container uk-flex-top" uk-modal>'.
                '<div class="uk-modal-dialog">'.
                    '<div class="uk-modal-body">'.
                        '<button class="uk-modal-close-default" type="button" uk-close></button>'.
                        '<h2 class="uk-modal-title">Edit Marker Data</h2>'.
                        '<form id="modal-form">'.
                            '<input class="uk-input" id="marker-label" type="text" placeholder="'.Text::_('MOD_MAPS_MARKERLABEL').'" />'.
                            '<span>'.Text::_('MOD_MAPS_MARKERDES').'</span>'.
                            $modalEditor.
                        '</form>'.
                    '</div>'.
                    '<div class="uk-modal-footer">'.
                        '<div class="uk-grid uk-child-width-auto uk-flex-right">'.
                            '<div><div class="uk-button nxd-button-success uk-modal-close">'.Text::_('MOD_MAPS_SAVECLOSE').'</div></div>'.
                            '<div><div class="uk-button nxd-button-danger uk-modal-close">'.Text::_('MOD_MAPS_CANCEL').'</div></div>'.
                        '</div>'.
                    '</div>'.
                '</div>'.
            '</div>';

What i've seen so far is that the form tag (#modal-form) not got rendered. Idk if this could be a problem related to the given js solution... Modal with console open

0
2

I duplicated your scenario (using the TinyMCE editor which is the base of JCE editor too) and it looks like for me that the toggleEditor() function is "handling" this interesting behavior within the Modal for the editor (as it is placing the editor in the document body when invoked, but that is only a half solution here). Thus, this script solved this problem for me partially.

<script>
  UIkit.util.on('#marker-modal', 'show', function() {
    
    tinyMCE.execCommand('mceToggleEditor', false, 'marker_description');
    Joomla.JoomlaTinyMCE.setupEditors();
  });
</script>

UPDATE:

I just had a short extra time to check this with the JCE editor and - as expected - the above only works with TinyMCE editor. So, if I can I'll be check this for JCE further...

UPDATE ON Loading JCE OR TinyMCE editor into a modal

Investigating this issue a bit more it has become obvious that the problem is that when you try to load/display an editor field in a Modal in a usual way, it will be placed inside an IFrame, and the Document head and body are going to be empty. Thus scripts will not find the editor and the editor will not be initialized and set active fully.

Solution: The editor must be loaded via JavaScript (I prefer vanilla JavaScript for doing this) and not only loaded but loaded into the body of the document. The key point is that it should be appended to a parent HTML element which is already in the body (this way we will avoid IFrame and empty document head/body). Actually this is the only key of this problem and of course there could be few different ways to solve this. So, the steps:

1. Based on the editor field definition in the question, let's create a function which return the Editor field for our JavaScript loader:

use \Joomla\CMS\Factory;
use \Joomla\CMS\Editor\Editor;

$modalEditor = function () {
  $conf = Factory::getConfig();
  $editor_name = $conf->get('editor');

  $editor = Editor::getInstance($editor_name);

  $name = $id = 'markers_markerdescription';
  $contents = '';
  $width = '100%';
  $height = '100px';
  $cols = 5;
  $rows = 10;
  $buttons = true;
  $asset = $author = null;
  $params = array();

  return json_encode($editor->display($name, $contents, $width, $height, $cols, $rows, $buttons, $id, $asset, $author, $params));
};

2. I just added an empty div element to the given HTML UIKit Modal layout (within the Form) (I did not want to append that one with javascript...)

So the UIkit based Modal with the added <div id="neweditor">:

<div id="marker-modal" class="uk-modal-container uk-flex-top" uk-modal>
  <div class="uk-modal-dialog">
    <div class="uk-modal-body">
      <button class="uk-modal-close-default" type="button" uk-close></button>
      <h2 class="uk-modal-title">Edit Marker Data</h2>
      <form id="modal-form">
        <input class="uk-input" id="marker-label" type="text" placeholder=" <?php Text::_('MOD_MAPS_MARKERLABEL'); ?> " />
        <span> <?php Text::_('MOD_MAPS_MARKERDES'); ?> </span>
        <div id="neweditor">

        </div>
      </form>
    </div>
    <div class="uk-modal-footer">
      <div class="uk-grid uk-child-width-auto uk-flex-right">
        <div>
          <div class="uk-button nxd-button-success uk-modal-close"> <?php Text::_('MOD_MAPS_SAVECLOSE'); ?> </div>
        </div>
        <div>
          <div class="uk-button nxd-button-danger uk-modal-close"> <?php Text::_('MOD_MAPS_CANCEL'); ?> </div>
        </div>
      </div>
    </div>
  </div>
</div>

Then I created the script which helps to load the editor in the Modal and initialize it, and it could be Joomla TinyMCE or JCE editor.

<script>
UIkit.util.on('#marker-modal', 'show', function() {
  if (typeof tinyMCE !== "undefined" && Joomla.JoomlaTinyMCE !== undefined) {
      console.log('Joomla core TinyMCE editor is used');
      if (document.getElementById('ed_loaded1') === null) {
          let editorDiv = document.createElement('div');
          editorDiv.setAttribute('id', 'ed_loaded1');
          let parDiv = document.getElementById('neweditor');
          parDiv.appendChild(editorDiv);
          editorDiv.innerHTML = <?php echo $modalEditor(); ?>;
          Joomla.JoomlaTinyMCE.setupEditors();
      }
  } else if (document.getElementById('ed_loaded1') === null && typeof tinyMCE !== "undefined") {
      console.log('It is a jce editor');
      addJceEditor();
  } else {
      console.log('You should set TinyMCE or JCE editor in Global configuration ');
      return;
  };
});

function addJceEditor() {
    let editorDiv = document.createElement('div');
    editorDiv.setAttribute('id', 'ed_loaded1');
    let parDiv = document.getElementById('neweditor');
    parDiv.appendChild(editorDiv);
    editorDiv.innerHTML = <?php echo $modalEditor(); ?>;
    let settings = tinymce.settings;
    var ed = new tinymce.Editor('markers_markerdescription', settings);
    ed.render();
    return;
}
</script>

Please be aware that I renamed your editor field to $name = $id = 'markers_markerdescription'; in my code. The selector should be modified if needed everywhere in the code.

The above script checks which editor is loaded, also checks if the Editor was already created and initialized (just to avoid endless duplication of editors in the Modal).

I focused only to solve this in short amount of time, so the code could be improved here and there of course, I wanted to keep this more or less readable, understandable with deliberately not using shorted "coding stunts"

And finally, I would recommend to create Form fields in a Joomla standard way using an XML file for defining a Form and Fields and that is actually much shorter way of doing these jobs. Like defining this editor field in an XML would look something like this:

<?xml version="1.0" encoding="utf-8"?>
<form>
    <fieldset name="making">
        <fields name="markers" label="COM_MYCOMPONENT_FIELD_LABEL">
            <field  
                name="markerdescription" 
                buttons ="true"
                type="editor" 
                label="Edit Marker Data" 
                description="" 
                width="500"
                editor="desired|alternative"
                filter="safehtml"
            />
        </fields>
    </fieldset>
</form>

And you could also load this editor Form field with about 4 lines of code anywhere in Joomla (loading this into a Modal requires JavaScript too of course).

I hope that the above will work fine for you too.

2
  • 1
    That's amazing. Thank you for your help / time solving this - I've learned a lot today
    – Marco
    Aug 5 at 4:03
  • @Marco - Great, thank you for the feedback!
    – Zollie
    Aug 5 at 5:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.