Získat tyl položky ve formuláři – selectbox

vosy
Člen | 525
+
0
-

Ahoj nedaří se mi v šabloně získat nějaký typ „$input->getControl()->type“ pro select box.
No vyjádření hrozný ale :)

<form n:name=$form class="{$prefix}-form {ifset $class}{$class}{/ifset}">

    {foreach $form->controls as $key=>$input}
		{var $button = $input->getControl()->type == 'submit'}
        {var $checkbox = $input->controlPrototype->type == 'checkbox'}

potřeboval bych zjistit že daný $input je selectbox

nightfish
Člen | 468
+
+4
-

@vosy {var $isSelectbox = $input instanceof Nette\Forms\Controls\SelectBox}

m.brecher
Generous Backer | 717
+
-1
-

Ahoj!

Prvky Nette formulářů mají string property type přístupnou přes metodu getOption(‚type‘), takže praktičtější než na to jít oklikou přes $input->getControl()->type, který např. pro select nefunguje je použít:

<form n:name=$form class="{$prefix}-form {ifset $class}{$class}{/ifset}">

    {foreach $form->controls as $key=>$input}
		{var $button = $input->getOption('type') === 'submit'}  // důležité !! NIKDY nepoužívat ==, vždy ===
        {var $checkbox = $input->getOption('type') === 'checkbox'}
        {var $select = $input->getOption('type') === 'select'}
m.brecher
Generous Backer | 717
+
-3
-

Tak mě napadá, že použití $input->getOption(‚type‘) jsem někde zahlédl v ukázce kódu někde na githubu a že v oficiální dokumentaci to není, ale jistý si nejsem. Budeme muset dokumentaci dokompletovat o různé zajímavé funkce a feature, které v Nette jsou, ale nejsou popsané a tak je nováčci nemohou použít (nejen nováčci, ale i @nightfish ). Ono to tam možná někde bude, ale asi zastrčené uvnitř textu, nebo to tam vůbec není. Do dokumentace to doplním. Ať je tato šikovná fičura k dispozici celé komunitě Nette ;). Ono se s $input->getOption(‚type‘) pracuje daleko lépe než instanceof, můžeme použít in_array(), match(), fqn třídy je zbytečně dlouhé.

Marek Bartoš
Nette Blogger | 1146
+
0
-

controls jsou typu Nette\Forms\Control, která žádnou metodu getOption() nemá. Ve většině případů bude fungovat, ale ne vždy.

m.brecher
Generous Backer | 717
+
0
-

Marek Bartoš napsal(a):

controls jsou typu Nette\Forms\Control, která žádnou metodu getOption() nemá. Ve většině případů bude fungovat, ale ne vždy.

No tak jsme narazili na to, že existuje legitimní potřeba mít v controls formuláře property type, kterou bychom využili v logice vykreslování, aby se nemuselo používat těžkopádné instanceof, která by měla oficiální podporu ve VŠECH controls formuláře. getOption() ale funguje a já ho v obecné šabloně pro vykreslení formuláře používám, protože nic lepšího v Nette formulářích jsem nebyl schopen najít, nepoužívám ale úplně všechny control formuláře, takže možná máš pravdu.

Nemáš náhodou představu, které prvky formuláře getOption() nepodporují?

Pokud některé ne, mělo by se to do kódu doplnit, popř. ideální by bylo mít kvalitní metodu na získání typu prvku něco jako getType() místo getOption(‚type‘). Je to potřeba ve vykreslovací šabloně.

m.brecher
Generous Backer | 717
+
0
-

@MarekBartoš Ahoj, já používám $formControl->getOption(‚type‘) ve svojí obecné třídě FormFactory, která nastavuje html pro lepší vykreslení formuláře a tyto prvky mě to podporuje:

foreach ($form->getComponents(deep: true) as $component){
    $class = match($component->getOption('type')){
        // todo: further nette inputs - integer, password, email
        'text' => 'text-input',         // TextInput
        'date' => 'text-input',         // DateInput - custom
        'datetime' => 'text-input',     // DateTimeInput - custom
        'textarea' => 'text-area',      // TextArea
        'select' => 'select-input',     // SelectBox, MultiSelectBox
        'checkbox' => 'checkbox',       // Checkbox, CheckboxList
        'radio' => 'radio-input',       // RadioList
        'file' => 'file-input',         // UploadControl - custom html
        'button' => 'button',           // SubmitButton, Button
        default => '',
    };
}

Ale faktem je, že se zde iteruje nad components, nikoliv controls a zatím jsem to použil v jednoduchých formulářích. Ale stejné controls/components se pomocí $formControl->getOption(‚type‘) vykresluje v šabloně a tam iteruji nad $form->getControls().

Editoval m.brecher (16. 10. 2022 17:01)

Marek Bartoš
Nette Blogger | 1146
+
+3
-

Není těžké na to přijít, stačí si najít kde je metoda getOption() definovaná. Je definovaná v BaseControl, takže všechny prvky v nette/forms ti tak fungovat budou, ale bez toho aby metoda byla v Control to není neprůstřelné.
instanceof je zkrátka potřeba, pokud ti má kód kontrolovat phpstan a fungovat napovídání v IDE. Kód na který se nedá prokliknout je pain při upgradech.