DependencySelectBox – Závislé SelectBoxy
- Foowie
- Člen | 269
@**p3s**: No, jelikož nastavuješ hodnotu jenom rodičovskému selectboxu, tak navazující DSB nemá jak zjistit, že se hodnota změnila. (A nemám čas to aktuálně opravovat). Takže v tom případě uprav action metodu takto:
public function actionDefault() {
$this["form"]->setDefaults(array("select1" => '|', ));
$this["form"]["select2"]->refresh();
}
- cuga
- Člen | 210
chtel bych se zeptat, chystas se pridat podporu pro pripad, kdy dva selectboxy zaviseji na spolecnem prvku?
tzn:
$form->addDependentSelectBox("select2", "Výběr 2", $form["select1"], array($this, "getValuesSelect2"));
$form->addDependentSelectBox("select3", "Výběr 3", $form["select1"], array($this, "getValuesSelect3"));
Editoval cuga (15. 1. 2011 19:04)
- tom
- Člen | 171
Chci se zeptat, když nepoužiju „jquery.nette.dependentselectbox.js“ zobrazí se mi tlačítko Load a vše funguje – selectboxy se vzájemně ovlivňují. Ale jakmile přidám „jquery.nette.dependentselectbox.js“, tlačítko Load sice zmizí, ale selectboxy se mi svázat nepodaří.
Kde hledat chybu?
Dík
- Foowie
- Člen | 269
@**tom**: Tak pokud používáš poslední verzi nette tak se pokusím popsat co má dělat ten JS.
Nejdříve si teda zkontroluj, jeslti ti firebug nehází žádnou chybu. Pokud ano, jakou?
Po načtení dokumentu se zavolá initialize. To zavolá hideSubmits, které
skryje všechny submity od DSB.
Zavěsí se callback při změně nějakého DSB. (tady bych to otestoval
alertem jeslti funguje reakce na změnu). Při vyvolání tohoto callbacku se
provede nejdříve fix pro nette validátory a potom se provede ajaxSubmit
pomocí daného tlačítka. (Zase zkontrolovat jestli se provede ajax
requesest)
Po dokončení ajax requestu se zavolá metoda jsonResponse, (ta kontroluje
navrácená data jestli nejsou od JsonDependentSelectBox
u) když
ne, volá se standardně $.nette.success(payload);
Takže žádné zázraky to nejsou. Pokud se ajax request provede, mrkni jeslti je relevantní vrácený obsah (jestli invaliduješ správné snippety apod.)
- Foowie
- Člen | 269
Tak se pokus vypsat řetězec
'#'+($(this).attr('id'))+$.dependentselectbox.buttonSuffix
. Mělo
by to být něco ve stylu #frmform-select2_submit
a pak jeslti
takový prvek ve formuláři v html kódu s daným ID existuje (submit).
Pokud OK, odstranit z příkazu
$.dependentselectbox.jsonResponse
, jestli se něco nezmění.
Teďka pokud to nefunguje a vůbec to nezavolá ajaxSubmit tak netuším
… :)
- tom
- Člen | 171
@Foowie: … jojo ten řetězec mám správně i ten buton tam je. Přišel jsem teď na to, že když místo $.dependentselectbox.jsonResponse použiju $.dependentselectbox.jsonResponse() viz
<script>
$('#'+($(this).attr('id'))+$.dependentselectbox.buttonSuffix).ajaxSubmit($.dependentselectbox.jsonResponse());
</script>
tak se aspoň dostanu dál až do jsonResponse: function(payload) :-) jenže tady když si hned na začátku vypíšu alert(payload); tak mi vrátí že payload není definován, takže problém budu mít asi někde tady …
Všiml jsem si, že když celý ten form odešlu pomocí tlačítka, tak to funguje … budu si muset pořádně nastudovat ajax :-)
- tom
- Člen | 171
Mám zatím pokusnou komponentu
<?php
class VyberProdejny extends NControl
{
public $hodnoty;
public function submitForm( $button )
{
$this->hodnoty = $button->form->values;
}
public function render()
{
$this->template->hodnoty = $this->hodnoty;
$this->template->setFile(dirname(__FILE__) . '/vyberprodejny.phtml');
$this->template->registerFilter(new NLatteFilter);
$this->template->render();
}
public function createComponentProdejnyForm($name)
{
$form = new NAppForm($this, $name);
$form->addSelect("select1", "Výběr 1")->setItems(array("1" => "Value = 1", "2" => "Value = 2", "3" => "Value = 3"));
$form->addDependentSelectBox("select2", "Výběr 2", $form["select1"], array($this, "getValuesSelect2"));
if($this->presenter->isAjax())
$form["select2"]->addOnSubmitCallback(callback($this, "invalidateControl"), "prodejnySnippet");
$form->addSubmit("final_submit", "Hodnoty !")
->onClick[] = array($this, "submitForm");
}
public function getValuesSelect2( $form )
{
return array(
"A" => $form["select1"]->getValue() . " - A",
"B" => $form["select1"]->getValue() . " - B",
"C" => $form["select1"]->getValue() . " - C",
);
}
}
?>
kterou zobrazuji
<?php
{snippet prodejnySnippet}
{widget prodejnyForm}
{/snippet}
?>
V presenteru mám továrnu
<?php
public function createComponentVyberProdejny($name)
{
$vp = new VyberProdejny($this, $name);
return $vp;
}
?>
a v šabloně
<?php
{widget vyberProdejny}
?>
používám prefixovou verzi Nette 2.0
- colek
- Člen | 59
ahoj, chtěl jsem si to vyzkoušet, tak jsem použil stejný kód jako (https://forum.nette.org/…e-selectboxy#…)
všechno funguje tak jak má, po změně prvního selectboxu se upraví i ten druhý. jen se mi pod prvním selectem ukáže zbytečně tlačítko load – ke změně již došlo a v examples se to neukazuje :)
nevíte kdy bych mohl hledat chybku?
díky
- colek
- Člen | 59
měl bych ještě dotaz, jak tp rozchodit, pokud mám formulář v kontejneru plněného v nějakém cyklu
háže mi to chybu Component with name ‚select1_submit‘ already exists.
$form = new AppForm($this, $name);
$i = 0;
foreach ($inserted as $key => $val){
$i++;
$name = 'container';
$container = $form->addContainer($name);
$category = Model::fetchPairsCategory();
$container->addSelect("select1", "Kategorie")->setItems( $category );
$kind = Model::fetchPairsKind();
$container->addSelect("select2", "Druh")->setItems( $kind );
$container->addDependentSelectBox("select1_1", "1", array($container["select1"], $container["select2"] ), array($this, "getValuesSelect1"));
$container->addDependentSelectBox("select1_2", "2", $container["select1"], array($this, "getValuesSelect2"));
if($this->getPresenter()->isAjax()){
$container["select1_1"]->addOnSubmitCallback(array($this->getPresenter(), "invalidateControl"), "formb");
$container["select1_2"]->addOnSubmitCallback(array($this->getPresenter(), "invalidateControl"), "formb");
}
}
- colek
- Člen | 59
díky moc…
když jsem poladil všechny ostatní chyby, které jsem tam měl, nepřejdu přes parametr, kde zadávám závislosti.
Tj. – pokud přidám selectbox závislý na boxu 1 a selectbox závislý na 2, je to v pohodě. Pokud bude ale druhý závislý na 1 i 2, neprojde to.
takhle nějak to mám, snad ti tím ušetřím pár vteřin času :)
private $counter = 1;
protected function createComponentFormb($name)
{
/** registace atd... $inserted... **/
$form = new AppForm($this, $name);
$i = 0;
foreach ($inserted as $key => $val){
$i++;
$name = 'container'.$i;
$container = $form->addContainer($name);
$category = RankModel::fetchPairs();
$container->addSelect("select1", "Kategorie")->setItems( $category );
$kind = RankModel::fetchPairsKind();
$container->addSelect("select2", "Druh")->setItems( $kind );
$container->addDependentSelectBox("select1_1", " 1", array($container["select2"]), array($this, "getValuesSelect1"));
//nelza zadat pole s více prvky
// $container->addDependentSelectBox("select1_1", " 1", array( $container["select2"] , $container["select1"] ), array($this, "getValuesSelect1"));
$container->addDependentSelectBox("select1_2", " 2", $container["select1"], array($this, "getValuesSelect2"));
if($this->getPresenter()->isAjax()){
$container["select1_1"]->addOnSubmitCallback(array($this->getPresenter(), "invalidateControl"), "formb");
$container["select1_2"]->addOnSubmitCallback(array($this->getPresenter(), "invalidateControl"), "formb");
}
}
$form->addSubmit("final_submit", "Hodnoty !")
->onClick[] = array($this, "submitForm");
return $form;
}
public function getValuesSelect1( $array ) {
$id = $this->counter;
$category = $array["container$id"]["select1"]->getValue();
$kind = $array["container$id"]["select2"]->getValue();
$rank = RankModel::fetchPairsByCategoryKind($category,$kind);
return $rank;
}
public function getValuesSelect2( $array ) {
$id = $this->counter;
$category = $array["container$id"]["select1"]->getValue();
$rank = RankModel::fetchPairsByCategory($category);
$this->counter++;
return $rank;
}
- romiix.org
- Člen | 343
Zdravím,
v prvom rade ďakujem za tento skvelý počin..
Premýšľam nad využitím, žiaľ nejak neviem či je táto komponenta
použiteľná pre moje „zadanie“.
Potrebujem prechádzať stromovú štruktúru s „nestabilným“ počtom levelov – konkrétne MENU. Proste nie je dopredu známe koľko selectov na stránke bude, bude to závislé na predošlých hodnotách.
Tým pádom teda bude treba odkrývať nasledujúce selecty postupne.
Riešili Ste niečo podobné? Máte nejaký nápad ako na to?
Vďaka!
Editoval romiix.org (6. 3. 2011 21:42)
- romiix.org
- Člen | 343
mm-marek napsal(a):
Tak toto sa mi teda nepodarilo skombinovať.
Budem to musieť vymyslieť inak :(
- bazo
- Člen | 620
ahoj,
tento doplnok je super ale mam problem: pri ajaxovom odoslani formularu, je hodnota zavisleho selectboxu vzdy null. ak vypnem js, tak hodnota sa odosle v poriadku. form pouzivam v komponente, ale to by nemal byt problem.
v definicii formulara:
<?php
$deliveryMethods = $shippingModel->fetchMethods($this->countryId, array('id', 'name'));
$form->addSelect('delivery_type', 'Delivery type', $deliveryMethods);
$form->addDependentSelectBox('payment_type', 'Payment type', $form['delivery_type'], array($this, 'getPaymentTypes'));
if($this->presenter->isAjax())
$form["payment_type"]->addOnSubmitCallback(array($this, "invalidateControl"), 'formOrderPropertiesSnippet');
?>
nacitavanie hodnot zavisleho selectu
<?php
public function getPaymentTypes(AppForm $form, DependentSelectBox $dependentSelectBox)
{
$values = $form->getValues();
$transportId = $values['delivery_type'];
$paymentsModel = new PaymentModel();
$paymentTypes = $paymentsModel->getPaymentTypesForTransport($transportId);
return $paymentTypes;
}
?>
hodnoty sa mi nacitaju v poriadku, aj pri nasledovnom tvoreni formulara su spravne zadefinovane, takze by sa mali odosiela ale hodnota payment_type je vzdy null pri ajaxe
form vykreslujem manualne v includovanej sablone
sablonu controlu
{snippet formOrderPropertiesSnippet}
{include 'formOrderProperties.phtml', form => $control['formOrderProperties']}
{/snippet}
sablona formOrderProperties
{control formOrderProperties begin}
{control formOrderProperties errors}
ine policka...
<table>
<tr>
<th>{$form['delivery_type']->label}</th><td>{$form['delivery_type']->control}</td>
</tr>
<tr>
<td>{$form['delivery_type_submit']->control}</td>
</tr>
<tr>
<th>{$form['payment_type']->label}</th><td>{$form['payment_type']->control}</td>
</tr>
<tr>
<th>{$form['compare_count']->label}</th><td>{$form['compare_count']->control}</td>
</tr>
<tr>
<th>{$form['status']->label}</th><td>{$form['status']->control}</td>
</tr>
<tr>
<td>{$form['btnSubmit']->control}</td>
</tr>
</table>
</div>
{control formOrderProperties end}
dependentselectbox verzia z githubu, nette 2.0 alpha
v com moze byt chyba? diky
- tenerd
- Člen | 15
Myslim, ze to bude asi tenhle bug – https://forum.nette.org/…vana-sablona.
Zkus odendat ten include a nakopiruj to do jedne sablony jestli to bude fungovat.
- maChy
- Člen | 9
Mám jeden velký formulář a při změně závislé položky se mi validuje následující položka místo znovunačtení stránky. Pokud odlinkuji netteForms.js fak vše funguje jak má, ale nefunguje js validace. Nette 2.0 v 5.2
s js moc nekamarádím tak nevím jak přidat validaci na všechny submity kromě toho od DependSelectBoxu :/
- tenerd
- Člen | 15
maChy napsal(a):
Mám jeden velký formulář a při změně závislé položky se mi validuje následující položka místo znovunačtení stránky. Pokud odlinkuji netteForms.js fak vše funguje jak má, ale nefunguje js validace. Nette 2.0 v 5.2
s js moc nekamarádím tak nevím jak přidat validaci na všechny submity kromě toho od DependSelectBoxu :/
Zkus použít nejnovější netteForms.js.
- maChy
- Člen | 9
tenerd napsal(a):
maChy napsal(a):
Mám jeden velký formulář a při změně závislé položky se mi validuje následující položka místo znovunačtení stránky. Pokud odlinkuji netteForms.js fak vše funguje jak má, ale nefunguje js validace. Nette 2.0 v 5.2
s js moc nekamarádím tak nevím jak přidat validaci na všechny submity kromě toho od DependSelectBoxu :/
Zkus použít nejnovější netteForms.js.
nepomohlo :(
- kashpi
- Člen | 48
Mám problém a nikde jsem tu nenašel řešení.
Dá se nějak udělat aby se odeslal formulář po stisknutí klávesy Enter?
V normálním formuláři to jde, ale když to udělám ve formuláři kde je
DependentSelectBox, tak hodnoty z těchto boxů jsou nulové. Dělám někde
chybu, nebo to je nějaká orchrana?
- Ja
- Člen | 260
Zdravim,
objevil se mi pri rozjizdeni teto komponenty takovy problem.
Jakmile zmenim select1, cely form se invaliduje a prekresli (to je v poradku). Ale zmizi mi veskere javascripty (tzn. objevi se pod select1 tlacitko LOAD) a ani se mi nepripoji na textareu CKEDITOR.
Je to velice zvlastni problem a ani si nejak nejsem jist, kde bych problem mel hledat, nebo jake vystupy z firebugu vam posilat?
- Foowie
- Člen | 269
Celý formulář se ajaxem načte znova (snippet). Měl by sis tedy přečít hlavičku JS souboru (musíš bindování JS vlastností provést po ajaxovém požadavku znova)
- Ot@s
- Backer | 476
Navrhuju nasledující vylepšení této kompnenty. Celá myšlenka je o tom, že pomocné submit buttony zaobaluju do tagu <noscript>. Z hlediska sémantiky by to tak i mělo být. Bonusem se získá přehlednější a na implementaci méně náročný JS. Uvádím pouze změny:
- Zaobalení submit buttonů (vázaných k závislým selectboxům) do <noscript>
- ruční renderování formuláře – do šablony se za závisle selectboxy vloží ručně (… nazev/ID SELECTu)
<noscript>{$filters["..._submit"]->control}</noscript>
- v metodě createButton() (ve FormControlDependencyHelper.php) asi přidat (nezkoušel jsem)
// za tento radek:
$this->button = new SubmitButton($this->buttonText);
// tento radek pridat
$this->button->setOption('container', \Nette\Web\Html::el('noscript'));
- Úprava jquery.nette.dependentselectbox.js, resp. funkce initialize (oprava z níže uvedených reakcí):
//....
initialize: function() {
var counter = 0;
$('.'+$.dependentselectbox.controlClass).live('change', function() {
var form = $(this).closest('form');
// Nette form validation
var button_id = form.attr('id')+$.dependentselectbox.buttonSuffix+counter;
$(this).closest('form').append('<input type="submit" formnovalidate="formnovalidate" id="'+button_id+'" style="display: none;" />');
button = document.getElementById(button_id);
button.form["nette-submittedBy"] = button;
// ----
form.ajaxSubmit($.dependentselectbox.jsonResponse);
});
},
//....
…a může se promazat všechno, co souvisí s hideSubmits.
Výhodny:
- sémantický kod
- nemusíte modifikovat jquery.nette.js (v success přidání hideSubmits)
- nemusíte pracovat s fce. hideSubmits, resp. upravovat ji podle toho, zda využíváte vlastní modifikace renderování formuláře (ono magické „…parent().parent().hide()“)
Pokud se to líbí a nekoliduje to s něčím, do čeho nevidím, poprosil bych autora o úpravu komponenty.
Editoval Ot@s (19. 5. 2011 14:17)
- tenerd
- Člen | 15
Ot@s:
Zajímavej nápad, ale nefunguje to, protože potřebuješ ten odeslat formulář tím schovaným submitem.
Pokud máš zapnutý js, tak ten submit v noscript nenajde, protože není v DOM, viz. http://stackoverflow.com/…h-javascript
- Ot@s
- Backer | 476
tenerd napsal(a):
Ot@s:
Zajímavej nápad, ale nefunguje to, protože potřebuješ ten odeslat formulář tím schovaným submitem.
Pokud máš zapnutý js, tak ten submit v noscript nenajde, protože není v DOM, viz. http://stackoverflow.com/…h-javascript
Přiznám se, že nerozumím tomu „nefunguje to“. V té mojí modifikaci ty pomocné butony nemají pro verzi pod JS žádný význam (= jsou tam k ničemu a veškerý JS, který s nima pracuje, jde pryč). Funkce ajaxSubmit (AJAX form plugin for jQuery od Honzy Marka) umí odeslat formulář jak přes objekt input::submit, tak i přes samotný form.
Pokud to znamená, že to nefunguje vůbec (tj. po změně v selectboxu se nic neděje), tak je možné, že jsem neuvedl všechny změny (protože mě to jako celek funguje). Opravdu by mělo stačit v jquery.nette.dependentselectbox.js smazat/zakomentovat vše, co s těmi butony souvisí.
- tenerd
- Člen | 15
Ot@s napsal(a):
Přiznám se, že nerozumím tomu „nefunguje to“. V té mojí modifikaci ty pomocné butony nemají pro verzi pod JS žádný význam (= jsou tam k ničemu a veškerý JS, který s nima pracuje, jde pryč). Funkce ajaxSubmit (AJAX form plugin for jQuery od Honzy Marka) umí odeslat formulář jak přes objekt input::submit, tak i přes samotný form.
Pokud to znamená, že to nefunguje vůbec (tj. po změně v selectboxu se nic neděje), tak je možné, že jsem neuvedl všechny změny (protože mě to jako celek funguje). Opravdu by mělo stačit v jquery.nette.dependentselectbox.js smazat/zakomentovat vše, co s těmi butony souvisí.
Máš pravdu, zapomněl jsem tu tvoji změnu u initialize
.
V tom případě to funguje, ale jen dokud nemáš ve formuláři nějakou js validaci. Pak se při změně selectboxu provede validace, kterou ale provádět nechceš.
Aby se neprováděla, tak je to pořeba udělat tak, jak to bylo původně –
tzn. formuláři nastavit nette-submittedBy
na button, který
má novalidate
- Ot@s
- Backer | 476
tenerd napsal(a):
Máš pravdu, zapomněl jsem tu tvoji změnu u
initialize
.V tom případě to funguje, ale jen dokud nemáš ve formuláři nějakou js validaci. Pak se při změně selectboxu provede validace, kterou ale provádět nechceš.
Aby se neprováděla, tak je to pořeba udělat tak, jak to bylo původně – tzn. formuláři nastavit
nette-submittedBy
na button, který mánovalidate
Svatá pravda, toho jsem si nevšiml – používám to ve filtračních formulářích a tam validaci (zatím) nepotřebuju. Nicméně řešení existuje – uměle se tento unikátní submit button vytvoří. Hygiena jde malinko do háje, ale stále to má (doufám) ty benefity, které výše uvádím.
initialize: function() {
var counter = 0;
$('.'+$.dependentselectbox.controlClass).live('change', function() {
var form = $(this).closest('form');
// Nette form validation
var button_id = form.attr('id')+$.dependentselectbox.buttonSuffix+counter;
$(this).closest('form').append('<input type="submit" formnovalidate="formnovalidate" id="'+button_id+'" style="display: none;" />');
button = document.getElementById(button_id);
button.form["nette-submittedBy"] = button;
// ----
form.ajaxSubmit($.dependentselectbox.jsonResponse);
});
},
Editoval Ot@s (19. 5. 2011 14:16)
- oudzej
- Člen | 4
Zdravím, formulář s dependentSelectboxem mi při načítání dat do
závislého SELECTu (s JS i bez) vždycky validuje celý
formulář, mám nastavený validationScope = FALSE
u toho buttonu, má parametr formnovalidate=„formnovalidate“ , ale
i přesto se validuje všechno. Netuším, co může být špatně… nevíte
někdo? :-)
Pošlu, co bude potřeba, ale veškerý kód je psán podle
dokumentace. Díky!
EDIT: Tak to bude možná tento bug ?
Editoval oudzej (24. 8. 2011 16:25)
- oudzej
- Člen | 4
Foowie napsal(a):
Mělo by se jednat o tenhle bug . Zkusil jsi použít verzi nette z githubu?
Nezkoušel, nechci na projektu používat dev verzi nette. Asi budu muset jít jinou cestou. Díky za odpověď.
- oudzej
- Člen | 4
oudzej napsal(a):
Foowie napsal(a):
Mělo by se jednat o tenhle bug . Zkusil jsi použít verzi nette z githubu?
Nezkoušel, nechci na projektu používat dev verzi nette. Asi budu muset jít jinou cestou. Díky za odpověď.
Tak jsem zkusil nanečisto použít vývojovou verzi a funguje to … Jen pro informaci :-)
- Jack06
- Člen | 168
Zajímalo by mě, když mám tento addon a mám 2 závislé selectboxy a
chci aby se objevili postupně, jak to udělat.
Nyní to je tak, potom co vyberu z prvního selectu data, tak se mi objeví oba
dva závislé selectboxy, já bych chtěl aby se mi zobrazil jen daný závislý
selectbox
Příklad: REGIONY – OKRESY – MESTA (vyberu region, zobrazí se okres,
vyberu okres, zobrazí se město.
Díky
Editoval Jack06 (23. 9. 2011 14:50)
- romiix.org
- Člen | 343
Podla mňa by bolo ideálne, ak by dependenci selectbox dostával jedno pole a postupne pridával nasledujúci selectbox – ak je to ešte možné.
$options =
array(
array(
"sr"=>"Slovenká republika",
array(
array(
"sr-ba"=>"Bratislavský kraj",
"items"=>array(),
),
array(
"sr-bb"=>"Banskobystrický kraj",
"items"=>array(),
),
array(
"sr-nr"=>"Nitriansky kraj",
array(
array(
"sr-nr-nr"=>"Okres Nitra",
"items"=>array(),
),
array(
"sr-nr-nz"=>"Okres Nové zámky",
"items"=>array(),
),
),
),
),
),
array(
"cr"=>"Česká republika",
"items"=>array(),
),
);