Nextras\Forms – užitečné formulářové komponenty

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
hrach
Člen | 1835
+
0
-

Nextras\Forms

je knihovna obsahuji uzitecne a casto pouzivane formularove prvky.

Komponenta JS frontend Popis
OptionList ANO radio list, vyberu pouze jednu hodnotu ze seznamu
MultiOptionList ANO checkbox list, vyberu 0-n hodnot ze seznamu; validace popdoruje pomínky výběru m hodnot.
DatePicker pouze ukázka (jQuery UI) HTML5 input, pracující s DateTime, nutny fallback pro JS komponenty
DateTimePicker pouze ukázka

Editoval hrach (1. 3. 2014 19:54)

barbucha
Člen | 11
+
0
-

Zdravim,
snazim se pouzit MultiOptionsList

$form->addMultiOptionList('level', 'Level:', array('DEBUG' => 'DEBUG', 'INFO'=> 'INFO', 'WARN' =>'WARN', 'ERROR' => 'ERROR);

a potrebuji mit promenou $level persistentni

pokud zatrhnu ve formulari napriklad WARN a ERROR vygeneruji se mi v odpovedi (html) dva hidden inputy
<input type=„hidden“ name=„level[0]“ value=„WARN“ /><input type=„hidden“ name=„level[1]“ value=„ERROR“ />

pokud pouziji formular znovu dochazi k chybam, hidden input a checkbox se vzajemne ovlivni a ve vysledna promena $level obsahuje nesmysly

Nemuzete me nejak nakopnout …

Editoval barbucha (30. 1. 2013 12:04)

hrach
Člen | 1835
+
0
-

Nechapu co je to mit persistentni formularovy prvek. Jak toho dosahujes?

Caine
Člen | 216
+
0
-

Tak pokud potrebujes mit $level persistentni, tak v obsluzny onSuccess metode asi udelas neco jako $this->level = $values['level'] (pokud jsi v presenteru/control prvku). A pri tvorbe formalure
$form->addMultiOptionList('level', 'Level:', array('DEBUG' => 'DEBUG', ...)->setDefault($this->level);

barbucha
Člen | 11
+
0
-

add @hrach
Persistentni formularovy prvek.
Pokud do formulare dam napriklad input typu text s nazvem test
<input type=„text“ name=„test“ value="">

a $test nastavim jako persistent, tak se mi nikdy zadny hidden input se jmenem test nevytvori

add @caine
krome formulare, pouzivam obsah promene do odkazu a hlavne jednou za cas delam ajaxem automaticky reload stranky, kde potrebuju mit informace z promene $level a nechtel jsem to delat nejakym zpusobem rucne. Stranka obsahuje formular a pod nim tabulku s vysledky ovlivnenymi zatrzenymi checkboxy, tato tabulka se pravidelne obnovuje.

boob
Člen | 21
+
0
-

Zdar, snazim sa rozbehat tieto komponenty, skopiroval som kod z ukazky

$form->addMultiOptionList('list2', 'Pick your interests', ['d', 'e', 'f'])
     ->addRule($form::LENGTH, 'You must pick just 1 or 2 interests.', array(1, 2));
?>
{form example}
<table>
<tr>
    <th>{label list1/}</th>
    <td>{input list1}</td>
</tr>
<tr>
    <th>{label list2/}</th>
    <td>
    {foreach $form['list2']-items as $key => $label}
        {label list2:$key class => checkbox}
            {input list2:$key}
            {$label}
        {/label}
    {/foreach}
    </td>
</tr>
</table>
{/form}

ale najprv dostanem chybu
Use of undefined constant items - assumed 'items'
pravdepodobne tam ma byt teda
$form['list2']->items
ale po opraveni zase dostanem
Component with name 'list2:0' does not exist.

je este nieco potrebne niekde pridat?
dakujem

Editoval boob (24. 4. 2013 13:09)

hrach
Člen | 1835
+
0
-

boob: musis pouzit nightly verzi, kde makra toto umeji nativne, nebo si stahni FormMacros ze starsi verze, ktera toto umeji. Pokud si pres composer sosnes zatagovanou verzi 1.0, tak ta to tam ma.

boob
Člen | 21
+
0
-

hrach: aha a nightly verziu coho? Nette? vo verzii 2.0.8 to nie je? ked pozeram, ze uz pred 3 mesiacmi sa toto riesilo? :) a nextras/forms cez composer mam dev-master

dakujem

hrach
Člen | 1835
+
0
-
  • dev-master nextras/forms funguje s dev-master nette/nette
  • 1.0 nextras/forms funguje s 2.0.x nette/nette

to sem chtel asi rict.

boob
Člen | 21
+
0
-

ah soo :) dakujem pekne, vyskusam, napisem

edit:

mam nainstalovane Nette 2.0.10 a nextras/forms 1.0.0, ale aj tak mi to pise Component with name 'list2:0' does not exist.

Editoval boob (29. 4. 2013 11:37)

duskohu
Člen | 778
+
0
-

Ahoj, snazim sa pouzit datePicker s TW bootstrap ako je v priklade, trosku som musel pozmenit typ inputu.

$newsTo = new DateTime();
$form->addDatePicker('newsTo', 'Novinka do')
->setDefaultValue($newsTo->format('d.m.Y'));
	<div id="{$form->getElementPrototype()->id}-newsTo-pair" class="control-group">
		{label newsTo/}
		<div class="controls">
			<div class="input-append date" >
				{input newsTo class=>'input-mini', type=>'text'}
				<span class="add-on"><i class="icon-remove"></i></span>
				<span class="add-on"><i class="icon-calendar"></i></span>
			</div>
		</div>
	</div>

problem je ze ani za svet neviem zmenit format datumu z Y-m-d na d.m.Y, pri prvom nacitani. Ked zmenim datum cez picker tak je uz vsetko ok. Neviete mi poradit ako na to?

Jan Mikeš
Člen | 771
+
0
-

Pres data-format attribut ;)

