1

I created a custom form field. This field consists of multiple tabs that switch for every language that is installed to a separate WYSIWYG Editor field. So it's basically just multiple Editor fields in tabs.

The first tab is the Joomla default language. So far everything works fine, including saving in the model. The problem I have is that the editor XTD Buttons always refer only to the first editor field.
So when I switch the second tab and and insert a readmore element, it gets inserted in the first editor tab.

On the other hand, the Toggle Editor button is working correct for every editor inside a tab.

This has to do with the setup and initialisation of the editor fields, because at the moment only one editor instance seems to be there, but I cannot get the right solution.

ftype is only the attribute that tells the field what kind of field there is, because it can also be only a regular input field and not editor, but that is of no importance for this question.

Here are most important parts of the code:

Custom Field:

<?php

defined('JPATH_PLATFORM') or die;

use Joomla\CMS\Layout\FileLayout;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Field\EditorField;

class JFormFieldTabEditors extends EditorField
{
    public $type = 'TabEditors';    

    protected function getLayoutData()
    {
        $data = parent::getLayoutData();

        $asset      = $this->asset ? $this->asset : '';
        $height      = $this->element['height'] ? (string) $this->element['height'] : '500';
        $width       = $this->element['width'] ? (string) $this->element['width'] : '100%';
        $columns      = $this->columns ? ' cols="' . $this->columns . '"' : '';
        $rows         = $this->rows ? ' rows="' . $this->rows . '"' : '';
        $maxlength    = $this->maxlength ? ' maxlength="' . $this->maxlength . '"' : '';
        $buttons =  $this->buttons ? (is_array($this->buttons) ? array_merge($this->buttons, $this->hide) : $this->hide) : false;

        if (Factory::getApplication()->isClient('site')) {
            $class = $this->fclass;
        } else {
            $class =  'form-control ' . $this->bclass;
        }

        $extraData = array(
            'ftype'    => $this->ftype,
            'maxlength'    => $maxlength,
            'height'         => $height,
            'width'         => $width,
            'rows'         => $rows,
            'columns'      => $columns,
            'asset'      => $asset,
            'asset'      => $asset,
            'charcounter'  => $this->charcounter,
            'class' => $class,
            'buttons' => $buttons,
            'hide' => $this->hide,
            'authorField' => $this->form->getValue($this->authorField),
            'autofocus' => $this->autofocus,
            'readonly'  => $this->readonly || $this->disabled,
            'syntax'    => (string) $this->element['syntax'],
        );

        return array_merge($data, $extraData);
    }

    protected function getInput()
    {
        $data = $this->getLayoutData();
        if ($this->ftype == 'editor') {
            $editor = $this->getEditor();
            $data['editor'] = $editor;
        }

        $name = (string) $this->element['name'];
        $table = (string) $this->element['table'] ? (string) '_' . $this->element['table'] : '_lang';
        $index = (string) $this->element['index'] ? (string) $this->element['index'] : 'oid';
        $oid = Factory::getApplication()->input->getInt('id');

        $data['langs'] = array();
        if ($oid > 0) {
            $db    = Factory::getDbo();
            $query = $db->getQuery(true);
            $query->select('language,' . $name);
            $query->from($table);
            $query->where($index . ' = ' . $oid);
            $db->setQuery($query);
            $data['langs'] = $db->loadAssocList('language');
        }

        $layout = new FileLayout('TabEditors', JPATH_ROOT . '/libraries/mylib/layouts/joomla/form/field');

        return rtrim($layout->render($data), PHP_EOL);
    }
}

Layout

<?php

defined('JPATH_PLATFORM') or die;

extract($displayData);

$attributes = array(
    $columns ?: '',
    $rows ?: '',
    !empty($class) ? 'class="' . $class . ' ' . $charcounter . '"' : '',
    strlen($hint) ? 'placeholder="' . htmlspecialchars($hint, ENT_COMPAT, 'UTF-8') . '"' : '',
    $disabled ? 'disabled' : '',
    $readonly ? 'readonly' : '',
    $onchange ? 'onchange="' . $onchange . '"' : '',
    $onclick ? 'onclick="' . $onclick . '"' : '',
    $required ? 'required' : '',
    !empty($autocomplete) ? 'autocomplete="' . $autocomplete . '"' : '',
    $autofocus ? 'autofocus' : '',
    $spellcheck ? '' : 'spellcheck="false"',
    $maxlength ?: '',
    !empty($counterlabel) ? $counterlabel : '',
);
?>

<?php
preg_match_all("/\\[(.*?)\\]/", $name, $match);
$fieldname = end($match[1]);
$jlangs = MyHelperUtility::getLanguages();
$cfg = MyHelperConfig::getConfig();

if ($group) {
    $group = '[' . $group . ']';
}
?>

<ul id="langtab_<?php echo $id; ?>" class="uk-tab" uk-tab="connect: #lang_<?php echo $id; ?>">
    <?php foreach ($jlangs as $language) : ?>
        <li><a href="#"><?php echo $language->title_native; ?></a></li>
    <?php endforeach ?>
</ul>

<ul id="lang_<?php echo $id; ?>" class="uk-switcher">
<?php foreach ($jlangs as $language) : ?>
    <li>
        <?php if ($ftype == 'editor') : ?>
            <?php
            $params = array(
                'autofocus' => $autofocus,
                'readonly'  => $disabled,
                'syntax'    => $syntax,
            );
            if ($language->lang_code == $cfg->get('defaultlang')) {
                echo $editor->display(
                    $name,
                    htmlspecialchars($value, ENT_COMPAT, 'UTF-8'),
                    $width,
                    $height,
                    $columns,
                    $rows,
                    $buttons,
                    $id,
                    $asset,
                    $authorField,
                    $params
                );
            } else {
                echo $editor->display(
                    'jform[lang][' . $language->lang_code . ']' . $group . '[' . $fieldname . ']',
                    htmlspecialchars(@$langs[$language->lang_code][$fieldname], ENT_COMPAT, 'UTF-8'),
                    $width,
                    $height,
                    $columns,
                    $rows,
                    $buttons,
                    $id . strtolower($language->lang_code),
                    $asset,
                    $authorField,
                    $params
                );
            }
            ?>
        <?php endif ?>
    </li>
<?php endforeach ?>
</ul>

1 Answer 1

0

Yes, as you say, I think your problem is that you seem to have only 1 Editor instance, which you're displaying repeatedly. The xtd buttons are attached to the Editor class, and so because you have only 1 instance, you get only 1 set of buttons.

As an alternative approach I would suggest that rather than having 1 tabseditors field in the form which displays multiple editors that instead you have multiple editor fields in the form, 1 for each editor you need to display. I presume you don't know how many languages you have to support, so you'd have to add those editor fields to the form dynamically, based on how many languages you find in the database.

This is fairly straightforward - after you load the form, just set up the xml for each editor field you need and use

$form->load($xml);

Some info on dynamically changing forms is in this form api guide.

I tried putting 2 editor fields into 2 different tabs, and the xtd buttons worked ok on both, so it is definitely possible to get it working.

1
  • As far i see, this is an approach for the model using the form. I want to use the field type through multiple models and different and future forms. So the approach only must happen in the custom field TabEditors. Should work with $this->form->setField($xml); inside getInput. Will check if its is a way.
    – maidan
    Jun 5, 2023 at 18:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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