DependencySelectBox – Závislé SelectBoxy

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

romiix.org napsal(a):

Imho nesmysl předávat najednou cca tisíc položek (můj případ využití tohoto doplňku), radši pošlu klientovi jen to, co právě potřebuji.

romiix.org
Člen | 343
+
0
-

iguana007 napsal(a):

romiix.org napsal(a):

Imho nesmysl předávat najednou cca tisíc položek (můj případ využití tohoto doplňku), radši pošlu klientovi jen to, co právě potřebuji.

Veď jasné, klientovi sa pošle len to čo je nutné. To pole by bolo kešované a vždy by sa vracal klientovy iba nasledujúci relevantný selectbox.

Jack06
Člen | 168
+
0
-

Řešíte někdo to, aby se tedy alespoň i postupně zobrazovaly ty selectboxy závislé a ne aby se zobrazily všechny při výběru dat v prvním z X?

Jinak reakce na příspěvek výše: Podle mě by to bylo strašně nepřehledné a blbě by se to cachovalo. A hlavně spousta lidí „běžných“ je zvyklá na obyčejné selectboxy a nebude čekat to, že se jim to pod otevře v tom daném selectboxu, nemluvě o tom, že by to byl problém protože aby se ti to zobrazilo jako podstrom, budeš muset updatovat původní pole a říci že ten prvek má podpole. Zdá se mi to spíše kontraproduktivní nebo minimálně špatně realizovatelné.

Editoval Jack06 (4. 10. 2011 13:55)

Xavy
Člen | 8
+
0
-

Dobrý den,

chtěl bych se zeptat jak nastavit defaultní hodnotu pro JSONDependSelectBox

<?php
$form->addJsonDependentSelectBox('predmet', 'Předmět', array($form['semestr'],$form['obor'],$form['rok']), callback('Specialization::findAllSubject'));

if($this->shortcut != null)  // nefunguje default predmet
          $form->setDefaults(array("obor"=>$this->spec, "rok" => $this->rocnik,"semestr" => $this->semestr, "predmet" => $this->shortcut));
?>

Díky za radu, jsem amatér :-)

mf.jouda
Člen | 5
+
0
-

Mam problem, na ktery jsem videl, ze narazilo vice lidi, ale zatim jsem nevidel funkcni reseni.
Vse funguje ok, pokud mam:

{snippet form}
	{control addStampForm}
{/snippet}

Nikdy se mi ale nezavola AJAXove prenacteni pri vlastnim vykresleni formularu:

{snippet form}
	<div class="form-header"></div>
	<div class="form-body">
        {$addStampForm->render('begin')}
        <table class="form-table">
		<tr>
			<td>{$addStampForm['type']->label}</td>
			<td>{$addStampForm['type']->control}</td>
		</tr>
		<tr>
			<td>{$addStampForm['number']->label}</td>
			<td>{$addStampForm['number']->control}</td>
		</tr>
	        <tr>
        	        <td colspan="2">
                		<div class="form-warning">
					{$addStampForm->render('errors')}
		                </div>
                	</td>
	        </tr>
	        <tr>
        	        <td></td>
                	<td>{$addStampForm['send']->control}</td>
	        </tr>
        </table>
       {$addStampForm->render('end')}
{/snippet}

Nevite prosim nekdo, jak to vyresit? Diky…

frosty22
Člen | 373
+
0
-

mf.jouda: myslím, že je to tím, že nemáš vykreslené submity – při vytvoření komponenty dependecyselect se k formuláři připojí né jedna, ale dvě komponenty – čili je potřeba vykreslit i tu druhou, název komponenty je: $nazevselectu_submit

Čili v tém případě, pokud je „number“ závislý select, tak tam musíš mít ještě někde:

{$addStampForm['number_submit']->control}

Editoval frosty22 (15. 11. 2011 9:24)

frosty22
Člen | 373
+
0
-

Xavy: zkus po nastavení defaultních hodnot zavolat na té komponenty metodu refresh, například:

<?php
$form["predmet"]->refresh();
?>

Editoval frosty22 (15. 11. 2011 9:23)

forkman
Člen | 72
+
0
-

Ahoj, dependentSelectBox jsem použil úspěšně ve starší verzi Nette, ale s aktualní betou pro PHP 5.2 mi to nějak nechce fungovat. Dostávám chybu, která mi přijde trochu nelogická, protože se to přeci skládá se selectBoxů…

Argument 1 passed to FormControlDependencyHelper::__construct() must be an instance of BaseControl, instance of SelectBox given, called in /data/private/web/app/controls/DependentSelectBox/DependentSelectBox.php on line 251 and defined

