Working with Joomla Forms - Form Class
Form fields (like text, textarea, radio, select/list) are fields in a HTML <form> element. In Joomla, you can use the Form class to conveniently and flexibly create forms with a large amount of form fields. These form fields are defined in XML file.
For example, in the component the XML file is stored in the folder: forms/form_name.xml
1. Get Joomla Form Class
First, you need to get an instance of a form.
use Joomla\CMS\Factory;
use Joomla\CMS\Form\FormFactoryInterface;
$form = Factory::getContainer()->get(FormFactoryInterface::class)->createForm('myform', array('control' => 'jform'));
The above code creates a Form instance with the name "myform". An array with control as jform is also passed. The HTML input elements will have name attributes set to "jform[message]", "jform[email]", and so on.
2. Load XML File
Next, load in the XML file containing the form definition.
$form->loadFile(JPATH_SITE . '/components/com_example/forms/myform.xml');
Alternatively, you can create a SimpleXMLElement in your code and then call
$form->load($xml);
The Joomla code for loadFile() just reads the data from the file into a SimpleXMLElement variable and then calls load().
3. Provide Pre-fill Data
If the form is being used to edit a record in the database or you need to prefill user related information like name and email, you can provide values by setting up an associative array $data.
$form->bind($data);
4. Output the Form
1. To display or render the field (both label and input):
echo $form->renderField($field_name);
2. To display only input of the field:
echo $form->getInput('field_name');
This is a method to get a form field markup for the field input. It will not display the control group and label.
3. To display only label of the field:
echo $form->getLabel('field_name');
This is a method to get the label for a field input.
4. The XML form can have many field sets. Each field set can contain many fields. You can display or render complete field set.
echo $form->renderFieldset('fieldset_name');
5. Change Forms Dynamically
If you have defined your form statically in an XML file, then after it is loaded, you can modify it dynamically in the PHP code.
1. Add field set
To create a new fieldset dynamically, create a SimpleXMLElement and the load it to the form.
$xml = new \SimpleXMLElement('<form><fieldset name="query" label="Query"></fieldset></form>');
$form->load($xml);
2. Add fields
You can use setField() to add or replace a single field.
$element = '<field name="title" type="text" label="Title" />';
$xml = new \SimpleXMLElement($element);
$form->setField($xml, $group, $replace, $fieldset);
Specify the $group and $fieldset parameters to include the new field within a specific field group and fieldset. The default group is null and default fieldset is "default".
If the $replace flag is set to true, then the field will be set whether it already exists or not. If false, then the field will not be replaced if it already exists. The default value of replace is true.
3. Add multiple fields
You can use setFields() to add or replace several fields. you can define an array of XML elements and pass these to the setFields(), which is the equivalent of calling setField() on each of the individual elements.
4. Set field attributes
You can use setFieldAttribute() to set or amend an attribute associated with a field.
$form->setFieldAttribute('field_name', 'attribute_name', 'attribute_value');
This is a method to set an attribute value for a field XML element. Attribute refers to the Joomla field attribute, rather than the HTML attribute of the input element.
5. Set field value
The HTML value attribute is treated differently from other HTML attributes. You can use the bind() to set the value or directly using the setValue() method.
$form->setValue('field_name', null, 'field_value');
This is a method to set the value of a field. If the field does not exist in the form, then the method will return false. The second argument is for field group.
6. Remove field or group
You can remove fields from the Form by calling removeField() to remove a specific field or removeGroup() to remove all the fields within a specified field group.
$form->removeField('field_name');
You can remove any field by name before displaying the form.
6. Other Methods of Form Class
There are a number of methods which allow you to access various aspects of the Form.
1. Form Name
To get the name of the form:
echo $form->getName();
2. Form Control
To get the form control:
echo $form->getFormControl();
3. Form Data
The getData() returns the pre-fill data (as json string) which has been set using the Form bind() method.
echo $form->getData();
4. Field Attribute
To get the attribute value of any field from the Form object.
echo $form->getFieldAttribute('field_name', 'attribute_name');
You can also get the attribute from the FormField object.
5. Field set
To get all the fieldsets
$fieldsets = $form->getFieldsets();
This is a method to get an array of fieldset objects with properties which reflect the <fieldset> tag in the form definition file like name, label and description.
6. Fields
The methods getField(), getFieldset() and getGroup() return fields as Joomla FormField objects. Then, you can use FormField class methods. For example,
$fields = $form->getFieldset('fieldset_name');
Now, to display input or label or display control group with label and input:
foreach($fields as $field)
{
echo $field->input;
echo $field->label;
echo $field->renderField();
}
To get one field:
$field = $form->getField('field_name');
This is a method to get a form field represented as a FormField object. You can also access field attributes like $field->name, $field->label and so on.
7. Methods of FormField Class
You can use following methods after getting FormField objects using any of the getField(), getFieldset() and getGroup() methods.
1. Getter and Setter
To get or set the value of attributes and parameters:
echo $field->__get('attribute_name');
$field->__set('attribute_name', 'attribute_value');
2. Attribute value
To get attribute value from the XML field definition:
echo $field->getAttribute('attribute_name');
3. Display field
To display or render field (control group with label and input):
echo $field->renderField();
How To Create XML Form: myform.xml
Following is the example of XML form. You can add more fields in the fieldset or create new fieldset.
<?xml version="1.0" encoding="UTF-8"?>
<form class="form-validate">
<fieldset name="fieldset_name">
<field name="name" type="text" label="Name" />
</fieldset>
</form>
Display Form Using Loop
You can display multiple field sets using loops.
foreach ($form->getFieldsets() as $fieldset)
{
$fields = $form->getFieldset($fieldset->name);
if (count($fields))
{
foreach ($fields as $field)
{
echo $field->renderField();
}
}
}
You are not required to change the code even if the names of field set or names of fields changes.