duskohu
Člen | 778
+
0
-

@Lexi teraz som asi velmi nepochopil ten data atribut mam naviazat na input alebo na div .input-append lebo som skusal data-format=‚d.m.Y‘ na obe , ale nepomoholo.

akadlec
Člen | 1326
+
0
-

@duskohu: pokud je to v tom dateinput elementu stejně jako v těch jiných co jsem viděl tak mají formát data natvrdo jako konstantu ve třídě. Řešil jsem to tak že jsem to předělal na proměnnou a přidal setter kterým jsem to mohl nastavovat, ale nakonec jsem to zahodil a udělal vlastní formextension přímo pro bootstrap který mě dělá input prepend či append a je tam i clear button.

EDIT:
aha asi sem tě přesně nepochopil, chceš změnit použitý formát přímo už v tom co dělá ten plugin? Konkrétně ten co odkazuješ používám taky a v tom obalovacím DIVu kde mám zadefinované options mám taky data atribut pro určení formátu.

Editoval akadlec (9. 7. 2013 8:53)

duskohu
Člen | 778
+
0
-

Ano ja potrebujem zmenit format ked nastavim setDefault a nacita sa form.No ja som to dal takto. len toto mi nefunguje. Zabudol som este na nieco? Js pouzivam to co je pri doplnku.

	<div id="{$form->getElementPrototype()->id}-newsTo-pair" class="control-group">
		{label newsTo/}
		<div class="controls">
			<div class="input-append date" data-format='d.m.Y'>
				{input newsTo class=>'input-mini', type=>'text'}
				<span class="add-on"><i class="icon-remove"></i></span>
				<span class="add-on"><i class="icon-calendar"></i></span>
			</div>
		</div>
	</div>
akadlec
Člen | 1326
+
0
-

@duskohu: Máš špatný data atribut:

<div class="input-append date" data-date-format="dd.mm.YYYY">
	....
</div>

Editoval akadlec (9. 7. 2013 9:22)

Jan Mikeš
Člen | 771
+
0
-

Ah, moje chyba, psal jsem z hlavy a neoveril si presny tvar toho atributu

duskohu
Člen | 778
+
0
-