Mám aktuální verzi z githubu, se starší verzí co mi fungovala jsem dostával zase chyby, že rodičovský selectBox není registrovaný v kontejneru.

Dík moc za radu.

Editoval forkman (18. 11. 2011 10:13)

mf.jouda
Člen | 5
+
0
-

frosty22:
Diky za radu, ale tohle ja tam ted mam, jako workaround prave kvuli tomu, ze mi to nefunguje AJAXove.
{$addStampForm[‚number_submit‘]->control} mi tam prida tlacitko Load – pres ktery to sice funguje, ale ja bych chtel aby se to delo na <input name=„type“ onchange=„!zde!“.

Nejaky jiny napad? Diky…

reskator
Člen | 18
+
0
-

forkman napsal(a):

Ahoj, dependentSelectBox jsem použil úspěšně ve starší verzi Nette, ale s aktualní betou pro PHP 5.2 mi to nějak nechce fungovat. Dostávám chybu, která mi přijde trochu nelogická, protože se to přeci skládá se selectBoxů…

Argument 1 passed to FormControlDependencyHelper::__construct() must be an instance of BaseControl, instance of SelectBox given, called in /data/private/web/app/controls/DependentSelectBox/DependentSelectBox.php on line 251 and defined

Mám aktuální verzi z githubu, se starší verzí co mi fungovala jsem dostával zase chyby, že rodičovský selectBox není registrovaný v kontejneru.

Dík moc za radu.

Mám obdobný problém (používám 2.0beta-PHP 5.3). Nevěděl by náhodou někdo, jak to zprovoznit?

Foowie
Člen | 269
+
0
-

Upraveno pro verzi PHP 5.2/5.3 „version 2.1-dev released on 2012–03–22“

reskator
Člen | 18
+
0
-

Paráda! Díky.

reskator
Člen | 18
+
0
-

frosty22 napsal(a):

mf.jouda: myslím, že je to tím, že nemáš vykreslené submity – při vytvoření komponenty dependecyselect se k formuláři připojí né jedna, ale dvě komponenty – čili je potřeba vykreslit i tu druhou, název komponenty je: $nazevselectu_submit

Čili v tém případě, pokud je „number“ závislý select, tak tam musíš mít ještě někde:

{$addStampForm['number_submit']->control}

Mám podobný problém při vlastním vykreslení formuláře. Pochopil jsem, že to nebude běhat, dokud nevykreslím i tu komponentu submit. Použil jsem tedy následující:

<th><?php echo $form['select2']->label ?></th>
<td><?php echo $form['select2']->control ?></td>
<td><?php echo $form['select2_submit']->control ?></td>

Ale hodí mi tu chybu: „Component with name ‚select2_submit‘ does not exist.“ Netuší někdo, kde je problém?

Foowie
Člen | 269
+
0
-

Ten submit se přidává vždy pro selectbox na kterém jsou ostatní závislé, takže spíše něco jako

<td><?php echo $form['select1_submit']->control ?></td>

(jsou-li DSB závislé na „select2“ tak se omlouvám, ale z popisu není patrné zda-li je select2 závislý nebo závisející selectbox)

Edit: Ostatně můžeš udělat něco jako dump($form->getComponents()); :)

Editoval Foowie (28. 3. 2012 18:59)

reskator
Člen | 18
+
0
-

Tak tohle byla triviální chyba :)

Editoval reskator (29. 3. 2012 13:17)

Tomáš Votruba
Moderator | 1114
+
0
-

Jak definitivně odstranit „Load“ button? Přes jQuery se vždy na chvilku zobrazít a to není pěkné.
Koukal jsem letmo do zdrojáku a je to nějak provázané. Máš tip?

Foowie
Člen | 269
+
0
-

Odstranit, nebo skrýt? Pokud ti jde jenom o lepší skrytí, tak by mohlo fungovat něco jako

<html>
	<head>
		<style>	.dependentControl_submit { display: none; } </style>
		<noscript> <style> .dependentControl_submit { display: block; } </style> </noscript>
	</head>
	<body>
		<input id="frmform-source_submit" class="dependentControl_submit button" type="submit" value="Load" name="source_submit" formnovalidate="formnovalidate">
	</body>
</html>

Pokud bys tam to tlačítko nechtěl vůbec, tak by ho asi stačilo nevykreslovat a lehce upravit javascript. Možná že je na čase se vykašlat na vypnutý JS a přepsat to do použitelnější formy, ale to až po státnicích :)

