2

In my Joomla 3 component, i have a custom field that is a select list with multiple=true. The values of such an select list are binary handled like 1,2,4,8,16.
When storing, the values are getting added and stored as one value. When displaying the select field, the binary values are getting reassembled into an array.

All works in Joomla 3, but an Joomla 4 Select list with fancy layout or not is not displaying the selected values. The storage of the binary value works, but not the display.

I saw that list field source has changed in J4, but haven't found the issue for this.

<?php

defined('_JEXEC') or die;

use Joomla\CMS\Factory;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\CMS\Form\FormHelper;
use Joomla\CMS\Form\Field\ListField;

class JFormFieldBinaryselect extends ListField
{
    public $type = 'Binaryselect';
    protected static $options = array();

    protected function getOptions()
    {
        if ($this->value > 0) {
            // creates array from value like: 12 = [4,8]
            $this->value = MyHelper::getBinArray($this->value);
        }
        return parent::getOptions();
    }
}

2 Answers 2

0

Because in J4 List field rendering has changes i solved it by moving the value creation into the setup function:

public function setup(\SimpleXMLElement $element, $value, $group = null)
{
    $return = parent::setup($element, $value, $group);

    if ($this->value > 0) {
        $this->value = MyHelper::getBinArray($this->value);
    }

    return $return;
}
0

In Joomla4 you don't need the FormHelper::loadFieldClass() necessarily, just

use \Joomla\CMS\Form\Field\ListField;

class BinaryselectField extends ListField
{
     protected $type = 'Binaryselect';

     protected $layout = 'joomla.form.field.list';

     protected function getOptions()
     {
          $options = array();
          //then get your array of data and then merge
          $options = array_merge(parent::getOptions(), $options);
          return $options;
     }

 }

So once the field is defined, for multi selects you will need to manipulate the selections. In the Admin side - table file within the bind step:

public function bind($array, $ignore = '') 
{
    // to save multiple select type formfield items, json the submitted data for storing
    $array['bins'] = json_encode($array['bins']);

    return parent::bind($array, $ignore);
 }

So the above covers saving the selections into the database. Then to display the selected options when editing an existing record - in the admin side - model file getItem step:

public function getItem($pk = null)
{
    if ($item = parent::getItem($pk)) {

        //Do any procesing on fields here if needed before being displayed
        $item->bins = json_decode($item->bins);
        // continue with remainder of method

In the frontend form - in the model getData method:

    // decode the string to array
    $this->_item->bins = json_decode($this->_item->bins);

And if using the table to save data from the frontend, such as a simple publish method, don't forget to decode the json data:

public function publish($id, $state)
{
    $table = $this->getTable();
            
    $table->load($id);
    $table->state = $state;
    $table->bins = json_decode($table->bins);

    return $table->store();
            
}
1
  • OK, but how about the question?
    – maidan
    Commented Feb 23, 2022 at 19:31

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.