@akadlec dik, ach jaj ta nepozornost :-P, ale aj napriek tomu to nepomohlo :-(

duskohu
Člen | 778
+
0
-

Tak sa mi to nakoniec podarilo dokopat, nepotreboval som ani dat atribut stacilo trosku prerobit zavadzacie js, keby mal niekto zaujem priklad je tu

akadlec
Člen | 1326
+
0
-

@duskohu: tak v tom případě tam máš něco špatně a něbo to někde přetěžuješ, ty dataatributy fungují bez problému, sám ten skript na který si linkoval pro bootstrap používám a celý konfig datepickeru mám právě přes data atributy

/**
 * Generates control's HTML element.
 *
 * @return \Nette\Web\Html
 */
public function getControl()
{
        $control = parent::getControl();

        if ( $this->isDisabled() )
                $this->buttonStyle = self::BUTTON_STYLE_ICON_NONE;

        $outter = $this->buttonStyle == self::BUTTON_STYLE_ICON_LEFT || $this->buttonStyle == self::BUTTON_STYLE_ICON_RIGHT ? \Nette\Utils\Html::el('div') : $control;

        if ( $this->buttonStyle == self::BUTTON_STYLE_ICON_LEFT ) {
                $outter->addClass('input-prepend date');

        } else if ( $this->buttonStyle == self::BUTTON_STYLE_ICON_RIGHT ) {
                $outter->addClass('input-append date');
        }

        $outter->addClass($this->className);

        // Set dataatribute options

        // The date format, combination of p, P, h, hh, i, ii, s, ss, d, dd, m, mm, M, MM, yy, yyyy
        $outter->data['date-format'] = $this->format;
        // Day of the week start. 0 (Sunday) to 6 (Saturday)
        $outter->data['date-weekstart'] = $this->weekStart;
        list($min, $max) = $this->extractRangeRule($this->getRules());
        // The earliest date that may be selected
        if ( $min !== NULL )
                $outter->data['date-startdate'] = $min->format($this->toPhpFormat ($this->format));
        // The latest date that may be selected
        if ( $max !== NULL )
                $outter->data['date-enddate'] = $max->format($this->toPhpFormat ($this->format));
        // Days of the week that should be disabled. Values are 0 (Sunday) to 6 (Saturday)
        if ( $this->daysOfWeekDisabled !== NULL )
                $outter->data['date-days-of-week-disabled'] = implode(',', $this->daysOfWeekDisabled);
        // Whether or not to close the datetimepicker immediately when a date is selected
        $outter->data['date-autoclose'] = $this->autoclose ? 'true' : 'false';
        // The view that the datetimepicker should show when it is opened
        $outter->data['start-view'] = $this->startView;
        // The lowest view that the datetimepicker should show
        $outter->data['min-view'] = $this->minView;
        // The highest view that the datetimepicker should show
        $outter->data['max-view'] = $this->maxView;
        // If TRUE or "linked", displays a "Today" button at the bottom of the datetimepicker to select the current date
        $outter->data['date-today-btn'] = $this->todayButton;
        // If TRUE, highlights the current date.
        $outter->data['date-today-highlight'] = $this->todayHighlight;
        // Enable keyboard for navigation
        $outter->data['date-keyboard-navigation'] = $this->keyboardNavigation;
        // The two-letter code of the language to use for month and day names
        $outter->data['date-language'] = $this->language;
        // Whether or not to force parsing of the input value when the picker is closed
        $outter->data['date-force-parse'] = $this->forceParse;
        // This option is currently only available in the component implementation
        $outter->data['picker-position'] = $this->pickerPosition;
        // Default date
        if ( $this->value )
                $outter->data['date'] = $control->value = $this->value->format($this->toPhpFormat($this->format));

        if ( $this->buttonStyle == self::BUTTON_STYLE_ICON_LEFT ) {
                // Trigger button
                $outter->add('<span class="add-on"><i class="icon-calendar"></i></span>');
                // Cancel button
                if ( $this->cancelButton ) {
                        $outter->add('<span class="add-on"><i class="icon-remove"></i></span>');
                }
                // Input field
                $outter->add($control);

        } else if( $this->buttonStyle == self::BUTTON_STYLE_ICON_RIGHT ) {
                // Input field
                $outter->add($control);
                // Cancel button
                if ( $this->cancelButton ) {
                        $outter->add('<span class="add-on"><i class="icon-remove"></i></span>');
                }
                // Trigger button
                $outter->add('<span class="add-on"><i class="icon-calendar"></i></span>');
        }

        return $outter;
}
duskohu
Člen | 778
+
0
-

@akadlec no to zle bolo ze som mal date format uz tu, ale ked ho vymazem tak data atribut funguje. Takze netreba ani prepisovat doplnok tento je super. Pani dakujem za pomoc.

hrach
Člen | 1835
+
0
-

nextras/forms jsou opěz kompatibilní s masterem. Nově přibyla jednoduchá možnost tvorby svých input maker, které input etc. upraví do podoby, které potřebuje váš kodér. Jako příklad je možné uvést též nové Bootstrap 3 makro. Tyto makra je možné dále rozšířovat, dle pořeby daného webu.

minarth
Člen | 1
+
0
-

Zdravím,
chtěl bych použít Nextras\forms ve formuláři, který dělám. Plánuji mít celý form v jednom source-file a vykreslovat ho na více různých webech.. šel jsem na to, jako je v návodu nette.org.. Ale nevím, jak do toho natlačit Nextras\forms. V návodu je použití bootstrap a config.neon.. nic z toho ale nemám.

Musím si vybudovat standartní „Nette set-up“ anebo to lze nějak obejít?

Díky

duskohu
Člen | 778
+
0
-

Cau, podporuje MultiOptionList toggle ? lebo som to skusal nasadit, ale neslo mi to.

hrach
Člen | 1835
+
0
-

duskohu: co sem na to ted koukal, tak to neni a hned tak asi nebude. i kdyz jsem provedl drobnou upravu, tak to nejak nefunguje :D (videl bych zapeklitost spis v nette a jeho logice addCondition)

minarth: vubec ti nerozumim :-) Pro pouziti nextras v podstate nepotrebujes zadne bootstrap. staci zaregistrovat extension metodu, nebo si napsat vlastni metodu, ktery vytvari dany formularovy prvek ve formu…