thorn
Člen | 14
+
0
-

At se snazim, jak se snazim, porad nemuzu rozjet rucni vykresleni, mam stazenou posledni verzi z tohoto roku, kod mam nasledujici:

presenter:

<?php

protected function createComponentAddQuestionsToForm() {

	$presenter = $this;

	$form = new Form($this, 'addQuestionsToForm');
	$form->getElementPrototype()->class('dependentControlForm');

	$form->addSelect("select1", "Norma: ", $this->getValuesSelect1())
		->addRule(Form::FILLED, 'Vyberte normu.');

	$form->addJsonDependentSelectBox("select2", "Region: ", $form["select1"], callback($this, "getValuesSelect2"))
		->addRule(Form::FILLED, 'Vyberte zařazení, minimálně region.');

	$form->addJsonDependentSelectBox("select3", "Element: ", $form["select2"], callback($this, "getValuesSelect3"));

	$form->addJsonDependentSelectBox("select4", "Subelement: ", $form["select3"], callback($this, "getValuesSelect4"))
		->getControlPrototype()->class('dependentControl');

	$form->addSubmit('addToCatalog', 'Zařadit otázky do katalogu');

	$form->onValidate[] = callback($this, 'gatherDataFormSubmitted');

    }
?>

sablona:

<?php
{snippet}
    {form addQuestionsToForm}
	<table>

	<tr>
	    <td>{$form['select1']->label}</td>
	    <td>{$form['select1']->control}</td>
	    <td>{$form['select1_submit']->control}</td>
	</tr>

	<tr>
	    <td>{$form['select2']->label}</td>
	    <td>{$form['select2']->control}</td>
	    <td>{$form['select2_submit']->control}</td>
	</tr>

	<tr>
	    <td>{$form['select3']->label}</td>
	    <td>{$form['select3']->control}</td>
	    <td>{$form['select3_submit']->control}</td>
	</tr>

	<tr>
	    <td>{$form['select4']->label}</td>
	    <td>{$form['select4']->control}</td>
	    <td></td>
	</tr>

	<tr>
	    <td></td>
	    <td></td>
	    <td>{$form['addToCatalog']->control}</td>
	</tr>

    </table>
    {/form}

{/snippet}
?>

Vsechny selecty, ktere maji tlacitko LOAD se mi nezobrazi, ten posledni select4, pac ho nepotrebuje, se jako jediny spolu s tlacitkem addToCatalog zobrazi. Nevi nekdo, kde by mohla byt chyba?? Vubec netusim, v cem by mohl byt problem..

Pokud by mel autor cas, docela bych uvital nejake jeho reseni rucniho vykresleni, zacatecnikum, jako ja, by urcite prozkoumani takoveho, hlavne funkcniho kodu, pomohlo, dekuji :)

Editoval thorn (6. 4. 2012 18:22)

Tomáš Votruba
Moderator | 1114
+
0
-

Nevím, jestli to půjde, ale jako komplexní příklad ti to možná pomůže:

public function parent beforeRender()
{
    parent::beforeRender();

    // register json, enables content change
    DependentSelectBox\JsonDependentSelectBox::tryJsonResponse($this->presenter);
}


/**
 * Select helper
 */
private function getCarModelsByType($form)
{
    $id = $form["car_type"]->value;
    $array = $this->models->car->getModelsByType($id); // return array("key" => "name");

    return $array; // array is required as return type
}

/**
 * Form
 */
protected function createComponentTestForm($name) {

    $form = new Form($this, $name); // required for full running

    $form->addSelect("car_type", "Car type", array("Opel", "Škoda", "BMW"));
    $form->addJSelect("car_model","Model", $form["car_type"], array($this, "getCarModelsByType"));

    $form->onSubmit[] = array($this, "testFormSent");
    $form->addSubmit("submit", "Save");

    return $form;
}


/**
 * Save form
 */
public function testFormSent(Form $form)
{
    if ($form["submit"]->isSubmittedBy()) { // required to avoid submit form on select change
        $values = $form->values;
        // ...
    }
}
pata.kusik111
Člen | 78
+
0
-

Zdravím,
doslat jsem se do naprosto beznadějné situace, kdy se snažím tomuto problému přijít na kloub už více jak týden, prolezl jsem snad všechna vlákna, vyzkoušel jsem znad všechny návody a jediné, co mi fungovalo bylo demo, ale to pro můj vývoj obsahuje starou verzi Nette.

