Dynamický závislý select – jak na to

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

Ahoj, potřeboval bych poradit s vykreslením dynamického / závislého selectu: mám jeden selectbox s kategoriemi a druhý dynamický s podkategoriemi. Použil jsem kuchařku slovo od slova, ale nefunguje (form se vykreslí, dle firebugu se data i nový formulář odešlou), ale formulář zabalený ve snippetu se nepřekreslí.

Stejný problém mám se svými kategoriemi – vše se posílá v pořádku, ale závislý selectbox má stále tytéž hodnoty.

Netuší někdo, kde je chyba / co s tím? Funguje někomu to demo dle kuchařky?

Tomáš Votruba
Moderator | 1114
+
0
-

Ahoj, pošli jak to máš, jestli nepůjde něco na první pohled odhalit.

Případně bych doporučil doplněk DependentSelectBox, nedávno aktualizovaný na Nette 2.0 (na gitu), kvůli jehož neaktuálnosti byl návod v kuchařce vytvořen. Ten umožní lepší práci s menším psaním, ve výsledku stačí i něco tak malého:

$form = new Form;
$form->addSelect("car_type","* Tovární značka",$this->carTypes);
$form->addJSelect("car_model","* Model", $form["car_type"],
	function($form) use ($_this) {
        	return $_this->models->cars->getSubtypes($form["car_type"]->value);
	}
);
net-vor
Člen | 35
+
0
-

Díky za tip, na doplněk jsem koukal, ale chtěl bych tomu přijít na kloub přímo v Nette. Mám zhruba:

formulář

protected function createComponentAdForm() {
	$form = new Form;
	$categoryModel = new CategoryModel;
	$form->addSelect("category", "Kategorie:", $categoryModel->allSelect());
	$form->addSelect("ad_in_subcategory", "Podkategorie:", $categoryModel->subcatsSelect());
	$form->addSubmit('submit', 'Uložit');
	$form->onSuccess[] = callback($this, 'adFormNew');
	return $form;
    }

nacucávání dat do subcategory

function handleSelectLoad($category) {
	    $categoryModel = new CategoryModel;
	    $options = $categoryModel->subcatsSelect($category);
	    $form = $this->getComponent("adForm");
	    $form["ad_in_subcategory"]->setItems($options); // set up new values
	    $this->invalidateControl("form"); // invalidate ajax snippet
    }

a v šabloně

{snippet form}
    {control adForm}
{/snippet}

<script type="text/javascript">
    $("form").delegate('#' + {$control["adForm-category"]->htmlId}, 'change', function() {
        $.get("?do=selectLoad", {"category": $(this).val()});
    });
</script>

Po změně kategorie se dle firebugu pošle nový formulář včetně nových hodnot v subcategory, ale bohužel se znova nevykreslí – v subcategory jsou stále staré hodnoty. Za jakoukoli radu a Tvůj čas budu moc vděčný.

net-vor
Člen | 35
+
0
-

[SOLVED] No mohl bych si teď říkat ‚kdybys nebyl hlupákem, nestal by ses medvědem‘. To by někdo nesměl zapomenout si natáhnout zpracovávání Ajaxu/jQuery pro Nette, tím se vše vyřešilo a fachčí to.

Tomáš Votruba
Moderator | 1114
+
0
-

Sry, moje chyba, doplněno.

Senik
Člen | 4
+
0
-

Ahoj, mám podobný problém jako kolega výše, kuchařku jsem přepsal pro svůj web, ale ať vybírám v prvním selectboxu, s druhým to ani nehne. Tady jsou kódy, nevim jestli tam chybu prostě nevidim nebo co dělám špatně.

layout

<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="{$basePath}/js/jquery.nette.js"></script>

formulář (jen krátký kus, jinak je to celkem dlouhý)

protected function createComponentInzeratForm() {
        $form = new Form;
        $presenter = $this;
	$form->addSelect('vyrobce_id', 'Výrobce:', $this->context->createVyrobce()->order('name ASC')->fetchPairs('id', 'name'))
        	->setPrompt('Vyberte výrobce:');
	$form->addSelect('model_id', 'Model:', $this->context->createModel()->order('name ASC')->fetchPairs('id', 'name'))
                ->addRule(Form::FILLED, 'Vyberte model motocyklu!')
                ->setPrompt('Vyberte model:');

nahrání dat do druhého selectu

public function handleSelectLoad($vyrobce) {
        $form = $this->getComponent('inzeratForm'); // our form
        $newModel = $this->context->createModel()->where(array('vyrobce_id' => $vyrobce))->order('name ASC')->fetchPairs('id', 'name');
        $form['model_id']->setItems($newModel); // set up new values
        $this->invalidateControl('form'); // invalidate ajax snippet
    }

a šablona

{snippet}
    {control inzeratForm}
{/snippet}

<script type="text/javascript">
    $("form").delegate('#'+{$control["inzeratForm-vyrobce_id"]->htmlId}, 'change', function() {
        $.get("?do=selectLoad", {"static_id": $(this).val()});
    });
</script>

Když si stránku pustim v Dragonflyi, tak po kliknutí na první select s výrobcem se nic neděje, že by teda chyba někde ve skriptu v šabloně?

pernip01
Člen | 21
+
0
-

Tak právě řeší to samé.

Dostal jsem s k tomu, že požadavek neodejde, přičemž událost odchycena je.
Když si dám

alert($(this).val());

$.get("?do=selectLoad", {"static_id": $(this).val()});

tak mi při změně vyskočí ona vybraná hodnota. Ale následně se požadavek neodešle.

problém by asi mohl být na tomto řádku, ale nevím, proč. JS chybu nehází.

$.get("?do=selectLoad", {"static_id": $(this).val()});

Stáhl jsem si soubor jquery.nette.js a připojil jej do dokumentu.

ViPEr*CZ*
Člen | 817
+
0
-

pernip01 napsal(a):
problém by asi mohl být na tomto řádku, ale nevím, proč. JS chybu nehází.

$.get("?do=selectLoad", {"static_id": $(this).val()});

Stáhl jsem si soubor jquery.nette.js a připojil jej do dokumentu.

Tam je potřeba vložit mezery mezi text a složené závorky (předpokládám, že toto je v latte šabloně).

Senik
Člen | 4
+
0
-

Mezery jsem zkusil přidat, ale stále nic. Navíc mi ten řídek NetBeans podtrhávají, jako by tam byla chyba. Netuším ale, kde by mohla být…

Senik
Člen | 4
+
0
-

pernip01: Už jsi to zprovoznil?

Jinak jsem zjistil, že mi nejspíš neodejde ani událost, protože když použiju kód:

<script type="text/javascript">
    $("form").delegate('#frminzeratForm-vyrobce', 'change', function() {
        alert($(this).val());
        $.get("?do=selectLoad", { "vyrobce": $(this).val()});
        alert($(this).val());
    });
</script>

Tak mi nevyskočí žádná hláška…

Editoval Senik (23. 4. 2012 14:17)