HasFormType
The HasFormType trait provides a way to associate forms with type-based objects. It allows you to define forms per type and retrieve them, making it useful for building type-based form systems where different types have different form structures.
Namespace
JobMetric\Form\Typeify\HasFormType
Overview
The HasFormType trait is designed to work with objects that have a type property. It allows you to define forms for each type and retrieve them later. This is particularly useful for polymorphic relationships or type-based systems where different types require different form structures.
Requirements
The trait expects the class using it to have:
- A
$typeproperty that identifies the type - A
setTypeParam()method to store type parameters - A
getTypeParam()method to retrieve type parameters
Available Methods
Form
Set a form for the current type:
public function form(Closure|array $callable): static
Parameters:
$callable(Closure|array): A closure that receives aFormBuilderinstance, or an array of form configurations
Returns: static - Returns the instance for method chaining
Throws: InvalidArgumentException - If a form already exists for this type
Get Form
Get the form for the current type:
public function getForm(): ?Form
Returns: Form|null - The form instance for the current type, or null if not set
Get Form Custom Fields
Get all custom fields from the form for the current type:
public function getFormCustomFields(): Collection
Returns: Collection<int, CustomField> - Collection of custom field instances
Basic Usage
Setting Form with Closure
use JobMetric\Form\Typeify\HasFormType;
class ProductType
{
use HasFormType;
public string $type = 'physical';
public function __construct()
{
$this->form(function ($formBuilder) {
$formBuilder->action('/products')
->method('POST')
->tab(function ($tab) {
$tab->id('details')
->label('Product Details')
->group(function ($group) {
$group->label('Basic Info')
->customField(function ($field) {
$field->text()
->name('name')
->label('Product Name')
->build();
})
->build();
})
->build();
})
->build();
});
}
}
Getting Form
$productType = new ProductType();
$form = $productType->getForm();
if ($form) {
$html = $form->toHtml();
}
Getting Form Fields
$productType = new ProductType();
$fields = $productType->getFormCustomFields();
foreach ($fields as $field) {
echo $field->label . "\n";
}
Complete Examples
Type-Based Form System
use JobMetric\Form\Typeify\HasFormType;
abstract class ContentType
{
use HasFormType;
public string $type;
abstract public function defineForm(): void;
}
class ArticleType extends ContentType
{
public string $type = 'article';
public function __construct()
{
$this->defineForm();
}
public function defineForm(): void
{
$this->form(function ($formBuilder) {
$formBuilder->action('/content')
->method('POST')
->tab(function ($tab) {
$tab->id('content')
->label('Article Content')
->group(function ($group) {
$group->label('Article Details')
->customField(function ($field) {
$field->text()
->name('title')
->label('Title')
->required()
->build();
})
->customField(function ($field) {
$field->text()
->name('author')
->label('Author')
->build();
})
->build();
})
->build();
})
->build();
});
}
}
class VideoType extends ContentType
{
public string $type = 'video';
public function __construct()
{
$this->defineForm();
}
public function defineForm(): void
{
$this->form(function ($formBuilder) {
$formBuilder->action('/content')
->method('POST')
->enctype('multipart/form-data')
->tab(function ($tab) {
$tab->id('media')
->label('Video Media')
->group(function ($group) {
$group->label('Video Details')
->customField(function ($field) {
$field->text()
->name('title')
->label('Video Title')
->required()
->build();
})
->customField(function ($field) {
$field->image()
->name('video_file')
->label('Video File')
->required()
->build();
})
->build();
})
->build();
})
->build();
});
}
}
Using with Polymorphic Models
use JobMetric\Form\Typeify\HasFormType;
class FormTemplate
{
use HasFormType;
public string $type;
public function __construct(string $type)
{
$this->type = $type;
$this->defineForm();
}
protected function defineForm(): void
{
$formConfig = $this->getFormConfigForType($this->type);
$this->form(function ($formBuilder) use ($formConfig) {
$formBuilder->action($formConfig['action'])
->method($formConfig['method'])
->tab(function ($tab) use ($formConfig) {
foreach ($formConfig['tabs'] as $tabConfig) {
$tab->id($tabConfig['id'])
->label($tabConfig['label'])
->group(function ($group) use ($tabConfig) {
foreach ($tabConfig['groups'] as $groupConfig) {
$group->label($groupConfig['label'])
->customField(function ($field) use ($groupConfig) {
// Build fields from config
})
->build();
}
})
->build();
}
})
->build();
});
}
protected function getFormConfigForType(string $type): array
{
// Return form configuration based on type
return [];
}
}
When to Use HasFormType
Use the HasFormType trait when you need to:
- Type-Based Forms: Associate different forms with different types
- Polymorphic Forms: Handle forms for polymorphic relationships
- Dynamic Form Selection: Select forms based on object type
- Type-Specific Validation: Use different validation rules per type
- Form Templates: Create reusable form templates for different types