Dostal jsem se do stavu, kdy se mi odešle požadavek, dokonce i přijde správná odpověď (kontrolováno přes firebug), ale hodnoty se mi ve formuláři nevymění. (Musel jsem upravit JSONDependentSelectBox class, aby odkazovala správně do stromové struktury tříd v Nette 2.0.3 stable a přepsal jsem jeden řádek kde místo ‚presenter->terminate($response)‘ je nyní ‚presenter->sendResponse($response)‘. A z nepochopitelného důvodu pokud registruji metodu \Nette\Application\UI\Form->addJselect kdekoliv jinde než v presenteru v metodě createComponent, tak mi Ajax vyhodí vyjímku a neexistující metodě.

Proto ze zoufalstvím prosím někoho, kdo by mohl napsat prodrobný návod konfigurace, pod kterou to funguje a jak se k ní dopracovat a k tomu i příslušné kódy. S Nette 2.0.3 nebo 2.1-dev. Formulář ideálně napsát jako tříd dědící z Nette\Application\UI\Form nebo rovnou do presenteru. Hledám řešení všetně šablony a všech JavaScriptů, které je potřeba naincludovat, jak je případně pozměnit, a v jaké verzi(např JQuery). Zachránilo by mi to život.

Editoval pata.kusik111 (7. 4. 2012 3:56)

Foowie
Člen | 269
+
0
-

Přidal jsem příklad s Nette 2.0.3
Edit: kdyžtak pak napiš kde byla chyba .)

Editoval Foowie (7. 4. 2012 10:25)

thorn
Člen | 14
+
0
-

Moc dekuji za pomoc, demo mi to cele dost ujasnilo, u me byl problem v tom, ze tak, jak jsem to zapsal vyse, udela to, ze to tlacitko LOAD schovava cely radek tabulky, takze nesmi byt na jednom radku s ostatnima a to byl kamen urazu :)

sparky
Člen | 5
+
0
-

Zdravim, snazim se nejak rozbehat tento doplnek a zakousl sem se na tomto:

InvalidArgumentException
Components should be assigned to FormContainer!

na lokalu bezim na php 5.3, ale mam nette s prefixy pro 5.2 kvuli produkcnimu serveru, ktery je jeste na 5.2

ze zdrojaku doplnku sem odmazal vsechny use a namespacea a prejmenoval nette tridy (pridal sem prefix N)

presenter:

<?php

protected function startup(){
	parent::startup();
	DependentSelectBox::register('addDependentSelectBox');
}

