1

I'm creating a small component with a search module. I will dumb this example down so that the question will be clear.

The component manages books. The book form XML looks like this and its structure CANNOT be changed:

<?xml version="1.0" encoding="utf-8"?>
<form>
    <fieldset addfieldpath="/administrator/components/com_books/models/fields">
        <field name="title" type="text" default="" />
        <field name="type" type="text" default="" />
        ...
        <fields name="specs">
            ...
            <field name="category" type="category" label="Category">
                <option value="">JSELECT</option>
            </field>
            ...
        </fields>
    </fieldset>
</form>      

The category field is a custom predefined list:

use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormHelper;

FormHelper::loadFieldClass('predefinedlist');

class JFormFieldCategory extends \JFormFieldPredefinedList
{
    public $type = 'Category';

    protected $predefinedOptions = array(
        '1' => 'Cat1',
        '2' => 'Cat2',
        '3' => 'Cat3',
        ...

    );
}

The component works fine (MVC) with selecting the category list and saving.

Now for the search module... I want to use a select filter in the module which is based on the category field.

What's the leanest way to do this? I don't want to repeat the category options. At the moment, I have this in the default.php of the module:

$value = Factory::getApplication()->input->getInt('category');
$bookform = Form::getInstance('com_books.book', 'book');
$bookform->setFieldAttribute('category', 'class', 'customclass', 'specs');
$bookform->setValue('category', 'specs', $value);
echo $bookform->getInput('category', 'specs', $value);

If I do this I get the following element:

<select id="specs_category" name="specs[category]" class="customclass">
    <option value="">JSELECT</option>
    <option value="1">Cat1</option>
    <option value="2">Cat2</option>
    <option value="3">Cat3</option>
    ...
</select>

But I don't want the group name inside. I know I can change the keying like this:

$bookform = Form::getInstance('com_books.book', 'book', array('control' => 'custom'));

<select id="specs_category" name="custom[category]" class="customclass">

But this is not working:

$bookform = Form::getInstance('com_books.book', 'book', array('control' => false));

What I need is this:

<select id="specs_category" name="category" class="customclass">

And please consider I cannot change the book XML structure as it is predefined for my work. Also this example is a bit dumbed down, so I cannot use custom fields.

I tried adding this to the custom category field

public function setup(\SimpleXMLElement $element, $value, $group = null)
{
    $result = parent::setup($element, $value, null); // the null removes the keying
    return $result;
}

That works, but the keying is needed when editing a book or when creating a menuitem, that uses this field as an option and the group params is needed.

I know I could get the HTML and fiddle around with a regex to remove the keying, but I'm sure that there is a better way.

  • Do you need the entire book form or just the category field in search module? – Sharky Sep 11 at 10:33
  • The book form has many elements that are based on custom fields like the one above. Some of them are also being used in creating menuoption filters. – Mike Sep 11 at 10:37
  • What's the problem with creating a search module's own XML file? You can use custom field classes from component, if that's what you're worried about. – Sharky Sep 11 at 13:04
  • The search module already has an XML file. Inside is an option for turning the category filter on and off. There is no need for choosing categories inside module options, only if the category filter should be used or not. – Mike Sep 11 at 13:10
0

So this is what I ended up doing:

$value = Factory::getApplication()->input->getInt('category');
$bookform = Form::getInstance('com_books.book', 'book');

$field = $bookform ->getField('category', 'specs');
$field->__set('group', null);
$field->__set('name', 'category');
$field->__set('class', 'customclass');
$field->setValue($value);

echo $field->renderField(array('customoption1' => true));

Would be nice to find a more lean solution if possible.

| improve this answer | |

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.