Creating a custom Form field type in Joomla sing the Modal Select example

Susan Sarandon
Release: 2024-11-17 10:18:03
Original
569 people have browsed it

Using the ModalSelect Form field type in Joomla 5 to simplify finding the right product, from thousands, by filtering in a modal window using category, manufacturer and search when developing an extension.

Intro

In the process of working with clients, there are tasks of various levels: someone needs a simple website of 5-6 pages. Someone needs a large catalog of goods or an online store with integrations with third-party systems using the REST API. Somebody else needs non-standard functionality for which there are no popular solutions available.

Joomla is good for development and allows you to create easily maintained code. If the requirement follows the CMS core then it has an answer for all these cases.

To complete a large project, we need to split it into smaller tasks, and I want to talk about solving one of these tasks in this article.

Initial data

Customers have already created a product catalog on one of the popular components of the online store for Joomla (JoomShopping). They can select the parameters of the product, put it in the cart and make a purchase. Everything is as usual. However, now you need to add the ability to create a graphic layout for products. For example, your product is a mug or a T-shirt. And before buying, you can go to the product designer, upload your logo or photo, write a text and this layout is attached to the order in the online store. After payment, the layout goes directly to production, where the image and text are applied to your mug and sent to the address.

Since implementation of this functionality is quite time consuming, it is created as a separate product designer component. And data provider plugins will already be created, allowing you to work with one or another e-commerce component.

One of the small, applied tasks is to create connections between the goods of the online store component and the goods in the product designer component. This should be convenient and intuitive for content managers who will work on the content in the future. Therefore, it is not enough just to make a text field where the id number of the desired product will be indicated. There may be only a few dozen products in an online store, and then choosing a product for communication is not very difficult. If there are thousands of products the functionality of searching and filtering products by parameters is important. If you can filter the list of products by category, manufacturer, or find it by name among hundreds of others, your work will be much faster and easier.

Creating a custom Form field type in Joomla sing the Modal Select example
See the video

This field is very similar to the work of the editor button plugins (editors-xtd group), where the data for selection is shown in the modal window: a link to the article, a short code for the module, etc.

A little theory

In the Joomla administrator panel, there are different fields that need to be filled with data from other components: specify the article, menu item, contact, product, etc. Usually such fields are designed as a select option drop-down list, they can be designed as input type="text" with a datalist, but there are also convenient fields showing a list of the desired entities, with filtering, search and pagination. Not only sources within the site (various components, plugins) can act as a data source, but also third-party services available via the REST API: CRM, delivery services, external databases, other Joomla sites, and so on.

We have all seen these fields in action when selecting an article in a menu item such as "Articles -Single article", "Contacts - Single contact", or when creating an alias of the menu item - "System links - Menu Item alias". However, let's remind ourselves what they look like.

A modal article selection window.

Creating a custom Form field type in Joomla sing the Modal Select example
A modal single contact selection window.

Creating a custom Form field type in Joomla sing the Modal Select example

The opportunities of the modal select field in Joomla

Let's take a closer look at these fields - what exactly they allow you to do. Somewhere deep inside, we understand that the main job of this field is to get the id of the selected entity and put this id in a text field. But on the screen we see something else - instead of an id number, we see the title of the article or contact. It's nice and convenient. You do not need to remember the name of the article with id 1452704. Also, the video clearly shows that if the field already has a value, the "clear" button appears. It resets the value of the field and allows you to click on the "select" button again.

Creating a custom Form field type in Joomla sing the Modal Select example

In some cases, we have the opportunity to create a selected type of entity - article, contact, etc. right in the process of creating a menu item. This button works taking into account the ACL - separation of access rights in Joomla.

Imagine you are building a website and creating a "Contacts" page. If you don't have a bunch of company branches with a complex structure, then this is just the usual Joomla article in the "Uncategorized" category. And it already has all the contacts in the form of text or of variables. In ancient times, you had to create the article first, and then go to the menu items and create a menu item for it. You don't have to do that now.

Creating a custom Form field type in Joomla sing the Modal Select example