protected function createComponentAddForm($name){
	$form = new NAppForm($this, $name);
	$form->addSelect('type', 'Typ odkazu', $this->context->MenuItemTypeRepository->enabled());
	$form->addDependentSelectBox('select2', 'Select 2', $form->getComponent('type'), callback($this, 'c'));//provizorni callback
	$presenter = $this;
	if($this->isAjax()) {
		$form['select2']->addOnSubmitCallback(callback($this, 'c')); // jenom provizorni
	$form->addSubmit('submit', 'Uložit');
	$form->onSuccess[] = array($this, 'addFormSubmitted');
}
?>

chovalo se to stejne i kdyz sem tam mel anonymni fci co tam byla v demu

<?php
class DependentSelectBox extends NSelectBox{
	public static function formAddDependentSelectBox($_this, $name, $label, $parents, $dataCallback){
		return self::Container_prototype_addDependentSelectBox($_this, $name, $label, $parents, $dataCallback);
	}

	public static function Container_prototype_addDependentSelectBox(NFormContainer $obj, $name, $label, $parents, $dataCallback){
		return $obj[$name] = new DependentSelectBox($label, $parents, $dataCallback);
	}

	public static function register($methodName = "addDependentSelectBox"){
		if(NETTE_PACKAGE == 'PHP 5.2 prefixed')
			NFormContainer::extensionMethod('NFormContainer::addDependentSelectBox', 'DependentSelectBox::formAddDependentSelectBox');
		else
			NFormContainer::extensionMethod($methodName, "DependentSelectBox::Container_prototype_addDependentSelectBox");
	}
?>

Nema nekdo nejaky napad co tam mam za chybu?

Lota
Člen | 38
+
0
-

Rád bych požádal o radu.
V bootstrapu mám:

FormContainer::extensionMethod('FormContainer::addDependentSelectBox', 'DependentSelectBox::formAddDependentSelectBox');

Komponenta, kde vytvářím formulář:

protected function createComponentNovinka(){
        $form = new AppForm();

        $form->addText("nazev", "Název: ")
                ->addRule(Form::FILLED, "Musíte vyplnit název novinky.");

        $menu = Menu::getMainMenuPairs();

        $form->addSelect("category", "Kategorie: ", $menu)
                ->addRule(Form::FILLED, "Vyberte kategofii")
                ->skipFirst("-- vberte kategorii --");
        $form->addDependentSelectBox("subCategory", "Podkategorie: ", $form["category"], array($this, "getValues"));
        $form->addFile("foto", "Foto:");
        $form->addTextArea("text", "Text: ")
                ->getControlPrototype()->addClass("mceEditor");



        $form->addSubmit("ulozit", "Uložit");
        $form->getElementPrototype()->onsubmit('tinyMCE.triggerSave()');
        $form->onSubmit[] = callback($this, $akce);

        if($this->isAjax()) {
            $form["subCategory"]->addOnSubmitCallback(array($this, "invalidateControl"), "form");
        }

        return $form;
    }

Bohužel, pokud chci vypsat formulář, tak naskočí error 500 a v logu mám od laděnky vzkaz: MemberAccessException Call to undefined method DependentSelectBox::setPrompt().
ř. 346 v souboru DependentSelectBox.php.

Chápu, že to chce metodu setPrompt, která tam není, ale kde ji mám vzít? Dopsat? Co má dělat?

PHP 5.3
Nette version 2.0-dev released on 2011–02–06

Editoval Lota (9. 6. 2012 16:35)

llook
Člen | 407
+
0
-

>

Bohužel, pokud chci vypsat formulář, tak naskočí error 500 a v logu mám od laděnky vzkaz: MemberAccessException Call to undefined method DependentSelectBox::setPrompt().
ř. 346 v souboru DependentSelectBox.php.

Chápu, že to chce metodu setPrompt, která tam není, ale kde ji mám vzít? Dopsat? Co má dělat?

PHP 5.3
Nette version 2.0-dev released on 2011–02–06

SetPrompt má dělat totéž, co skipFirst (viz), ale jinak bych radil stáhnout si novější Nette.

Lota
Člen | 38
+
0
-

To bohužel nemohu, protože jakákoliv jiná verze Nette mi nefunguje. Hází mi to pak server error 500 a nedaří se mi zaboha přijít na to v čem je problém. Musím si vystačit s tímto.

Můj problém se zavislým selectem jsem vyřešil takto https://blog.nette.org/…-and-pure-js

Tohle řešení mi do teď přepisovalo celý formulář, ale to jsem už vyřešil také

<td>{snippet form}{$novinka['subCategory']->control}{/snippet form}</td>

Jediné s čím si tedy ještě pořád nevím rady je proč mi nejde jiná verze nette, ale to je diskuse asi do jiného vlákna.

duskohu
Člen | 778
+
0
-

Ahojte viete mi poradit chcel som si rozbehat tento doplnok v formulari krory je v komponente,
stiahol som si demo a snazil prerobit ale asi zle, mozete mi napisat co mam zle??
napisem tu podtup ako som to robil:

1. libs/Nette/Forms/DependentSelectBox/
nakopirival:

JsonDependentSelectBox.php
jquery.nette.dependentselectbox.js
FormControlDependencyHelper.php
DependentSelectBox.php

2. do js som dal to co treba :-)

3. bootstrap.php

\Nette\Forms\Container::extensionMethod("addDependentSelectBox", "DependentSelectBox\JsonDependentSelectBox::formAddDependentSelectBox");

4.Presenter

public function beforeRender() {
	parent::beforeRender();
	DependentSelectBox\JsonDependentSelectBox::tryJsonResponse($this->presenter);
}

5. Presenter >> zavolam si komponentu

protected function createComponentKomponenta()
{
  return new KomponentaFormular();
}

6. Komponenta KomponentaFormular

public function createComponentMojFormular()
{
	$form = new Form();
	$form->addSelect('select1', 'Select 1', array('A' => 'A', 'B' => 'B', 'C' => 'C'));

	$form->addDependentSelectBox('select2', 'Select 2', $form['select1'], function($form) {
		$v = $form['select1']->getValue();
		return array("$v 10" => "$v 10", "$v 20" => "$v 20", "$v 30" => "$v 30");
	});

	if($this->getPresenter()->isAjax()){
		$form["select2"]->addOnSubmitCallback(array($this->getPresenter(), "invalidateControl"), "jsonFormSnippet");
	}
	$form->addSubmit('create', 'Vytvořit');
	$form->onSuccess[] = callback($this, 'MojFormularSubmitted');
	return $form;
}

7. latte sablona komponenty

{snippet jsonFormSnippet}
  {control mojFormular}
{/snippet}

takze ked mam toto formular mi vykresli ale ked dam zmenit select1 tak sa nic nestane
Zapnem firebug a tam mi posle request ale, ten neprejde akurat mi vrati: 500 Internal Server Error

urcite som nico zle urobil ale neviem co, viete mi poradit? dakujem :-)

