Decorator – jak předat Form::onClick[] službu s parametrem @self když je to formulář?

m.brecher
Generous Backer | 863
+
0
-

Ahoj,

Mám utilitku která nastaví každému formuláři v aplikaci nějaké css classy:

class FormUtils
{
    public function normalizeFormClasses(Form $form): void
    {
        foreach ($form->getComponents(deep: true) as $component){
            $class = match($component->getOption('type')){
                'text' => 'text-input',         // TextInput
                'textarea' => 'text-area',      // TextArea
                'select' => 'select-input',     // SelectBox, MultiSelectBox
 				.........
            };

			.......

            $component->setHtmlAttribute('class', $class);
        }
    }

Formulář pak nevykresluji DefaultRendererem z Nette, ale přes vlastní šablonu Latte.

Nyní musím $formUtils->normalizeFormClasses() spouštět ručně v každém formuláři:

class UserFormFactory
{
    public function __construct(
        private FormUtils $formUtils,
    )
    {}

    public function create(): Form
    {
        $form = new Form;

       .......  // přidání prvků formuláře

        $form->onRender[] = $this->formUtils->normalizeFormClasses(...);  // ruční spouštění

        return $form;
    }

Chtěl bych to nastavit v konfiguraci na jednom místě pro všechny formuláře. Formuláře ale nejsou služby, ale komponenty. Takže podle očekávání tohle nefunguje – common.neon:

decorator:
	Nette\Application\UI\Form:
		setup:
			- '$onRender[]' = @App\Utils\FormUtils::normalizeFormClasses(...)

ani tohle – common.neon:

decorator:
	Nette\Application\UI\Form:
		setup:
			- '$onRender[]' = [@App\Utils\FormUtils, normalizeFormClasses]

Je možné toto v konfiguraci nějak vyřešit?

Editoval m.brecher (6. 10. 2022 3:50)

Pepino
Člen | 256
+
+3
-

Můžeš udělat továrnu na formuláře.

class FormFactory
{
    public function __construct(
        private FormUtils $formUtils,
    )
    {}

    public function create(): Form
    {
        $form = new Form;
        $form->onRender[] = $this->formUtils->normalizeFormClasses(...);
        return $form;
    }
}

A formuláře pak vytvářet:

class UserFormFactory
{
    public function __construct(
        private FormFactory $formFactory,
    )
    {}

    public function create(): Form
    {
        $form = $this->formFactory->create();

        .......  // přidání prvků formuláře

        return $form;
    }
}
m.brecher
Generous Backer | 863
+
0
-

@Pepino díky za tip, ano, to je správná cesta, to řeší všechny problémy.