And if the field already has a value, then in some cases it is possible to edit the selected entity (article, menu item, etc.) right in the process of creating a menu item.

So, using the selection field in the modal window, we can:

  • select
  • create
  • edit
  • clear

This is what's in front of my eyes. But in the depths of Joomla there is also a curious urlCheckin parameter that allows you to send the selected value to the url specified in the field. It is worth noting that this functionality in Joomla has been gradually developing for quite a long time. However, a separate universal field type that can be used for your needs appeared only in Joomla 5. It's not even in Joomla 4.

How are the fields of the Form constructor of the Joomla admin panel interface arranged?

Previously, this constructor was called JForm. I will assume that not all my readers have in their hands such a development tool as an IDE - development environment - a la PHP Storm or VS Code, so I will try to give additional guidelines for navigating the code base.

In Joomla, the Logic is separated from the View (the actual HTML output), so we will explore it in several places at the same time.

Logic is the Form class

Logic is the Form class. In Joomla 5, the Form class files are located in libraries/src/Form. We examine these files in order to understand the logic itself, what happens to the data and how to work with it.

Creating a custom Form field type in Joomla sing the Modal Select example

In short, the Form constructor receives XML with a description of the fields. reads data (field type, custom field class from the addfieldprefix attribute, if any, etc.), loads the required field class using FormHelper. If the field has some rules for filtering the output data - the FormRule class is used - remember the Joomla fields of the filelist type, where you can specify filtering parameters and select, for example, only php or only css files.

Joomla Form field class files are located in libraries/src/Form/Field. There are, to put it mildly, a lot of them. This is the building material of the admin panel, and sometimes the frontend too.

Creating a custom Form field type in Joomla sing the Modal Select example

Class files describe class properties such as $type, $layout, and others necessary for operation. Most fields have methods getInput() - actually returns the HTML output of the field, getLayoutData() - preprocessing data for the field before sending it to the render, getLabel() - working with the field label, etc.

We remember that the field classes inherit the parent FormField class. In the class file libraries/src/Form/FormField.php the possible attributes of the field are described, that can be used in the description in XML. They have a brief description of what it is and why.

Creating a custom Form field type in Joomla sing the Modal Select example
Child classes (heirs) have the ability to work with the methods of the parent class and, if necessary, override it.

Creating a custom Form field type in Joomla sing the Modal Select example

View (HTML output, layout) of a field in Joomla 5

Each field class has a HTML output. In classic MVC, the View works with data output immediately, but in Joomla there is an additional layer - Layout, which allows you to override layouts - one of the most important features of this CMS. The core layouts are expected to be located in the layouts folder in the site root. They pass an array of $displayData with all the data received from the getLayoutData() method. We specify which output layout to use in the $layout class property.

<?php
/**
 * Name of the layout being used to render the field
 *
 * @var    string
 * @since  3.7
 */
protected $layout = 'joomla.form.field.email';
Copy after login
Copy after login
Copy after login
Copy after login

This type of recording is quite common. In Joomla, layout is a dot-separated path to the layout file from the layouts folder at the root of the site. That is, the entry $layout = 'joomla.form.field.email' means that layouts will be used when rendering the field layouts/joomla/form/field/email.php.

<?php 
use Joomla\CMS\Layout\LayoutHelper;

$displayData = [
                'src' => $this->item->image,
                'alt' => $this->item->name,
               ];

echo LayoutHelper::render(
                        'joomla.html.image',
                         $displayData
                    );
Copy after login
Copy after login
Copy after login

Similarly, this example will use layout layouts/joomla/html/image.php. Some layouts can be overridden in the html folder of site templates and admin panel.

Accordingly, if we want to see exactly what data comes to the layout in the end and how it is displayed, go to the layout file and look.

Creating a data selection field in the Modal Select window in Joomla 5

Now let's return to the main task of the article.

