ConvetionalRenderer – Latte pomocník pro ruční renderování formuláře + Tw Bootstrap
- Filip Procházka
- Moderator | 4668
Makro {input}
vyžaduje přítomnost proměnné
$_form
, protože přijímá pouze cestu k prvku (proto tam mám
lookupPath
)
Pokud bys to chtěl napsat ještě lépe tak použij moje nová makra a bude to fungovat „samo“ :)
<div id="modalForm" class="modal hide" role="dialog" aria-labelledby="myModalLabel" aria-hidden="false">
{snippet modalForm}{if $showForm}
{form $form}
<div class="modal-header">
<a class="close" data-dismiss="modal" aria-hidden="false">×</a>
<h3 id="myModalLabel">{$formLabel}</h3>
</div>
<div class="modal-body">
{form errors}
{group "body"}
</div>
<div class="modal-footer">
{foreach $form->getGroup('controls')->controls as $control}
{input $control->lookupPath('Nette\Forms\Form')}
{/foreach}
</div>
{/form}
{/if}{/snippet}
</div>
- Filip Procházka
- Moderator | 4668
Ta by se tam měla přidávat jako default – tedy zrušíš ji tak, že
tam dáš jinou form-
třídu :)
- Tomáš Jablonický
- Člen | 115
Ahoj,
při použití tohoto rendereru jsem si všiml docela vysokého času … vykreslení formuláře klasickou metodou trvá něco do 100 ms ale formulář vykreslený pomocí Bootrstap Twitteru trvá trojnásobek (300 ms někdy skoro 400) – což už je trochu brzda.
Nešlo by to trochu optimalizovat?
- Filip Procházka
- Moderator | 4668
Mně vykreslení celé stránky trvá kolem 100ms. Nebude chyba jinde?
Každopádně nějaké optimalizace by se snad udělat daly.
Editoval HosipLan (6. 10. 2012 14:12)
- David Ďurika
- Člen | 328
pise mi to Unknown macro {pair} a mam pocit ze som ten addon implementoval
spravne…
{$form->render($form[‚control-name‘])} mi fungue spravne
v com je problem ? dakujem
- Filip Procházka
- Moderator | 4668
Pokud {pair}
není obaleno do {form}
, tak nebude
fungovat. Což je napsané v „dokumentaci“ pluginu.
Editoval HosipLan (9. 10. 2012 16:58)
- David Ďurika
- Člen | 328
mam to obalene vo {form} tu je zablona:
<?php
{form phraseEditForm, class => 'row'}
<div class="control-group span3">
{label phraseType /}
{input phraseType}
</div>
<div class="control-group span3">
{label sourceLanguage /}
{input sourceLanguage}
</div>
<div class="control-group span3">
<label for="frmeditForm-source_languages"><b>Translation status</b></label>
{$form->render($form['corrected'])}
{pair ready}
{* {$form->render($form['ready'])} toto funguje *}
</div>
{/form}
?>
- LeonardoCA
- Člen | 296
Hosiplan: chybí mi v dokumentaci možnost vyrenderovat samostatný control – ne jako pair, je nějaká jednoduchá cesta?
- Felix
- Nette Core | 1196
achtan napsal(a):
a co ten moj problem ? https://forum.nette.org/…tw-bootstrap?p=2
Vyreseno, nesmime zapominat na
Kdyby\Extension\Forms\BootstrapRenderer\DI\RendererExtension::register($configurator);
Editoval Felix (15. 10. 2012 9:33)
- David Ďurika
- Člen | 328
problem s CheckboxList-om
hlasi to http://grab.by/gZEI
ked vypnem bootsrapRenderer tak vsetko ide OK
- Filip Procházka
- Moderator | 4668
@achtan: jediné co můžu udělat, tak dát tam výjimku s „tuto implementaci checkboxlistu psalo prasátko, stahni si tohle “.
- LeonardoCA
- Člen | 296
@Hosiplan – trochu jsem zkoušel renderování profilovat a optimalizovat, používám 2× zanořený Replikátor a i poměrně jednoduchý formulář (asi 15 inputů v různých containerech + tlačítka) se mi renderuje cca 200–300ms.
Já se k tomu budu vracet až za delší dobu tak zase jen pár nápadů:
- bez využití cache renderování znatelně urychlí použití jedné šablony místo dvou a hodí se to i proto, že se tak dá toho více přesunout do inicializace a nemusí se volat opakovaně v render
- template si držím přímo v rendereru ať se nemusí opakovaně inicializovat při volání každého makra
- přemýšlím jak omezit počet interního volání getControl() protože to mi při zapnutém XDebugExtension trvá cca 2ms a pro jeden prvek se volá 3× a pak renderovávání jednoho prvku trvá cca 8–17 ms v závislosti na tom jestli renderuji i label. Ono vlastně jsem si ještě trochu více přepsal inicializaci a povedlo se mi to snížit z původních cca 45ms na prvek bez cashování. (pořád jde o custom rendering při generování celého formuláře se to chová jinak)
Teď už nevím co všechno jsem měnil, ale jelikož to ještě není doladěné a čas není tak tu hodím akorát náznak: https://gist.github.com/4047257
Bez předání template v parametru to je v mém případě takřka nepoužitelné, čas roste takřka lineárně s počtem prvků a hravě jsem se tak dostal na jednotky sekund. Protože jsem chtěl všechny formuláře configurovat přes config.neon tak jim template předávám takto:
factories:
bootstrapRenderer:
class: Kdyby\Extension\Forms\BootstrapRenderer\BootstrapRenderer (@presenterAccessor::cloneTemplate())
PresenterAccessor si získává presenter od application za běhu, ale ještě se mi to stále nelíbí.
Editoval LeonardoCA (9. 11. 2012 19:54)
- LeonardoCA
- Člen | 296
Bezva. Ještě přihodím jeden poznatek. Pořád hledám optimální cestu definování formulářů a tak jsem zkoušel různé přístupy. Při použití mírně upravených továrniček z Venne se spouštělo volání beforeRender při každém generování containeru místo jen při generování formuláře a pak se celý formulář vygeneroval tolikrát, kolik bylo vložených containerů replikátorem. Zase jen při custom renderingu.
Příčinu jsem neobjevil, bylo to už trochu moc cizích kódů najednou čas krátký a je možné, že jsem tam zanesl nějakou chybu – ale když jsem přepl na default renderer tak ten formulář vykreslil správně akorát si neporadil s bootstrap specifickými makry.
- Matúš Matula
- Člen | 257
Ahoj,
nejako sa mi nedari zaregistrovat latte makra, v bootstrap.php mam nasledovny riadok
<?php
Kdyby\BootstrapFormRenderer\DI\RendererExtension::register($configurator);
?>
hned po zaregistrovani RobotLoadera
<?php
$configurator->createRobotLoader()
->addDirectory(APP_DIR)
->addDirectory(LIBS_DIR)
->register();
?>
ale pri pouziti custom makra to hodi
Nette\Latte\CompileException - There are unclosed macros in ..
nejake napady?
- Matúš Matula
- Člen | 257
Sry, zabudol som napisat, ze som si prave stiahol najnovsiu verziu z githubu..
Edit: Aby nedoslo k nedorozumeniu, tu najnovsiu verziu som mal od zaciatku, len som to zabudol napisat v prispevku. Takze stale to nefunguje..
Edit2: Vyzera to, ze stacilo zmazat cache :-) Sorry za false report.
Editoval Matúš Matula (28. 1. 2013 16:20)
- MartinitCZ
- Člen | 580
Ahoj,
používám tento doplněk a addDynamic() a narazil jsem na jeden problém.
Je možnost addDynamic() obalit nějakým div a případně jak?? Potřeboval
bych totiž tuto část odsadit od zbytku formuláře.
Zkoušel jsem addGroup(), ale to bohužel není ono.
Děkuji.
- Šaman
- Člen | 2659
Ahoj, nechceš to ještě rozšířit o podporu ikon? Mě konkrétně by se to hodilo na kalendář, ale využití by se našlo častěji.
Představoval bych si to tak, že formulářovému prvku nastavím
->setOption('prepend-icon', 'icon-pencil');
a ono mi to
správně vlepí ikonu do formu nebo do tlačítka.
Editoval Šaman (6. 2. 2013 6:38)
- Filip Procházka
- Moderator | 4668
$input->setOption('input-prepend', Html::el('i')->class('icon-pencil'));
Ale vylepšíme, vytvoříš mi issue, prosím?
- darthcz
- Člen | 113
achtan napsal(a):
problem s CheckboxList-om
hlasi to http://grab.by/gZEI
ked vypnem bootsrapRenderer tak vsetko ide OK
Mám úplně stejný problém, nemáte nějakou implementaci checkboxlist, u které to funguje? Zkoušel jsem i https://raw.github.com/…kboxList.php a bohužel pořád to samé :-/
Problém je, že checkboxlist vrací z funkce getControl($key) string, ale renderer očekává pole objektů Nette\Utils\Html…
Další problém je, že pokud dám checkboxlistu NULL nebo array(), tak se mi stejný prvek vykreslí dvakrát. Jednou ve skupině a jednou mimo skupinu. Se zadanými parametry místo NULL se vykreslí správně. S klasickým renderem vše funguje správně.
$this->addGroup('Propagace');
$this->addCheckboxList('features', 'Metody propagace', NULL);
Editoval darthcz (7. 2. 2013 5:52)
- Zbirek
- Člen | 4
Zdravím, nevím si rady s naprostou banalitou. Nedaří se mi zaregistrovat Latte makra … Přikládám bootstrap.php. Používám aktuální verzi Sandboxu
<?php
use Nette\Forms\Container,
Nette\Forms\Controls;
// Load Nette Framework or autoloader generated by Composer
require __DIR__ . '/../libs/autoload.php';
$configurator = new Nette\Config\Configurator;
// Enable Nette Debugger for error visualisation & logging
//$configurator->setDebugMode(TRUE);
$configurator->enableDebugger(__DIR__ . '/../log');
// Enable RobotLoader - this will load all classes automatically
$configurator->setTempDirectory(__DIR__ . '/../temp');
$configurator->createRobotLoader()
->addDirectory(__DIR__)
->addDirectory(__DIR__ . '/../libs')
->register();
// Create Dependency Injection container from config.neon file
$configurator->addConfig(__DIR__ . '/config/config.neon');
$configurator->addConfig(__DIR__ . '/config/config.local.neon', $configurator::NONE); // none section
$container = $configurator->createContainer();
Kdyby\BootstrapFormRenderer\DI\RendererExtension::register($configurator);
return $container;
?>
Díky za každou radu
- duskohu
- Člen | 778
@Zbirek Zaregistroval si len Extension, macro musis
zaregistrovat v templatePrepareFilters.
Skus nieco taketo do BasePresentru:
public function templatePrepareFilters($template) {
$latte = $this->getContext()->createNette__Latte();
\Kdyby\BootstrapFormRenderer\Latte\FormMacros::install($latte->compiler);
$template->registerFilter($latte);
}
Edit: Odporucam pozriet: Registrace macra
Editoval duskohu (21. 3. 2013 10:33)
- Filip Procházka
- Moderator | 4668
Makro se registruje samo od sebe (v extension), ale pokud hackuješ
Latte\Engine
a přidáváš tam makra v presenteru, tak se to do
něj z containeru nedostane.
- Filip111
- Člen | 244
Ahoj, šel by BootstrapFormRenderer zaregistrovat pomocí neonu nebo v rámci nějaké jiné Extension?
Jde mi o to, že používám vlastní Cms jako Extension a přidávat
řádek
Kdyby\BootstrapFormRenderer\DI\RendererExtension::register($configurator);
do mnoha bootstrapů se mi nechce.
- Filip Procházka
- Moderator | 4668
Pokud používáš vývojové Nette, tak stačí
extensions:
twBootstrapRenderer: Kdyby\BootstrapFormRenderer\DI\RendererExtension
- Filip111
- Člen | 244
Perfektní…
až na to, že mi to nefunguje. Nahradil jsem verzi 2.0.5 za dev, přidal
definici v neonu,
a začalo mi to házet chybu v presenteru, že
$this->context->cms
neexistuje.
Tedy vůbec se nezaregistrovalo původní rozšíření registrované v bootstrapu:
$configurator->onCompile[] = function ($configurator, $compiler) {
$compiler->addExtension('cms', new CmsExtension);
};
Ještě jsem ho zkoušel přesunout do neonu
extensions:
cms: CmsExtension
#twBootstrapRenderer: Kdyby\BootstrapFormRenderer\DI\RendererExtension
ale to taky nepomůže.
Není k tomu někde nějaký info? Na fóru jsem nic(moc) nenašel a nechci
tím zaplácnout tenhle topic.
Vůbec se mi nyní nedaří zaregistrovat jakékoliv extension.
- enumag
- Člen | 2118
@Filip111: Trochu si pleteš pojmy. V DIC
($this->context
) jsou služby, nikoli extensions. Extension má
pouze říct DI kontejneru, jaké služby má obsahovat – a tyto služby
v něm pak najdeš. Extension by služby vždy mělo prefixovat
takže výsledný název služby bude „cms.sluzba“ a dostal by ses k ní
přes $this->context->{"cms.sluzba"}
. Také zvaž použití
inject místo
context.
Editoval enumag (15. 4. 2013 21:17)
- Filip111
- Člen | 244
O injectu vím, zatím se mi nechtělo všechno přepisovat.
Nevím, jestli mi něco neuteklo nebo jsem to jen špatně popsal, ale mám např. extension CmsExtension, ta má vlastní konfigurák cms.neon a v něm jsou definované služby, např.:
services:
cms.catalogFilter:
class: web123\Filters\CatalogFilter
...
cms.contentFilter
class: ...
...
K těmto službám pak v presenteru přistupuji např. pomocí
$this->context->cms->catalogFilter
To je dobře nebo špatně (když pominu absenci injectu)?
Nyní po použítí dev verze vůbec nejsou načtené služby schované pod
$this->context->cms.
- t0x1c
- Člen | 151
Zdravím. Mám problem když chci renderovat jednoduchý formulář s kodem v presenteru:
protected function createComponentServerForm() {
$form = new UI\Form;
$form->setRenderer(new BootstrapRenderer($this->createTemplate()));
$form->addSelect('sluzba', 'Mám zájem o', array(
'cs16' => 'Counter-Strike 1.6 - 10 slotů',
'mc' => 'Minecraft+Bukkit - 5 slotů',
'tekkit' => 'Tekkit - 5 slotů',
'csgo' => 'CS:GO - 10 slotů'
))
->addRule(UI\Form::FILLED, "Toto pole je povinné!");
$form->addSubmit('submit', 'Mám zájem o server')
->setAttribute('class', 'btn btn-large btn-warning')
->setAttribute('style', ''); //style
$form->onSuccess[] = $this->serverFormSubmitted;
return $form;
}
a v template
<div style="width: auto;height: auto;margin-left: auto;margin-right: auto">
{form serverForm}
{control $form errors}
{$form->render('errors')}
{$form->render('controls')}
{$form->render('buttons')}
{/form}
</div>
udělá mi to toto
http://www.imagehosting.cz/…s/bugsis.jpg
Už se s tim ser* skoro hodinu a ne a ne to fungovat u jinych formulářu mi
to fungovalo normálně když jsem přidal např:
{form registraceForm}
{control $form errors}
{$form->render('errors')}
{/form}
ale u tohoto když to přidam takhle mimo mi to udělá mezi tim selectem a buttonem nesmyslnou mezeru velkou asi na výšku 300 px.. viz. http://www.imagehosting.cz/…znzvu4ko.jpg V čem je chyba? Díky
Editoval t0x1c (22. 5. 2013 21:00)
- Filip Procházka
- Moderator | 4668
To vypadá, že se tam někde špatně uzavírá nějaký div.
Btw, není tohle {control $form errors}
zbytečné?
- Filip Procházka
- Moderator | 4668
Nechceš se v tom zkusit porejpat a zjistit kde se ti blbě uzavírají ty tagy? :)
Co vyrenderuje tohle?
-----
<div style="width: auto;height: auto;margin-left: auto;margin-right: auto">
-----
{form serverForm}
-----
{$form->render('errors')}
-----
{$form->render('controls')}
-----
{$form->render('buttons')}
-----
{/form}
-----
</div>
-----
- n.u.r.v.
- Člen | 485
Ahoj, stáhl jsem si twitter bootstrap a celou jeho složku (bootstrap) jsem dal do složky „projekt/www/“.
A teď jsem tu pročítal toto vlákno a mám v tom pěkný guláš – prosím o radu, jak používat/vykreslovat bootstrap formuláře? Kam co musím zaregistrovat/napsat, případně co ještě stáhnout?
např. můj přihlašovací formulář v SignPresenter.php:
protected function createComponentSignInForm() {
$form = new Form();
//$form->setAction('pages/login.php');
$form->setMethod('POST');
$form->addText('email', 'E-mail:')
->setRequired('Zadejte prosím Váš e-mail!')
->setAttribute('name', 'username')
->addRule(Form::EMAIL, "Vložený e-mail je ve špatném formátu!");
$form->addPassword('password', 'Heslo:')
->setRequired('Vyplňte heslo')
->setAttribute('onkeyup', 'passwordStrength(this.value);')
->setAttribute('id', 'pass')
->setAttribute('name', 'password');
$form->addSubmit('send', 'Přihlásit!');
$form->onSuccess[] = $this->signInFormSubmitted;
return $form; // vykreslí formulář
a latte in.latte:
{var $robots = noindex}
{block #content}
<h1 n:block=title>Administrace - příhlášení</h1>
{control signInForm}
Chápu dobře, že stačí do config.neon umístit toto (to se mi zdá nějak moc jednoduché):
extensions:
twBootstrapRenderer: Kdyby\BootstrapFormRenderer\DI\RendererExtension
Moc děkuji za radu…
- enumag
- Člen | 2118
@n.u.r.v. A dokumentaci jsi četl?
Btw. tohle funguje myslím jen ve 2.1:
extensions:
twBootstrapRenderer: Kdyby\BootstrapFormRenderer\DI\RendererExtension
Editoval enumag (19. 6. 2013 12:44)