Jak udělat AJAX závislý selectbox?
- Martin Mates
- Člen | 179
Snažím už poměrně dlouho o AJAX dependent select box, ale bohužel bez
úpěchu. Stále dostávám hlášku „Please select valid option“. Hodnoty
v select boxu se změní, snippet se invaliduje v pořádku, ale po odeslání
to zkrátka neprojde. Hodnoty v select boxu změní metoda
handleRefreshTarifOptions
, kterou volá javascript.
Už netuším, jak dál. Postupoval jsem podle webu zde: http://www.zeminem.cz/…t-select-box
Bude to trošku delší, ale jiná možnost není. Zdrojáky:
Presenter s formulářem (zjednodušené):
class PoptavkaPresenter extends BasePresenter
{
/** @var PoptavkaFormFactory @inject */
public $poptavkaFormFactory;
/**
* Enable {snippet} macro inside {form} macro
*/
public function beforeRender()
{
parent::beforeRender();
$this->template->_form = $this['poptavkaForm']; // form {snippet} workaround
}
/**
* Creates demand form using a factory.
*
* @param $name
* @return Form
*/
public function createComponentPoptavkaForm($name)
{
$form = $this->poptavkaFormFactory->create($this, $name);
$form->onSuccess[] = array($this, 'odeslatPoptavku');
return $form;
}
/**
* Refreshes selectbox in poptavka form using web service and filled address.
*
* @param null|string $address
*/
public function handleRefreshTarifOptions($address = null)
{
if ($this->isAjax()) {
$services = $this->lumpyService->getAvailableServices($address);
$this['poptavkaForm']['tarif']->setItems($this->poptavkaFormFactory->createTarifOptions($services));
$this->redrawControl('selectTarif');
}
}
Továrnička na vytvoření formuláře (zjednodušené):
class PoptavkaFormFactory extends Nette\Object
{
public function __construct(Application $application, IMailer $mailer, LumpyService $lumpyService, Session $session, $appDir)
{
$this->application = $application;
$this->appDir = $appDir;
$this->mailer = $mailer;
$this->lumpyService = $lumpyService;
$this->session = $session;
$this->sessionAddress = $session->getSection('searchedAddress')->address;
}
/**
* Creates form.
*
* @param null $container
* @param null $name
* @return Form
*/
public function create($container = null, $name = null)
{
$form = new Form($container, $name);
// Get available services from Lumpy service
$services = $this->lumpyService->getAvailableServices($this->sessionAddress);
$form->addSelect('tarif', 'Tarif:', $this->createTarifOptions($services))
->addRule(Form::FILLED, 'Vyplňte prosím, o jaký tarif máte zájem.');
$form->addSubmit("send", "Odeslat nezávaznou poptávku");
return $form;
}
}
Všechno funguje, zdá se, dobře, ale když vyberu hodnotu jinou, než byla v select boxu na začátku, tak to neprojde. Myslím si, že to mám stejně, jako je to na zmíněném webu. Nevím, jestli to v novějším Nette už takto nejde, nebo v čem je problém. Díky moc, budu rád za jakékoliv nakopnutí.
- David Matějka
- Moderator | 6445
Sice nevim, proc pouzivas session, ale asi k tomu mas duvod. Ale nezapominas v tom handleRefreshTarifOptions ulozit do session predanou adresu?
- Martin Mates
- Člen | 179
Ta session je tam z jiného důvodu a s problémem podle mě nesouvisí. Je to tam proto, protože uživatel už pravděpodobně psal svojí adresu jinde, tak ji tady bude mít předvyplněnou. Použije se rovnou při vytváření formuláře, pro získání výchozích možností do select boxu.
- Martin Mates
- Člen | 179
Jak to myslíš? Ten select už ty hodnoty na začátků má. Jen se v průběhu mohou změnit. Jestli budu brát hodnoty z values nebo z postu je teď jedno, protože formulář se ani nezvaliduje, takže k nějakému braní hodnot ani nedojde.
- David Matějka
- Moderator | 6445
V tom pripade mas problem tady:
$services = $this->lumpyService->getAvailableServices($this->sessionAddress);
$form->addSelect('tarif', 'Tarif:', $this->createTarifOptions($services))
ze i po odeslani to naplnis tarifama dle adresy v session
- Martin Mates
- Člen | 179
Ahaaaaaa.. díky moc za inspiraci!! On se ten formulář vlastně vytváří po odeslání znova. Heureka!