duskohu
Člen | 778
+
0
-

@hrach nevadi, nejako si uz poradim :-), aj tak dakujem pekna praca.

raketoplan2005
Člen | 147
+
0
-

Nette 2.0
Nextras/Forms 1.0.0

$form->addMultiOptionList('list1', 'Pick your interests', ['a', 'b', 'c'])
     ->addRule($form::FILLED, 'You must pick some interest.');

Tento zápis u mě vyžaduje zaškrtnutí všech checkboxů namísto kteréhokoli, je to možné, prosím? :-)

Druhá věc je jak nastavím vlastní klíče jednotlivým checkboxům ta kabych pak mohl nastavit setDefaults, prosím? Checkboxy se mi indexují vždy od nuly.

Předávám jako třetí parametr:

$db->table->fetchPairs('id', 'name');

Děkuji

Editoval raketoplan2005 (5. 8. 2013 20:25)

Jakub Kontra
Člen | 30
+
0
-

Je možné aby mi toto nefungovalo?

$form->addDateTimePicker('time_from', 'Datum a čas výjezdu:')
			 ->addRule(\Nette\Application\UI\Form::VALID, 'Entered date is not valid!')
			 ->addCondition(\Nette\Application\UI\Form::FILLED);

EDIT:

Shazuje mi to apache, pokud ale smažu validace je to funkční

Editoval JimmyBlack (22. 8. 2013 0:24)

hrach
Člen | 1835
+
0
-

https://github.com/…/issues/1202
Hmhm, chtelo by to vyresit ten bc break

medhi
Generous Backer | 255
+
0
-

Je to super, rád bych to použil, ale podle všeho to funguje pouze s master verzí Nette. A tu se zase nedoporučuje používat. Lze to nějak aplikovat na poslední stable verzi Nette, abych to mohl reálně použít?

Děkuji

hrach
Člen | 1835
+
0
-

