Values z ajaxem upraveného formuláře

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

Zdravím,
na začátek bych chtěl poprosit o hájení – s nette i ajaxem začínám
mám formulář který mi má vkládat do db hodnotu seo-url s následným presenterem, view a dalšími informacemi.
Při výběru presenteru má být překreslen selectbox u view i detailId dle hodnot, které ten konkrétní – vybraný – presenter umí – což se stane.. bohužel při odeslání mi formSucceeded nezachytí hodnoty které mi ajax před momentem vložil a vrátí mi jen hodnoty z polí, které zná formulář ve výchozím stavu – předpokládám, že je to ochrana proti podstrkávání hodnot, což prakticky teď dělám.

Bohužel už se v tom plácám strašně dlouho a chtěl bych vás poprosit o šťouchnutí jakým směrem se vydat – zkoušel jsem snippet nastavit na celý formulář, ale rozdíl kromě ztracených dat jsem nepostřehl. Uvedu zde osekaný kód a budu rád za každou radu.

<?php
 protected function createComponentForm() {
        $form = new Form;
        $form->addSelect('presenter', 'Presenter:')
                ->setItems($this->model->getPresenterNames(), FALSE)
                ->setPrompt('Vyberte Presenter');

        $form->addSelect('view', 'View:')->setPrompt('Vyberte Presenter');
        $form->addSelect('detailId', 'DetailId:')->setPrompt('Vyberte Presenter');

        $form->addSubmit('save', 'Uložit')->setValidationScope(array());
        $form->onSuccess[] = array($this, 'formSucceeded');

        return $form;
    }

	public function formSucceeded($button, $values) {
        dump($values); // bohužel view i detailId vrací NULL
		//.....
	}


	public function handleSelectChange($presenter_id = NULL) {
   		$this['form']['view']->setPrompt('Bez specifikace')->setItems($this->model->getViews($presenter_id), FALSE);
        $this->invalidateControl('view');

        $this['form']['detailId']->setPrompt('Bez specifikace')->setItems($this->model->getDetailIds($presenter_id));
        $this->invalidateControl('detailId');
    }
?>

formulář vykresluji manuálně – bez renderu úmyslně

{form form}
<table id="article">
        <tr><th>{label presenter /}</th><td>{input presenter}<b n:ifcontent>{inputError presenter}</b></td></tr>
            <tr><th>{label view /}</th><td>{snippet view}{input view}{/snippet}<b n:ifcontent>{inputError view}</b></td></tr>
            <tr><th>{label detailId /}</th><td>{snippet detailId}{input detailId}{/snippet}<b n:ifcontent>{inputError detailId}</b></td></tr>
        <tr><th>{label save /}</th><td>{input save}</td></tr>
    </table>

{/form}

<script>
   var links = {link "selectChange!"}
{include #jsCallback, link => links}
</script>

{define #jsCallback}
$('#{$control["form"][presenter]->htmlId}').on('change', function() {
    $.nette.ajax({
        type: 'GET',
        url: {$link},
        data: {
        presenter_id: $('#{$control["form"][presenter]->htmlId}').val()
        }
    });
});
{/define}
Felix
Nette Core | 1196
+
0
-

Hmmm, mas to cele obalene snippetem? Je to sice trochu slozitejsi, ale tohle by ti melo fungovat.

Do toho handleSelectChange ti prijdou spravna data? Resp. $presenter_id je vyplneny? Jestli to treba nemas zanore nekde v komponente.

Zkousel jsi v success metode zavolat:

$form->getHttpData()?

Taky furt nic? Pak mi budes muset ukazat ten kod vic. Jestli to mas v presenteru nebo v komponente. Jak to vykreslujes apod.

Nezkousel jsi treba tenhle doplnek? Je sice starsi, ale mohl by.


Jeste me napada, overujes na zacatku, jestli mas predany parameter $presenter_id? Kdyz zi volas url/?presenter_id=4, nactou se ti spravne hodnoty? Vypada to, ze nette ti to necha nasetovat, ale pak ti to prepise zakladnima datama.

mkos
Člen | 4
+
+1
-

Řeším stejný problém…
Prozatím jsem dospěl k tomuto zjištění

  1. snippety v tabulce takhle nefungují, řešením by byly zřejmě dynamické snippety viz dokumentace, to jsem ale nezkoušel.
  2. já jsem použil manuální rendering formuláře pomocí <dl>,při tomto renderingu se snippet překreslí správně.
{form nazevFormulare}
	<dl>
		<dt>{label select1 /}</dt>
		<dd>{input select1}</dd>
		<dt>{label select2 /}</dt>
		{snippet sel2}
			<dd>{input select2}</dd>
		{/snippet}
		<dd>{input send}</dd>
	</dl>
{/form}
  1. Používám tento script
<script type="text/javascript">
    $(function(){
        $('#frm-nazevFormulare-select1').change(function(){
            $.nette.ajax({
                type: 'GET',
                url: {link loadZakazky!},
                data: {
                    'value': $(this).val(),
                }
            });
        });
    });
</script>

a handler

public function handleLoadZakazky($value){
    $zakazky = $this->zModel->getZakazky($value);
    $this['nazevFormulare']['select2']->setItems($zakazky);
    $this->redrawControl('sel2');
}

data je třeba získat

$form->getHttpData();

Jediný problém, který řeším je ten, jak ošetřit validaci při zadaném pravidle.

$form['select2']->setRequired('Vyberte hodnotu z nabídky');

Při takto nastaveném pravidle vyhodí Nette vnitřně chybu a celý signál zabije i když je položka vybraná správně a funkce zadaná při $form->onSuccess[] vůbec neproběhne.