one-two
Člen | 80
+
0
-

Mám Nette 2.0.5 a měl sem problém při zpětném výběru v selectboxu, nějak chaoticky to pak začalo vybírat. Fixnul sem to přepsáním původních metod getValue a setPrompt z třídy SelectBox z verze Nette 2.0beta. Asi to neni uplně nej řešení, ale neměl sem čas to řešit, takže dávám tímto menší notifikaci o problému :)

tivvit
Člen | 36
+
0
-

Ahoj,

DependentSelectBox při použití jQuery 1.9.0 hází chybu:
Uncaught TypeError: Object [object Object] has no method 'live'

Zkoušel jsem to i v demu ze stránky adonu (https://componette.org/search/?…)
Dělám nějakou chybu a pokud ne, poradí mi někdo jak to fixnout nebo to mám nahlásit jako issue autorovi?

David Matějka
Moderator | 6445
+
0
-

.live() bylo v jQuery 1.9 odstraneno, vice na http://api.jquery.com/live/

je tam i info jak to můžeš nahradit. j nahlaš to jako issue, zatim to buď můžeš opravit nějakým z těch způsobů popsaných na webu jquery (on, delegate..) nebo použít starší jquery

Quinix
Člen | 108
+
0
-

Zdravím, pokud použiju tenhle doplněk a volám při definici setDefaultValue, callback pro získání prvků se volá 3×. Není to trochu mockrát? :) V callbacku na získání prvků šahám do databáze, takže místo 1 dotazu se provedou tři… je to bug, nebo dělám něco blbě?

$form->addSelect("building", 'Budova', $buildings)
            ->setDefaultValue(1);
        $form->addDependedSelect('floor', 'Podlaží', $form['building'], callback($this, 'getFloorDictionary'))
            ->setDefaultValue($floor->id);
//addDependentSelect vytváří instanci JsonDependentSelectBox
dada-amater
Bronze Partner | 52
+
0
-

Ahoj,

narazil jsem myslim na BUG. Problem je v tom, ze mi to odesilalo formular jen tim, jak jsem menil hlavni selectbox a chtelo si to nacitat ty zavisle. To tlacitko Load je take submit tlacitko a je u nej vypnuta validace: $this->button->setValidationScope(false). Jenze kdyz formular odeslete, tak i bez kontroly validace formulare zavola metody, ktere jste si definovali v $form->onSuccess[] = callback( $this, ‚formSubmited‘ ). Cili metoda formSubmited($form) je volana i kdyz je formular nevalidni, a to jen proto, ze se tam pouziva DependencySelectBox. Pouzivam ajax verzi tohoto doplnku.

Podle me by bylo nejlepsi, kdyby nette nikdy nedovolilo volat onSuccess metody, pokud neni formular validovan. To je ale otazka pro DG, treba je to k necemu dobry.

Resim to takto:

<?php
	if($form->isSubmitted() && !$this->presenter->isAjax() && $form->isValid())
		$form->onSuccess[] = callback( $this, 'formSubmited' );
?>

Jedina nevyhoda je, pak nelze odesilat formulare ajaxove, coz je ale jedno, protoze stejne po odeslani formulare by melo dojit k presmerovani.

Editoval dada-amater (7. 5. 2013 16:14)

Foowie
Člen | 269
+
0
-

Osobně používám raději $form->addSubmit("submit", "Save")->onClick[] = callback($this, 'submitForm');. Nejsou s tím takové problémy jako s $form->onSuccess.

dada-amater
Bronze Partner | 52
+
0
-

Foowie napsal(a):

Osobně používám raději $form->addSubmit("submit", "Save")->onClick[] = callback($this, 'submitForm');. Nejsou s tím takové problémy jako s $form->onSuccess.

A co kdyz ti nekdo odesle formular pres ENTER?

David Matějka
Moderator | 6445
+
0
-

ten problem, pres ktery button jde odeslat form resim takto:
mam zdedenej Nette\Application\UI\Form:

class Form extends \Nette\Application\UI\Form
{
    public function onSuccess(Form $form)
    {
        try {
            parent::onSuccess($form);
        } catch (AbortExecutionException $e) {

        }
    }