Hm. No… co bys rad pouzil? Neco noveho co tam je? Ja na masteru mam projekty ktere jsou verejne a maji velkou navstevnost. >8k nastev. Tag 1.0.0 je myslim pro stable ok. Pripadne kdyby nekdo poslal pull, tak to mergnu pro 1.0.1.

medhi
Generous Backer | 255
+
0
-

Konkrétně mi jde o OptionList, ale Nette 2.0.12 ještě neumí {input name:xxx}, které to generuje. Nebo dělám něco špatně?

duskohu
Člen | 778
+
+1
-

Ahoj, snazim sa rozchodit ajaxovu validaciu:

$form->addDatePicker('date_from', 'Dátum od')
->addRule($form::FILLED, 'Pole "%label" musí byť vyplnené!')

Je to podporovane? Lebo formular mi stale odosle. Samozrejme ked vypnem ajax tak mi formular odosle a vypise error hlasku. Problem je v tom ze formular mi odosle stale, a js validacia neprebehne, ani pri ajaxe, ani klasicky.

Jiří Nápravník
Člen | 710
+
0
-

Zdravím,
chtěl bych používat Nextras\Forms pro renderováníé Bootstrap 3. Je nějak možné při manuálním vykreslování nějak vykreslit celý pár? Tedy label i input? Kdyby\BootstrapRenderer má na to sympatické makro {pair}, které to obstarává, je něco takového možné u Nextras, případně jak na to? Protože často potřebuji vypsat oba najednou a když udělám {label }{input}, tak pak musím logicky ten obalovaci div class=„form-group“ dělat ručně, což je moc pracný…

hrach
Člen | 1835
+
0
-

Dival jses vubec na kod? :) Zkus jak v normalnim rendereru, pac to od nej dedi. https://github.com/…Renderer.php#…

Jiří Nápravník
Člen | 710
+
0
-

Dival jsem se na kod, ale prilis moudry jsem z toho nebyl. Samozrejme jsem si vsiml metody renderPair. ale mejak jsem moc nepochopil jak to použít dospěl jsem k něemu takovému:

{form form}
{$form->renderer->renderPair($input)}
{/form}

jenže skončím s chybou na

$this->form->getElementPrototype()->class('form-horizontal');

s tím že není definován $this->form

Já to nakonec vyřešil tím, že jsem podědil ten Nextras renderer a s vlastním formulářovým makrem, mj nastavuji ten $this->form, tak to pak funguje. Ale třeba dělám něco špatně.

hrach
Člen | 1835
+
0
-
  • urcite je blbost kombinovat renderer a makra
  • co si pamatuju, tak se renderer pouziva nejak takto:
{$form->render(begin)}
{$form->render(pair, $input)}
{$form->render(end)}
Jiří Nápravník
Člen | 710
+
0
-
  • co si pamatuju, tak se renderer pouziva nejak takto:
{$form->render(begin)}
{$form->render(pair, $input)}
{$form->render(end)}

tj právě přesně to co mi klasicky nefungovalo a kvůli kterému jsem rozšiřoval ten tvůj Renderer. Protože pokud koukám správně do kódu, tak DefaultFormRenderer v metodě render jako parametr mode nezpracovává pair… Metoda renderPair je volána jen z renderControls, která je volána z renderBody…

urcite je blbost kombinovat renderer a makra

nevím jestli se chápeme, já si jen udělal vlastní makro {pair}, který jen volá ten můj urpavený render:

public function macroPair(MacroNode $node, PhpWriter $writer)
{
	return $writer->write('$__form->render(\'pair\', $__form[%node.word])');
}
Azathoth
Člen | 495
+
0
-

Zdravím, chtěl bych se zeptat, jak si u datepickeru u toho javascriptového kalendáře nastavím jazyk. Díky za odpověď.

hrach
Člen | 1835
+
0
-

@Azathoth zalezi na datepickeru. Komponenta v nextras je primarne rendering do html5. ukazka,jak to tranformovat to nejakyho pickeru je spis demo ;) Jde ti o format data, nebo o co?

