Add developer documentation for building configurable quick forms.

This commit is contained in:
Michael Stenta 2023-03-13 09:36:05 -04:00
parent de8a262685
commit a8f7081601
1 changed files with 219 additions and 0 deletions

View File

@ -222,6 +222,225 @@ Available traits and the methods that they provide include:
given a name and vocabulary. If the term does not exist, a new term will be
created.
## Configurable quick forms
A "configurable" quick form is one that allows users to change how the quick
form behaves, by providing settings and a configuration form for customizing
them.
To make an existing quick form configurable:
1. Add `implements ConfigurableQuickFormInterface` to the quick form's class
definition. This indicates to farmOS that the quick form is configurable,
builds a router item for the configuration form, adds it to the UI, etc.
2. Add `use ConfigurableQuickFormTrait` to the quick form's class definition.
This adds default methods required by the `ConfigurableQuickFormInterface`.
3. Add a `defaultConfiguration()` method that returns an array of default
configuration values.
4. Add a `buildConfigurationForm()` method that builds a configuration form
with form items for each of the properties defined in
`defaultConfiguration()`.
5. Add a `submitConfigurationForm()` method that processes submitted values and
assigns configuration to `$this->configuration`.
6. Add a `config/schema/[mymodule].schema.yml` file that describes the
[configuration schema/metatdata](https://www.drupal.org/docs/drupal-apis/configuration-api/configuration-schemametadata).
The following is the same "Harvest" example as above, with the new interface
and methods, followed by the schema file that describes the settings.
```php
<?php
namespace Drupal\farm_quick_harvest\Plugin\QuickForm;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\Core\Form\FormStateInterface;
use Drupal\farm_quick\Plugin\QuickForm\ConfigurableQuickFormInterface;
use Drupal\farm_quick\Plugin\QuickForm\QuickFormBase;
use Drupal\farm_quick\Traits\ConfigurableQuickFormTrait;
use Drupal\farm_quick\Traits\QuickLogTrait;
/**
* Harvest quick form.
*
* @QuickForm(
* id = "harvest",
* label = @Translation("Harvest"),
* description = @Translation("Record when a harvest takes place."),
* helpText = @Translation("Use this form to record a harvest."),
* permissions = {
* "create harvest log",
* }
* )
*/
class Harvest extends QuickFormBase implements ConfigurableQuickFormInterface {
use ConfigurableQuickFormTrait;
use QuickLogTrait;
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'default_quantity' => 100,
];
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, string $id = NULL) {
// Date+time selection field (defaults to now).
$form['timestamp'] = [
'#type' => 'datetime',
'#title' => $this->t('Date'),
'#default_value' => new DrupalDateTime('now', \Drupal::currentUser()->getTimeZone()),
'#required' => TRUE,
];
// Asset reference field (allow multiple).
$form['asset'] = [
'#type' => 'entity_autocomplete',
'#title' => $this->t('Assets'),
'#target_type' => 'asset',
'#tags' => TRUE,
];
// Harvest quantity field.
$form['quantity'] = [
'#type' => 'number',
'#title' => $this->t('Quantity'),
'#required' => TRUE,
'#default_value' => $this->configuration['default_quantity'],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// Draft a harvest log from the user-submitted data.
$timestamp = $form_state->getValue('timestamp')->getTimestamp();
$asset = $form_state->getValue('asset');
$quantity = $form_state->getValue('quantity');
$log = [
'type' => 'harvest',
'timestamp' => $timestamp,
'asset' => $asset,
'quantity' => [
[
'type' => 'standard',
'value' => $quantity,
],
],
'status' => 'done',
];
// Create the log.
$this->createLog($log);
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
// Default quantity configuration.
$form['default_quantity'] = [
'#type' => 'number',
'#title' => $this->t('Default quantity'),
'#default_value' => $this->configuration['default_quantity'],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
$this->configuration['default_quantity'] = $form_state->getValue('default_quantity');
}
}
```
`config/schema/farm_quick_harvest.schema.yml`:
```yaml
farm_quick.settings.harvest:
type: quick_form_settings
label: 'Harvest quick form settings'
mapping:
default_quantity:
type: integer
label: 'Default quantity'
```
### Methods
The `ConfigurableQuickFormTrait` class add all the necessary methods required
by `ConfigurableQuickFormInterface` (which is used to designate a quick form as
"configurable"). Child classes can override these methods to customize their
behavior. At a minimum, most configurable quick form classes should override
`defaultConfiguration()`, `buildConfigurationForm()`, and
`submitConfigurationForm()`.
Available methods include:
- `defaultConfiguration()` - Provide an array of default configuration values.
- `buildConfigurationForm()` - Build the configuration form as an array using
[Drupal Form API](https://www.drupal.org/docs/drupal-apis/form-api/introduction-to-form-api).
- `validateConfigurationForm()` - Perform validation on the user input.
- `submitConfigurationForm()` - Perform logic when the form is submitted to
prepare the quick form configuration entity. This will not run if validation
fails.
## Quick form configuration entities
Each quick form that is displayed to the user in farmOS is represented as a
[configuration entity](https://www.drupal.org/docs/drupal-apis/entity-api/configuration-entity).
Each configuration entity specifies which quick form plugin it uses (aka which
PHP class that extends from `QuickFormBase`), along with other information like
label, description, help text, and configuration settings (used by configurable
quick forms).
However, if a configuration entity is not saved, farmOS will try to provide a
"default instance" of the quick form plugin. From a module developer's
perspective, this means that the module does not need to provide any config
entity YML files in `config/install`. It can rely on farmOS's default quick
form instance logic to show the quick form.
In the case of configurable quick forms, a config entity will be automatically
created when the user modifies the quick form's configuration and submits the
configuration form.
Quick form configuration entities can also be used to override defaults,
including the label, description, and help text. They can also be used to
disable a quick form entirely by setting the config entity's `status` to
false.
If multiple configuration entities are provided for the same plugin, multiple
quick forms will be displayed in the UI. This is useful if you want to create
a set of similar quick forms with pre-set configuration options.
### Disable default instance
In some cases, a plugin may not want a "default instance" to be created.
Instead, they may want to require that a quick form configuration entity be
explicitly created. For example, if a plugin requires configuration settings,
but there isn't a sensible default for that configuration and user input is
required, a "default instance" may not be possible.
In that case, the plugin can add `requiresEntity = True` to its annotation,
which will tell farmOS not to create a default instance of the quick form.
The quick form will only be made available if a configuration entity is saved.
## Quick form actions
farmOS provides lists of logs and assets throughout its interface. Many of