Form renderer – bootstrap tabs
- Jan Mikeš
- Člen | 771
Můžeš si nachystat jednu šablonu s ručním vyrenderováním formuláře, kterou budou využívat všechny formy, já to tak používám pro všechny formuláře v admin rozhraní, viz. příklad, třeba pomůže/inspiruje.
{* translatableForm.latte: *}
{form $formName}
{var $renderer = $form->getRenderer()}
{$renderer->render($form, 'ownerrors')|noescape}
<fieldset>
{foreach $form["common"]->controls as $formControl}
{$renderer->renderPair($formControl)|noescape}
{/foreach}
</fieldset>
<ul class="nav nav-tabs" n:inner-foreach="$form['translations']->components as $locale => $container">
<li n:class="$iterator->first? active">
<a data-toggle="tab" href="#tab-lang-{$locale}">
{$locale}
</a>
</li>
</ul>
<div class="tab-content" n:inner-foreach="$form['translations']->components as $locale => $container">
<fieldset n:class="$iterator->first? 'active in', tab-pane, fade" id="tab-lang-{$locale}" n:inner-foreach="$container->controls as $formControl">
{$renderer->renderPair($formControl)|noescape}
</fieldset>
</div>
<fieldset>
{foreach $form["buttons"]->controls as $formControl}
{$renderer->renderPair($formControl)|noescape}
{/foreach}
</fieldset>
{/form}
{* etc Actuality.add.latte *}
{include 'translatableForm.latte', formName => 'manageActualityForm'}
U všech formulářů v admin pak dodržuji strukturu, kdy mám
3 containery, shared
, translations
a
buttons
. Výsledné formuláře pak vypadají např. takto
V tomto případě jsou navíc jako bonus otevírány ajaxem v modalu.
- Jan Mikeš
- Člen | 771
Mám BaseFormFactory s tímto kódem:
public function create($domain = NULL)
{
$form = new UI\Form;
$renderer = $form->getRenderer();
$renderer->wrappers['controls']['container'] = NULL;
$renderer->wrappers['pair']['container'] = 'div class=control-pair';
$renderer->wrappers['pair']['.error'] = 'has-error';
$renderer->wrappers['control']['container'] = 'div class=control-input';
$renderer->wrappers['label']['container'] = 'div class=control-label';
$renderer->wrappers['control']['description'] = 'span class=input-help';
$renderer->wrappers['control']['errorcontainer'] = 'span class=form-error-message';
// make form and controls compatible with Twitter Bootstrap
foreach ($form->getControls() as $control) {
if ($control instanceof Controls\Checkbox || $control instanceof Controls\CheckboxList || $control instanceof Controls\RadioList) {
$control->getSeparatorPrototype()->setName('div')->addClass($control->getControlPrototype()->type);
}
}
return $form;
}
Zde lehce očesaný kód pro LESS:
form {
.control-pair {
.make-row(0);
.clearfix();
&.has-error {
.control-label {
color: red;
}
}
&.required {
.control-label {
label:before {
content: '* ';
color: red;
}
}
}
}
.control-label {
.make-sm-column(3, 0);
}
.control-input {
.make-sm-column(9, 0);
}
.input-help {
// ...
}
.input-error {
// ...
}
select,
input[type="text"],
input[type="date"],
input[type="email"],
input[type="password"],
textarea {
.form-control;
// ...
}
input[type="submit"] {
.btn;
.btn-success;
}
}
Ve skutečnosti je toho CSS/LESS mnohem více :-)
Editoval Lexi (8. 9. 2016 21:54)
- Landsman
- Člen | 152
Nepoužil jsi tam náhodou někdy i replicator?
Řeším to, že bych jeden z těch tabů chtěl překreslovat po přidání
položky replicatorem. Tzn obalit jej snippetem. Taby si ručně vypíši, nic
jiného mi asi nezbyde. Pak je tam ale tento problém: https://forum.nette.org/…a-form-maker#…
- Jan Mikeš
- Člen | 771
Bohužel replicator nepoužívám, ale řešením by mohla být kombinace
toho co tam píší. Pravděpodobně budeš muset použít
{snippetArea}
kvůli includované šabloně, dále
{var $_form}
hack, název formuláře máš v proměnné
$formName
, takže se potřebuješ dostat
k {$control[$formName]}
- Jan Mikeš
- Člen | 771
Je to ošklivý hack, ale funkční :-) alternativou by mohlo být javascriptové řešení, které by ti duplikovalo containery/inputy, ale napsat by sis ho musel sám (možná na fóru budou ukázky kódů).
Výhodou tohoto řešení by byl celkově čistější přístup, rychlost (úplně by vypadla potřeba kontaktovat server při přidávání kontejnerů, vše by řešil JS).
Nevýhodou mírně složitější zpracování dat přes
getHttpData()
a nějaké to psaní v javascriptu.
- Landsman
- Člen | 152
Lexi napsal(a):
Je to ošklivý hack, ale funkční :-) alternativou by mohlo být javascriptové řešení, které by ti duplikovalo containery/inputy, ale napsat by sis ho musel sám (možná na fóru budou ukázky kódů).
Výhodou tohoto řešení by byl celkově čistější přístup, rychlost (úplně by vypadla potřeba kontaktovat server při přidávání kontejnerů, vše by řešil JS).
Nevýhodou mírně složitější zpracování dat přes
getHttpData()
a nějaké to psaní v javascriptu.
Já to na jednom projektu mám tak, jak popisuješ. Realizace byla upřímně o dost snazší, ale chtěl jsem to tady zkusit udělat přes replicator. Hotovo. Teď přemýšlím, jaké mi to může dát výhody oproti té jquery manipulaci s DOM :D
No teoreticky to můžu ukládat do session, kdyby třeba spadl internet :)
Editoval Landsman (8. 9. 2016 22:59)
- Jan Mikeš
- Člen | 771
Landsman napsal(a):
No teoreticky to můžu ukládat do session, kdyby třeba spadl internet :)
To konec konců můžeš i s tou JS implementací ;) pokaždé když zmáčkneš tlačítko „přidat položku“ nebo „odebrat položku“, může se na pozadí spustit ajax na signál, který ti přidá do session informaci o tom, že uživatel přidal nový kontejner. To samé s odebíráním. Do toho ještě v několika vteřinových intervalech ukládat data uživatele a po odeslání formuláře session vyčistit (k tomu mám případně také někde ukázku, u formuláře který má kolem 100 inputů se to velice hodí :-) ).
Fantazii se meze nekladou.
- Landsman
- Člen | 152
Lexi napsal(a):
Landsman napsal(a):
No teoreticky to můžu ukládat do session, kdyby třeba spadl internet :)
To konec konců můžeš i s tou JS implementací ;) pokaždé když zmáčkneš tlačítko „přidat položku“ nebo „odebrat položku“, může se na pozadí spustit ajax na signál, který ti přidá do session informaci o tom, že uživatel přidal nový kontejner. To samé s odebíráním. Do toho ještě v několika vteřinových intervalech ukládat data uživatele a po odeslání formuláře session vyčistit (k tomu mám případně také někde ukázku, u formuláře který má kolem 100 inputů se to velice hodí :-) ).
Fantazii se meze nekladou.
Cool, tam se to rozhodně vyplatí.
Vychází z toho ten JS asi opravdu nejlépe. Příště asi komplet
přes něj.