Examples are important for us to study (Joomla 5.0.1 at the time of writing this article):

  • the main class of the field is libraries/src/Form/Field/ModalSelectField.php
  • the Joomla article modal select field - administrator/components/com_content/src/Field/Modal/ArticleField.php
  • menu type modal select field - administrator/components/com_menus/src/Field/MenutypeField.php
  • menu item modal select field - administrator/components/com_menus/src/Field/MenutypeField.php
  • output layout - layouts/joomla/form/field/modal-select.php

The single contact modal select field from com_contacts at the time of writing this article has not yet been converted to a universal field type one and just lies in (in Joomla 5.0.2, when this article was written) administrator/components/com_contact/src/Field/Modal/ContactField.php. It inherits FormField directly, not ModalSelectField.

The algorithm of actions for adding your own field is as follows:

  • create an XML form with our field in an xml file or programmatically using SimpleXMLElement.
  • If we work on the fly then, using the plugin for the onContentPrepareForm event, we add XML forms to the desired form (check $form->getName() before that)
  • Creating a field class.
  • If necessary, we create our own HTML output (layout) of the field. We will leave this out of the scope of this article. And it works. ## Field XML The most important thing in this code is the addfieldprefix attribute, which means the namespace of your field class. The class name is formed from addfieldprefix "" type "Field". In this case, the field class will be JoomlaPluginWtproductbuilderProviderjoomshoppingFieldProductlistField.
<?php
/**
 * Name of the layout being used to render the field
 *
 * @var    string
 * @since  3.7
 */
protected $layout = 'joomla.form.field.email';
Copy after login
Copy after login
Copy after login
Copy after login

HTML output (layout) of the field

In order for everything that happens in PHP to be clear, you need to first look at the layout of the field output. It is in the file layouts/joomla/form/field/modal-select.php. In fact, 2 input fields are output - one visible, the other invisible. The title of the selected article, contact, or product is entered in the visible field in the form of a placeholder - the $valueTitle parameter. And the second is his id - $value. If we have not selected anything yet, there should be a phrase in the field like "select an article" or "select a product". This is a language constant that we put in the hint attribute in the XML field or in the setup() method of the field class.

All parameters available for the output layout (which means those that can be used programmatically or in an XML file):

<?php
/**
 * Name of the layout being used to render the field
 *
 * @var    string
 * @since  3.7
 */
protected $layout = 'joomla.form.field.email';
Copy after login
Copy after login
Copy after login
Copy after login

PHP field class

The field class, as you may have guessed, is in my plugin. The way to it plugins/wtproductbuilder/providerjoomshopping/src/Field/ProductlistField.php. I took the single modal article select field as a basis and redesigned it to suit my needs - choosing a product from the JoomShopping online store. We extend the parent ModalSelectField class with our own class.

My tasks include only product selection, editing and creation are not, so in the text of the article we are talking only about product selection. The PHP class is small, I will give it in its entirety and comment on it.

<?php 
use Joomla\CMS\Layout\LayoutHelper;

$displayData = [
                'src' => $this->item->image,
                'alt' => $this->item->name,
               ];

echo LayoutHelper::render(
                        'joomla.html.image',
                         $displayData
                    );
Copy after login
Copy after login
Copy after login

Separately, the getValueTitle() method was introduced, which shows the name of the selected entity (product name, article title, etc.) in cases when they have already been selected and saved. That is, we went to edit the menu item, we do not touch the field, but we want to see the title of the article / product name understandable to people, and not just an id. This method shows the desired title.

<field
      type="productlist"
      name="product_id"
      addfieldprefix="Joomla\Plugin\Wtproductbuilder\Providerjoomshopping\Field"
      label="Field label"
      hint="Field placeholder"
      />
Copy after login
Copy after login

In some fields where more complex functionality is required - multilingual associations and so on - there are other methods in the field class that override the basic methods of the FormField class:

  • setLayoutData() is a method for preprocessing data before actually rendering the field
  • getRenderer() - additional parameters for rendering etc.

In our case, there is no such need, so we do not use them.

HTML output of the content of the modal window

When you click on the "select" button, a modal Bootstrap window opens, in which a list of products opens in the