Multi-Forms (deprecated)
WARNING
Multi-Forms is a feature that has been deprecated in version 9.6.0 and was replaced by the Entity Map feature.
Let's say you want to handle different variants for an entity in one Entity List.
For instance, maybe you want to display sold cars on an Entity List: easy enough, you create a Car
entity, list and form. But you want to handle different form fields for cars with an internal combustion engine and those with an electric engine; you can of course use a form and conditional display to achieve this, but in a case where there are many differences, the best option may be to split the Entity in two (or more) Forms. That's Multi-Form.
Write the Form classes
Following up the car example, we would write two Form classes: CombustionCarForm
and ElectricCarForm
, maybe. They are regular SharpForm
classes, as described here.
TIP
Note that You'll probably be able to regroup some common code in a trait or by inheritance: it's up to you.
Configuration
Once the classes are written, you must declare the forms in the entity class:
class CarEntity extends SharpEntity
{
protected ?string $list = CarList::class;
protected string $label = 'Car';
public function getMultiforms(): array
{
return [
'combustion' => [\App\Sharp\CombustionCarForm::class, 'Combustion car'],
'electric' => [\App\Sharp\ElectricCarForm::class, 'Electric car'],
];
}
}
The expected return of the getMultiforms()
method is an array with:
- the subentity key as key: this is the value of the split attribute, to disambiguate each type (see below),
- and, as value, an array with the Form class and the subentity label.
At this stage, you need only one more thing: configure the Entity List to handle Multi-Form.
The Entity List
Now we want to "merge" our Car entity in the Entity List, and allow the user to create or edit either a combustion or an electric car. With the configuration added to the entity class, at the previous step, we already have a dropdown button replacing the "New" button, each value leading to the right Form.
You must configure an instance attribute to disambiguate each type: each instance must have his attribute valuated either with "electric" or "combustion", in our example.
You declare this attribute in the Entity List buildListConfig()
method:
class CarList extends SharpEntityList
{
// [...]
function buildListConfig(): void
{
$this->configureMultiformAttribute('engine');
}
}
Here, the engine
attribute must be filled for each Car instance. So how you do that? Obviously, the first way is to keep the same attribute you use in your database: in many cases, you already have this engine
value in a column. If not, or if the value is something less readable (an ID for instance), use a custom transformer:
class CarList extends SharpEntityList
{
// [...]
function getListData(): array
{
return $this
->setCustomTransformer('engine', function($value, Car $car) {
return $car->motor === 'EV' ? 'electric' : 'combustion';
})
->transform(Car::get());
}
}