    public function abort()
    {
        return new AbortExectionException;
    }
}

class AbortExecutionException extends \Exception { }

potom pri vytvareni formu:

$form->addSubmit('foo', 'Bar');
$form->addSubmit('save', 'Save');
$form->onSuccess[] = function($form) {
	if(!$form['save']->isSubmittedBy()) {
		$form->abort();
	}
$form->onSuccess[] = callback($this, 'formSubmitted');
}

takze ten druhy onSuccess se provede pouze kdyz bylo kliknuto na button save

dada-amater
Bronze Partner | 52
+
0
-

Furt si myslim, ze by bylo fajn, kdyby to fungovalo podle ocekavani a onSuccess by se volal az v pripade uspesne validace, viz dokumentace Handlery událostí onSuccess a onClick se volají pouze v případě, že je odeslání validní. Uvnitř obslužných metod tedy nemusíme validitu ověřovat

David Matějka
Moderator | 6445
+
0
-

uspesna validace vs. odeslani je validni.
odeslani je validni, i presto, ze validace neni uspesna (respektive se neprovedla),jelikoz pomoci ->setValidationScope(FALSE) jsem rek, ze se validovat nema :)

kdyby se po setValidationScope(FALSE) neprovadelo onSuccess bylo by to MNOHEM vic matouci, jelikoz by se delo uplne neco jinyho, nez je ocekavano.

imho by bylo nejlepsi, kdyby sel nastavit na buttonu dalsi priznak, ktery by prave rikal, ze se nema provadet onSuccess udalost.

dada-amater
Bronze Partner | 52
+
0
-

Je to asi vec nazoru :-). Pokud nepotrebuji validovat, tak to povesim na $form->onSubmit[]. No proste se mi to nelibi, jen jsem chtel aby ostatni vedeli, ze tam kde ted meli jeden submit a validovalo se vzdy, takze se to pouzitim DependencySelectBox muze rozbit, protoze se jim formular odesila zmenou v selectu. A to je podle me dulezity vedet.

vichpetr
Člen | 11
+
0
-

Ahoj,

zkoušel jsem z dependencySelectBox upravit jak multiSelect pomocí jQuery.multiselect() …

Po výběru první položky se formulář nahraje znovu (to funguje), ale pak už nereaguje na žádné změny … můžete mi prosím poradit?

Díky

duskohu
Člen | 778
+
0
-

Funguje vam tento doplnok na nette 2.1. dev? Asi koli zmene formularov toto: https://github.com/…selectbox.js#L31 generuje zle ID

Editoval duskohu (18. 8. 2013 12:39)

czm4rty
Člen | 29
+
0
-

Hot fix:

private $buttons;

public function __construct($label, $parents, $dataCallback) {
	...
	foreach ($parents as $parent) {
	...
        $this->buttons[] = $dependencyHelper;
	...
    }
	...
}
protected function attached($form) {
    parent::attached($form);
    foreach($this->buttons as $button) {
        $button->getButton()->htmlId;
    }
    $this->processAttaching($form);
}

Editoval czm4rty (18. 8. 2013 20:25)

czm4rty
Člen | 29
+
0
-

Já bych naopak potřeboval poradit, jak zprovoznit doplněk s nette.ajax.js.

Na tomto řádku mi to hlásí chybu: Uncaught TypeError: Object [object Object] has no method ‚success‘
jquery.nette.dependentselectbox.js

Nevím, jak zavolat metodu success u ext snippets.

Foowie
Člen | 269
+
0
-

Chyba s HTML ID opravena.

darthcz
Člen | 113
+
0
-

Chci se zeptat, zda by bylo možné udělat tento doplněk instalovatelný přes composer tzn. zda by bylo možné hodit ho na packagist.org. Nějak se mi ho nepodařilo rozchodit, pokud ho přes composer stahuju přímo z gitu. Autoloader composeru mi nenalezne třídy. Nyní ho mám ručně stažený, což mě ale moc netěší, když mám všechny ostatní závislosti spravované composerem.

Také bych ocenil, kdyby text tlačítka ,,Load" byl nějak konfigurovatelný, protože na česky psaném webu s vypnutým javascriptem tlačítko ,,Load" nepůsobí vůbec dobře.

Foowie
Člen | 269
+
0
-

@darthcz: Až budu mít chvilku tak to na packagist hodím. A co se týká textu tlačítka, jednotlivě to lze měnit pomocí $form['PARENT_SELECTBOX_NAME_submit']->caption = 'Načíst';

darthcz
Člen | 113
+
0
-

