Dynamický závislý select – jak na to
- net-vor
- Člen | 35
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
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
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
[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.
- Senik
- Člen | 4
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
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
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
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)