Vytvoření vlastního typu pole
Krom připravených typů formulářových polí si můžete samozřejmě vytvořit své vlastní pole - vlastní typ, nebo lepší implementaci pro již existující typ. Jedinou podmínkou je použití dědičnosti. Každé formulářové pole (respektive jeho třída) musí dědit od třídy Jet\Form_Field. Vaše třídy tedy musí dědit od uvedené třídy, ale samozřejmě mohou dědit od libovolné již existující třídy. Prostě standardní objektově orientované programovaní ❤️
Pozor na jednu důležitou věc. Pokud používáte automatické generování formulářů mapovaných na třídy a chcete vaší novou třídu (nebo celý nový typ) použít i pro tyto formuláře, tak musíte dát vědět příslušné továrně že existuje nový typ, nebo že daný existující typ pole reprezentuje nová třída.
Nová implementace existujícího typu formulářového pole
Jak bylo řečeno, tak stačí vytvořit novou třídu, která může dědit od stávající třídy reprezentující daný typ formulářového pole:
namespace JetApplication;
POZOR! Je nutné předat informaci továrně. Volání továren je nutné umístit do inicializace aplikace. Tedy do skriptu ~/application/Init/Factory.php
use Jet\Form;
use Jet\Form_Field_Tel;
class MyForm_Field_Tel extends Form_Field_Tel {
//.. ... ..
}
use Jet\Factory_Form;
Factory_Form::setFieldClassName( Form::TYPE_TEL, MyForm_Field_Tel::class );
Zcela nový typ pole
Nyní pojďme vytvořit novou třídu a především úplně nový typ pole. Třída může mít implementované vlastní metody pro zachytávání a validaci (a případně libovolné další metody). Důležité je, že její vlastnost $_type musí informovat o tom jaký typ formulářového pole představuje. S touto informací se totiž bude operovat i dále. Je dobré si pro typ vytvořit novou konstantu. Zde je pro ukázku použita imaginární konstanta MyForm::MY_NEW_FIELD_TYPE.
namespace JetApplication;
use Jet\Form;
use Jet\Form_Field;
use Jet\Data_Array;
class MyForm_Field_NewType extends Form_Field
{
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
protected string $_type = MyForm::MY_NEW_FIELD_TYPE;
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public function catchInput( Data_Array $data ): void
{
//... ... ...
}
public function validate(): bool
{
//... ... ...
}
public function getRequiredErrorCodes(): array
{
//... ...
}
}
Třídu tedy máme. Ale ještě je nutné udělat několik věcí:
- Zaregistrovat nový typ / novou třídu do továrny formuláře. (jinak by typ nemohl být použit například pro automaticky generované formuláře).
- Zaregistrovat jaké renderery bude pro nový typ pole použit.
- Zaregistrovat jaké view skripty budou pro daný typ použity.
Registrace typu do továrny
Registraci typu do továrny provedeme takto:
use Jet\Factory_Form;
Factory_Form::setFieldClassName( MyForm::MY_NEW_FIELD_TYPE, MyForm_Field_NewType::class );
POZOR! Volání továren je nutné umístit do inicializace aplikace. Tedy do skriptu ~/application/Init/Factory.php.
Registrace rendererů
Nyní je nutné továrně říct jaké renderery budou pro nový typ pole použity.
Opět budeme pracovat s továrnou, tedy ve skriptu ~/application/Init/Factory.php
Kompletní volání může mít tuto podobu:
Factory_Form::setRendererFieldClassName( MyForm::MY_NEW_FIELD_TYPE, 'field', Form_Renderer_Field::class );
Uff ... To je ale poněkud zdlouhavé volání. Ovšem je dobré si jej pro představu a úplnost ukázat.
Factory_Form::setRendererFieldClassName( MyForm::MY_NEW_FIELD_TYPE, 'container',Form_Renderer_Field_Container::class );
Factory_Form::setRendererFieldClassName( MyForm::MY_NEW_FIELD_TYPE, 'error', Form_Renderer_Field_Error::class );
Factory_Form::setRendererFieldClassName( MyForm::MY_NEW_FIELD_TYPE, 'help', Form_Renderer_Field_Help::class );
Factory_Form::setRendererFieldClassName( MyForm::MY_NEW_FIELD_TYPE, 'input', Form_Renderer_Field_Input_Common::class );
Factory_Form::setRendererFieldClassName( MyForm::MY_NEW_FIELD_TYPE, 'label', Form_Renderer_Field_Label::class );
Factory_Form::setRendererFieldClassName( MyForm::MY_NEW_FIELD_TYPE, 'row', Form_Renderer_Field_Row::class );
Ukažme si ale praktičtější volání, která nahradí vše co jsme si do teď ukázali a provede vše potřebné.
Factory_Form::registerNewFieldType(
Tento kus kódu provede vše potřebné - takto se reálně a jednoduše registruje nový typ. Jiná volání nejsou nutná! Tato metoda zaregistruje třídu i renderery pro nový typ. Všimněte si prosím, že v seznamů elementů a rendererů je uveden pouze element input. Pokud chcete pro ostatní elementy použít výchozí renderery, tak není nutné je uvádět a budou doplněny výchozí hodnoty.
field_type: MyForm::MY_NEW_FIELD_TYPE,
field_class_name: MyForm_Field_NewType::class,
renderers: [
'input' => MyForm_Renderer_Field_Input_Special::class
]
);
Záměrně jsme si ukázali oba způsoby, i když praktičtější je určitě ten druhý.
Registrace view skriptů
Poslední co nám zbývá je říct systému jaké výchozí view skripty bude nový typ pole mít. To musíme dát vědět systémové konfiguraci.
Pro pořádek je dobré udělat to také ve skriptu ~/application/Init/Factory.php
Princip je stejný jako u registrace rendererů a také je možné použít volání několika metod pro každé view zvlášť, ale tím vás již zde trápit nebudu a rovnou si ukažme optimální způsob jak to udělat:
SysConf_Jet_Form_DefaultViews::registerNewFieldType(
Jak je vidět, tak i zde není nutné vyjmenovávat všechna view, ale pouze tak, která chcete mít nastavena jinak než jsou výchozí hodnoty systému.
field_type: MyForm::MY_NEW_FIELD_TYPE,
views: [
'input' => 'field/input/my-special'
'label' => 'field/label-my-special'
]
);
Tedy celá registrace nového typu má ve finále tuto podobu:
namespace JetApplication;
use Jet\Factory_Form;
use Jet\SysConf_Jet_Form_DefaultViews;
Factory_Form::registerNewFieldType(
field_type: MyForm::MY_NEW_FIELD_TYPE,
field_class_name: MyForm_Field_NewType::class,
renderers: [
'input' => MyForm_Renderer_Field_Input_Special::class
]
);
SysConf_Jet_Form_DefaultViews::registerNewFieldType(
field_type: MyForm::MY_NEW_FIELD_TYPE,
views: [
'input' => 'field/input/my-special'
]
);
Nový parametr vašeho formulářového pole
Obecný princip vytvoření nového typu pole již znáte, ale vraťme se ještě jednou na začátek. Uvedený příklad zatím počítal pouze s tím, že budete mít vlastní implementaci zachycení dat a validace.
Ale to u složitějších typů polí zdaleka nemusí stačit. V reálném světě budete potřebovat aby nový typ pole měl i své parametry. Podobně jako u číselných typů lze určit rozmezí od - do, u souborů povolené typy nahrávaných souborů a tak dále. Viz typy formulářových polí.
V podstatě je to jednoduché. Prostě přidáte třídě představující typ formulářového pole potřebnou vlastnost, getter a setter a pochopitelně implementujete logiku použití daného parametru - zejména při validaci. Ano, takto to stačí a bude to fungovat.
Ovšem pokud jste si již zkoušeli Jet Studio, tak jste nalezli nástroj na mapování formulářů na třídy. A pokud budete chtít aby tento nástroj znal i váš nový typ formulářového pole, tak jej musíte správně zaregistrovat. Ale nejen to, musíte i definovat parametry vašeho nového pole. Tak aby například Jet Studio poznalo že se jedná o parametr formuláře a umělo s ním pracovat (tedy aby bylo možné "naklikávat" i váš nový vstupní element).
Jak to udělat? Dát vlastnosti, která představuje nový parametr, příslušné atributy. Rovnou si ukažme reálný příklad přímo z Jet. Tento trait se používát pro číselná formulářová pole, kde může figurovat rozsah platných číselných hodnot:
namespace Jet;
trait Form_Field_Part_NumberRangeInt_Trait
{
#[Form_Definition_FieldOption(
type: Form_Definition_FieldOption::TYPE_INT,
label: 'Minimal value',
getter: 'getMinValue',
setter: 'setMinValue',
)]
protected ?int $min_value = null;
#[Form_Definition_FieldOption(
type: Form_Definition_FieldOption::TYPE_INT,
label: 'Maximal value',
getter: 'getMaxValue',
setter: 'setMaxValue',
)]
protected ?int $max_value = null;
#[Form_Definition_FieldOption(
type: Form_Definition_FieldOption::TYPE_INT,
label: 'Step',
getter: 'getStep',
setter: 'setStep',
)]
protected ?int $step = null;
// ... ... ...
}
Jak vidíte, tak k definici slouží atributy a je to poměrně triviální definice.
Parametry definice
Parametr | Význam |
---|---|
type | O jaký typ se jedná. Seznam typů viz dále. |
label | Popis parametru. Popis je určen pro nástroj jako je Jet Studio. |
setter | Název metody - setteru v rámci třídy představující formulářové pole, pomocí kterého lze parametr nastavit. |
getter | Název metody - getteru v rámci třídy představující formulářové pole, pomocí kterého lze zjistit nastavenou hodnotu parametru. |
Typy parametrů
Typ | Význam |
---|---|
Form_Definition_FieldOption::TYPE_STRING | Hodnota typu string |
Form_Definition_FieldOption::TYPE_INT | Hodnota typu int |
Form_Definition_FieldOption::TYPE_FLOAT | Hodnota typu float |
Form_Definition_FieldOption::TYPE_BOOL | Hodnota typu bool |
Form_Definition_FieldOption::TYPE_CALLABLE | Volání - fakticky pole o dvou pozicích. První pozice (index 0) může být:
|
Form_Definition_FieldOption::TYPE_ARRAY | Prosté pole. |
Form_Definition_FieldOption::TYPE_ASSOC_ARRAY | Asociované pole. |