Formulář s dependent selectem se nezpracuje
- ch4rli3
- Člen | 6
Nette 2.0.10
PHP 5
Ahoj,
podle kuchařky
jsem napsal formulář a obsluhu multiple dependent select – tohle funguje
přesně jak chci. Nicméně narazil jsem na trochu jiný problém. Když
fomrulář odešlu tak mi hlásí, že u těch závislých selectů nemám
vyplněné hodnoty.
Takto vypadá moje komponenta na vytváření formuláře:
protected function createComponentClientForm()
{
$cityPairs = $this->locationRepository->getCities()->fetchPairs('id','mesto');
$form = new Form();
$form->addText('jmeno', 'Klient:',40,100)
->addRule(Form::FILLED, 'Je nutné vyplnit jméno zákazníka');
$form->addText('ip', 'IP Adresa:',40,100)
->addRule(Form::FILLED, 'Je nutné vyplnit IP zákazníka')
->addRule(Form::REGEXP, "Zadejte správný tvar IP", '/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/');
$form->addSelect('cityId', 'Město:', $cityPairs)
->setPrompt('- Vyberte město -')
->addRule(Form::FILLED, 'Je nutné vybrat město');
$form->addSelect('streetId', 'Ulice:')
->setPrompt('- Nejdříve vyberte město -')
->addRule(Form::FILLED, 'Je nutné vybrat ulici');
$form->addSelect('locationId', 'Číslo popisné:')
->setPrompt('- Nejdříve vyberte město -')
->addRule(Form::FILLED, 'Je nutné vybrat číslo popisné');
$form->addSubmit('create','Pokračovat');
$form->onSuccess[] = $this->clientFormAccepted;
return $form;
}
a takto vypadá můj latte soubor:
{define content}
<fieldset>
<legend>Přidat Klienta</legend>
{form clientForm}
{control $form errors}
<table class="nostyle">
<tr>
<td>{label jmeno /}</td>
<td>{input jmeno }</td>
<td></td>
<td></td>
</tr>
<tr>
<td>{label ip /}</td>
<td>{input ip }</td>
<td></td>
<td></td>
</tr>
<tr n:snippet="secondSnippet">
<td>{label cityId /}</td>
<td>{input cityId }</td>
<td>{label streetId /}</td>
<td>{input streetId}</td>
<td>{label locationId /}</td>
<td n:snippet="thirdSnippet">{input locationId}</td>
{include #js}
</tr>
<tr>
<td></td>
<td>{input create }</td>
<td></td>
<td></td>
</tr>
</table>
{/form}
</fieldset>
{define #js}
<script>
{include #jsCallback, input => cityId, link => getStreets}
{include #jsCallback, input => streetId, link => getCP}
</script>
{/define}
{define #jsCallback}
$('#{$control["clientForm"][$input]->htmlId}').on('change', function() {
$.nette.ajax({
type: 'GET',
url: '{link {$link}!}',
data: {
'value': $(this).val(),
}
});
});
{/define}
{/define}
Samotné závislosti selectů fungují, ale formulář se správně neodešle. hlásí to pořád že nemám vyplněnou hodntou u ulice a čísla popisného :( co dělám špatně? Díky
- ch4rli3
- Člen | 6
OK vyřešil jsem to nakonec sám. Pravidla pro nutnost vyplnění selectů streetId a locationId jsem přesunul aby se přidali až v jednotlivých handlech. Kód tedy vypadá takto:
Komponenta formuláře:
protected function createComponentClientForm()
{
$cityPairs = $this->locationRepository->getCities()->fetchPairs('id','mesto');
$form = new Form();
$form->addText('jmeno', 'Klient:',40,100)
->addRule(Form::FILLED, 'Je nutné vyplnit jméno zákazníka');
$form->addText('ip', 'IP Adresa:',40,100)
->addRule(Form::FILLED, 'Je nutné vyplnit IP zákazníka')
->addRule(Form::REGEXP, "Zadejte správný tvar IP", '/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/');
$form->addSelect('cityId', 'Město:', $cityPairs)
->setPrompt('- Vyberte město -')
->addRule(Form::FILLED, 'Je nutné vybrat město');
$form->addSelect('streetId', 'Ulice:')
->setPrompt('- Nejdříve vyberte město -');
$form->addSelect('locationId', 'Číslo popisné:')
->setPrompt('- Nejdříve vyberte město -');
$form->addSubmit('create','Pokračovat');
$form->onSuccess[] = $this->clientFormAccepted;
return $form;
}
latte soubor:
{define content}
<fieldset>
<legend>Přidat Klienta</legend>
{form clientForm}
{control $form errors}
<table class="nostyle">
<tr>
<td>{label jmeno /}</td>
<td>{input jmeno }</td>
<td></td>
<td></td>
</tr>
<tr>
<td>{label ip /}</td>
<td>{input ip }</td>
<td></td>
<td></td>
</tr>
<tr n:snippet="secondSnippet">
<td>{label cityId /}</td>
<td>{input cityId }</td>
<td>{label streetId /}</td>
<td>{input streetId}</td>
<td>{label locationId /}</td>
<td n:snippet="thirdSnippet">{input locationId}</td>
{include #js}
</tr>
<tr>
<td></td>
<td>{input create }</td>
<td></td>
<td></td>
</tr>
</table>
{/form}
</fieldset>
{define #js}
<script>
{include #jsCallback, input => cityId, link => getStreets}
{include #jsCallback, input => streetId, link => getCP}
</script>
{/define}
{define #jsCallback}
$('#{$control["clientForm"][$input]->htmlId}').on('change', function() {
$.nette.ajax({
type: 'GET',
url: '{link {$link}!}',
data: {
'value': $(this).val(),
}
});
});
{/define}
{/define}
handly:
public function handleGetStreets ($value)
{
$streetPairs = $this->locationRepository->getStreets($value)->fetchPairs('id','ulice');
$this['clientForm']['cityId']->setDefaultValue($value);
$this['clientForm']['streetId']->setPrompt('- Vyberte ulici -')
->setItems($streetPairs)
->addRule(Form::FILLED, 'Je nutné vybrat ulici');
$this['clientForm']['locationId']->setPrompt('- Nejdříve vyberte ulici -');
$this->invalidateControl('secondSnippet');
}
public function handleGetCP ($value)
{
$cpPairs = $this->locationRepository->getCP($value)->fetchPairs('id','cp');
$this['clientForm']['locationId']->setPrompt('- Vyberte číslo popisné -')
->setItems($cpPairs)
->addRule(Form::FILLED, 'Je nutné vybrat číslo popisné');
$this->template->form = $this->template->_form = $this['clientForm'];
$this->invalidateControl('thirdSnippet');
}
Zpracování formuláře:
public function clientFormAccepted(Form $form)
{
$values = $form->getHttpData();
$response = $this->clientRepository->addClient($values);
$this->flashMessage($response->message, $response->type);
$this->redirect('this');
}
Dávám to tu záměrně vše protože by to mohlo snad někomu mohlo pomoct jak řešit problematiku závislých selectů.
Editoval ch4rli3 (19. 6. 2013 8:37)
- TeeBee87
- Člen | 14
Já jsem si to upravil tak, že si ty hodnoty dotáhnu při vytváření formuláře. Akorát ten formulář musí být připojený, aby šlo použít getHttpData.
<?php
public function __construct(IContainer $parent, $name, EntityManager $em)
{
parent::__construct($parent, $name);
$this->em = $em;
$this->addEntitySelect('eventType', 'Event type', $this->em->getDao(EventType::getClassName())->findAll())
->setPrompt('Select')
->addRule(self::FILLED);
$this->addEntitySelect("competition", "Competition")
->setPrompt('Select event')
->addRule(AddBetForm::FILLED);
$this->addEntitySelect("event", "Event")
->setPrompt('Select competition')
->addRule(AddBetForm::FILLED);
if ($this->getHttpData('eventType')) {
$this->eventTypeChange($this->getHttpData('eventType'));
}
if ($this->getHttpData('competition')) {
$this->competitionChange($this->getHttpData('competition'));
}
$this->addSubmit('submit', 'front.forms.save');
}
public function eventTypeChange($value)
{
if ($value) {
$this['competition']
->setPrompt('Select')
->setItems($this->em->getDao(Competition::getClassName())->findBy(['eventType' => $value]));
} else {
$this['competition']
->setPrompt('Select from event type')
->setItems(array());
}
$this['event']
->setPrompt('Select from competition')
->setItems(array());
}
public function competitionChange($value)
{
if ($value) {
$this['event']
->setPrompt('Select')
->setItems($this->em->getDao(Event::getClassName())->findBy(['competition' => $value]));
} else {
$this['event']
->setPrompt('Select from competition')
->setItems(array());
}
}
// A v presenteru:
protected function createComponentAddBetForm($name)
{
$form = new AddBetForm($this, $name, $this->em);
$form->onSuccess[] = $this->addBet;
return $form;
}
public function addBet(AddBetForm $form)
{
....
$this->redirect('this');
}
public function handleEventTypeChange($value)
{
$this['addBetForm']->eventTypeChange($value);
$this->redrawControl('competition');
}
public function handleCompetitionChange($value)
{
$this['addBetForm']->competitionChange($value);
$this->redrawControl('event');
}
?>