Azathoth
Člen | 495
+
0
-

Jde mi o to, že když si rozkliknu ten kalendář, tak jsou tam názvy dnů a měsíců anglicky.
V js složce mám soubor bootstrap-datetimepicker.cs.js, ale nevím, jak to udělat, aby se ta čeština v tom kalendáři zobrazovala.

hrach
Člen | 1835
+
0
-

no nacist ten soubor, ne?

Azathoth
Člen | 495
+
0
-

To dělám. Mám tam
<script src=„{$basePath}/js/jquery.min.js“></script>
<script src=„{$basePath}/js/bootstrap-datetimepicker.js“></script>
<script src=„{$basePath}/js/bootstrap-datetimepicker.cs.js“></script>
<script src=„{$basePath}/js/nextras.datetimepicker.init.js“></script>
<link href=„{$basePath}/css/datetimepicker.css“ type=„text/css“ rel=„stylesheet“>
<link rel=„stylesheet“ href=„{$basePath}/css/bootstrap.css“>

a nic. Pořád je to anglicky.

BigCharlie
Člen | 283
+
0
-

Narazil jsem na drobný, ale protivný problém. Pokud použiju CheckboxList ve spojení s Bs3Input makry, dojde k chybě v šabloně:

Call to a member function addAttributes() on a non-object

// z šablony
$_input = $_form["exampleChecklist"];
echo Nextras\Forms\Bridges\Latte\MacrosBS3InputMacros::input($_input->getControl()->addAttributes(array()), $_input)

Problém je v tom, že Checkboxlist::getControl vrací string.

Obejít se to dá tím, že místo CheckboxListu využiju MultiOptionList z Nextras. Existuje řešení, při kterém mohu využít nettí CheckboxList?

hrach
Člen | 1835
+
0
-

@BigCharlie urcite by to bylo super. Nechces udelat pullrequest?

tttpapi
Člen | 100
+
0
-

Už to tu několikrát bylo, ale řešení tu nikde není.
Mám verzi Nette 2.0.18 a stáhl jsem si Forms verzi 1.0.0.
Pokud si chci multiOptionList vykreslit ručně, tak to píše chybu Component with name ‚roles:1‘ does not exist.

config

<?php
nette:
        latte:
            macros:
                - Nextras\Forms\Latte\Macros::install
?>

Bootstrap

<?php
use Nette\Forms\Container;
use Nextras\Forms\Controls;
Container::extensionMethod('addOptionList', function (Container $container, $name, $label = NULL, array $items = NULL) {
    return $container[$name] = new Controls\OptionList($label, $items);
});
Container::extensionMethod('addMultiOptionList', function (Container $container, $name, $label = NULL, array $items = NULL) {
    return $container[$name] = new Controls\MultiOptionList($label, $items);
});
Container::extensionMethod('addDatePicker', function (Container $container, $name, $label = NULL) {
    return $container[$name] = new Controls\DatePicker($label);
});
Container::extensionMethod('addDateTimePicker', function (Container $container, $name, $label = NULL) {
    return $container[$name] = new Controls\DateTimePicker($label);
});
Container::extensionMethod('addTypeahead', function(Container $container, $name, $label = NULL, $callback = NULL) {
    return $container[$name] = new Controls\Typeahead($label, $callback);
});
?>

Komponenta

<?php
$form->addMultiOptionList('roles', 'Vyberte role', $this->roleRepository->findAll()->fetchPairs('id', 'title'));
?>

Latte

{form example}
...
<tr>
            <th>{label roles /}</th>
            <td>
                {foreach $form['roles']->items as $key => $label}
                    {dump $key}
                    {label roles:$key}
                        {input roles:$key}
                    {$label}
                    {/label}
                {/foreach}
            </td>
        </tr>
...
{/form}
David Grudl
Nette Core | 8166
+
+7
-

Tip pro vývojáře doplňků: pokud se chcete vyhnout zbytečnému načítání třídy, místo

Nette\Forms\Container::extensionMethod('addMultiOptionList', ...);

použijte

Nette\Object::extensionMethod('Nette\Forms\Container::addMultiOptionList', ...);