Foowie napsal(a):

@darthcz: Až budu mít chvilku tak to na packagist hodím. A co se týká textu tlačítka, jednotlivě to lze měnit pomocí $form['PARENT_SELECTBOX_NAME_submit']->caption = 'Načíst';

super, díky :)

besir
Člen | 170
+
0
-

Ahoj, doufám, že mi ještě někdo po takové zareaguje, ale mam pro mě vcelku záhadný problém a sice mam zatim 1hlavni a jeden zavisly selectbox. Formulář se v pohodě odešle ajaxem a dostanu response, jenže špatnou. Pokud se podivam do callbacku ktery je zaveseny na DependentSelectBox tak v nem je hodnota hlavniho selectu shodna s defaultni hodnotou. Po trosce debugovani jsem zjistil, ze se ten callback ve skutecnosti zavola 3× a sice dostava tyto hodnoty: 1. prvni polozku parentniho selectboxu, 2. defaultni hodnotu, 3. vybranou hodnotu, ale vysledek je takovy, ze vzdy dostanu vysledek pro defaultni hodnoty.

Kod – Form: (je to bastl na rozchozeni)

public function createComponentEditMenuItemForm()
	{
		$form = new \Nette\Application\UI\Form();
		$form->addText('name', 'Jméno');
		$form->addSelect('presenterName', 'Modul', $this->getMenuItemFormValuesModules())->setPrompt('Vyber');
		$form->addDependentSelectBox('action', 'Akce', $form['presenterName'], array($this, 'findModulesActions'));
		$form->addText('url', 'Url');
		$form->addCheckbox('homepage', 'Homepage');
		$form->addSelect('parent', 'Rodič', $this->getMenuItemFormValuesParents())->setPrompt('');
		$form->addCheckbox('published', 'Publikováno');
		$form->addText('class', 'CSS třída odkazu');
		$form->addHidden('menu_id');

		$form->setDefaults($this->getMenuItemFormDefaults());

		$form->addSubmit('submit', 'Uložit');
				$form->onSuccess[] = array($this, 'validateSubmitButton');

		$form['action']->refresh();

		return $form;
	}

Kod – callback:

public function findModulesActions(\Nette\Application\UI\Form $form)
	{
		$values = $form->getValues();
		// Nejedna se o presenter, ale vracenou hodnotu z formu (jen aby to nematlo ;-)
		if ($values->presenterName == 'Front:Contact')
		{
			return array('foo' => 'foo');
		}
		else
		{
			return array('bar' => 'bar');
		}
		$this->getPresenter()->invalidateControl('formSnippet');
	}

Verze nette: 2.0.13

Díky za pomoc, už jsem zoufalý :-(

Foowie
Člen | 269
+
0
-

Jenom rychlá otázka, $form = new \Nette\Application\UI\Form($this, $name); nepomůže?

besir
Člen | 170
+
0
-

Ja jsem vul :D, diky @Foowie

kralik
Člen | 230
+
0
-

Ahoj,
nějak si nevím rady a chtěl bych prosím poradit.
Bude to určitě nějaká prkotina, ale nemůžu na ni přijít.
Zkouším tuto komponentu s Nette 2.0.6. a PHP 5.4.14

Presenter:
Funkční

<?php
protected function createComponentFormAddDoc($name) {

        $form = new UI\Form($this,$name);
        ...
        $form->addSelect('oddeleni', 'Oddělení', $odd);
                ->addRule(UI\Form::FILLED);
        $form->addJSelect('wf', 'Workflow', $form['oddeleni'], function($form) {
                $v = $form['oddeleni']->getValue();
                return array("$v 10" => "$v 10", "$v 20" => "$v 20", "$v 30" => "$v 30");
                });
?>

Výše uvedené v pohodě funguje, ale když načtu data z Modelu, tak změná hodnot v závislém SB neproběhne.

Nefunkční
Presenter

<?php
protected function createComponentFormAddDoc($name) {

        $form = new UI\Form($this,$name);
        ...
        $form->addSelect('oddeleni', 'Oddělení', $odd);
                ->addRule(UI\Form::FILLED);
        $form->addJSelect('wf', 'Workflow', $form['oddeleni'], function($form) {
                $v = $form['oddeleni']->getValue();
                $wf = $this->mainModel->getFormValWf($v);
                return $wf;
                });
?>

mailModel

<?php
public function getFormValWf($v) {
        return array("$v 10" => "$v 10", "$v 20" => "$v 20", "$v 30" => "$v 30");
}
?>

Moc díky za pomoc