získání dat z formuláře handlerem

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

Ahoj, vím, že je to pravděpodobně prasečina hadr, ale jde nějakým způsobem v handleru získat data z formuláře, aniž bych odeslal form přes submit? Tzn. udělat jakýsi „hidden“ submit.

Ve formuláři je totiž tlačítko pro přídání dalšího účastníka, ale když ho přidám, ztratím data, která uživatel napsal, protože nedošlo k odeslání formuláře (tam následuje uložení do session – jedná se o jeden krok v nákupním košíku).

	public function handleAddAttendee($p) {
		$form = $this['attendeesForm']->getValues();
		dump($form);die; //vypise udaje o formulari ok - i dynamicke polozky, ale bez dat samozrejme

		(...)

		$this->redirect('this#p-' . $p . '-' . $newAttendeeKey);
	}

Aurielle
Člen | 1281
+
0
-

Co ti brání formulář jakoby submittnout, provést změny, které potřebuješ, a vrátit se na něj zpátky? Místo na $form->onSuccess můžeš navěšovat handlery přímo na jednotlivé SubmitButtony a tím rozlišit, jestli potřebuješ formulář uložit nebo jen změnit: $button->onClick[] = function(...) { ... };

(onClick handler se volá nad úspěšně zvalidovaným formulářem, případně můžeš využít i kombinaci $form->onSuccess a $form['submitbutton']->isSubmittedBy(), výsledný efekt bude stejný.)

duke
Člen | 650
+
0
-

Nejlepší je skutečně normálně formulář submitnout a postupovat, jak radí @Aurielle.

Ale ptal ses, zda to jde i bez submitu, a na to je odpověď ano, ale musel by sis veškerá potřebná data poslat přímo jako parametr toho signálu addAttendee, a protože to je submitem prostě jednodušší a přehlednější, dalo by se takové řešení skutečně považovat za prasečinu.

Jiří Nápravník
Člen | 710
+
+1
-

Píšeš, že jde o přidání dalšího účastníka. Není na tohle vhodné použít Kdyby/Replicator?

FJP
Člen | 124
+
0
-

Jiří Nápravník napsal(a):

Píšeš, že jde o přidání dalšího účastníka. Není na tohle vhodné použít Kdyby/Replicator?

Replikátor se mi bohužel nepodařilo rozchodit.

… celé to vypadá následovně:

	protected function createComponentAttendeesForm() {
		$form = new Nette\Application\UI\Form;
		$textboxs = $form->addContainer('products');
		foreach ($this->session->getSection('userCart')->data as $productKey => $product) {
			$sec = $textboxs->addContainer($productKey);
			if (!isset($product->attendees)) {
				$this->userCart[$productKey]->attendees = array();
				for ($i = 0; $i < $product->count; $i++)
					$this->userCart[$productKey]->attendees[$i] = array();
			}
			foreach ($product->attendees as $attendeeKey => $attendee) {
				$tri = $sec->addContainer($attendeeKey);
				$first_name = $tri->addText('first_name', $this->vocabulary('name'))->setAttribute('placeholder', $this->vocabulary('name').' *')->setRequired($this->vocabulary('v_required'));
				if (isset($attendee->first_name))
					$first_name->setDefaultValue($attendee->first_name);
				$last_name = $tri->addText('last_name', $this->vocabulary('surname'))->setAttribute('placeholder', $this->vocabulary('surname').' *')->setRequired($this->vocabulary('v_required'));
				if (isset($attendee->last_name))
					$last_name->setDefaultValue($attendee->last_name);
				$company_position = $tri->addText('company_position', $this->vocabulary('positionInCompany'))->setAttribute('placeholder', $this->vocabulary('positionInCompany'));
				if (isset($attendee->company_position))
					$company_position->setDefaultValue($attendee->company_position);
				$email = $tri->addText('email', $this->vocabulary('email'))->setType('email')->setAttribute('placeholder', $this->vocabulary('email').' *')->setRequired($this->vocabulary('v_required'))->addRule(Form::EMAIL, $this->vocabulary('v_email'));
				if (isset($attendee->email))
					$email->setDefaultValue($attendee->email);
				$phone = $tri->addText('phone', $this->vocabulary('phone'))->setAttribute('placeholder', $this->vocabulary('phone').' *')->setRequired($this->vocabulary('v_required'));
				if (isset($attendee->phone))
					$phone->setDefaultValue($attendee->phone);
				$guide = array(
					'e' => $this->vocabulary('electronic'),
					't' => $this->vocabulary('printed'),
				);
				$guideList = $tri->addRadioList('guide', $this->vocabulary('courseGuide').': *', $guide)->setRequired($this->vocabulary('v_required'));
				if (isset($attendee->guide))
					$guideList->setDefaultValue($attendee->guide);
			}
		}
		$note = $form->addTextArea('note', $this->vocabulary('note'));
		if (!empty($this->session->getSection('userCart')->note))
			$note->setDefaultValue($this->session->getSection('userCart')->note);

		$form->addSubmit('submit', $this->vocabulary('nextStep'));
		$form->onSuccess[] = array($this, 'attendeesFormSubmitted');
		return $form;
	}

	public function attendeesFormSubmitted(Nette\Application\UI\Form $form) {
		$val = $form->getValues();

		foreach ($val['products'] as $productKey => $attendees) {
			$this->userCart[$productKey]->attendees = array();
			$this->userCart[$productKey]->attendees = $attendees;
		}
		$this->session->getSection('userCart')->note = $val->note;
		$this->redirect('ShoppingCart:contactInfo', array('localization' => $this->localization->code));
	}

	public function handleAddAttendee($p) {
		$form = $this['attendeesForm']->getValues();
//		dump($form);die; //vypise udaje o formulari ok, ale bez data samozrejme

		end($this->userCart[$p]->attendees);
		$key = key($this->userCart[$p]->attendees);
		$newAttendeeKey = $key + 1;
		$this->userCart[$p]->attendees[$newAttendeeKey] = array();
		$this->userCart[$p]->count = count($this->userCart[$p]->attendees);
		$this->redirect('this#p-' . $p . '-' . $newAttendeeKey);
	}

v šabloně

			{form attendeesForm}
				{include progress.latte step=>"2"}

				{foreach $items as $productKey => $item}
					<div class="box cart-box">
						<div id="p-{$productKey}">
							<h4>
								<a href="{plink Product:detail id => $item->productId, localization => $localization}">{$item->product}</a>
								<span class="pull-right">
									{if $localization === 'en'}
										{$presenter->findTerm($item->id)->date_from|date:'%m/%d/%Y'} - {$presenter->findTerm($item->id)->date_to|date:'%m/%d/%Y'}
									{else}
										{$presenter->findTerm($item->id)->date_from|date:'j. n. Y'} - {$presenter->findTerm($item->id)->date_to|date:' j. n. Y'}
									{/if}
								</span>
							</h4>
							{foreach $item->attendees as $attendeeKey => $attendee}
								<div id="p-{$productKey}-{$attendeeKey}" class="person-box">
									<div class="row">
										<div class="col-md-4">
											{input products-$productKey-$attendeeKey-first_name}
											{if $form['products-' . $productKey . '-' . $attendeeKey . '-first_name']->error}
												<div class="error">{$form['products-' . $productKey . '-' . $attendeeKey . '-first_name']->error}</div>
											{/if}
										</div>
										<div class="col-md-4">
											{input products-$productKey-$attendeeKey-last_name}
											{if $form['products-' . $productKey . '-' . $attendeeKey . '-last_name']->error}
												<div class="error">{$form['products-' . $productKey . '-' . $attendeeKey . '-last_name']->error}</div>
											{/if}
										</div>
										<div class="col-md-4">
											{input products-$productKey-$attendeeKey-company_position}
											{if $form['products-' . $productKey . '-' . $attendeeKey . '-company_position']->error}
												<div class="error">{$form['products-' . $productKey . '-' . $attendeeKey . '-company_position']->error}</div>
											{/if}
										</div>
									</div>
									<div class="row">
										<div class="col-md-4">
											{input products-$productKey-$attendeeKey-phone}
											{if $form['products-' . $productKey . '-' . $attendeeKey . '-phone']->error}
												<div class="error">{$form['products-' . $productKey . '-' . $attendeeKey . '-phone']->error}</div>
											{/if}
										</div>
										<div class="col-md-4">
											{input products-$productKey-$attendeeKey-email}
											{if $form['products-' . $productKey . '-' . $attendeeKey . '-email']->error}
												<div class="error">{$form['products-' . $productKey . '-' . $attendeeKey . '-email']->error}</div>
											{/if}
										</div>
									</div>
									<div class="row">
										<div class="col-md-8 guide">
											{label products-$productKey-$attendeeKey-guide /} {input products-$productKey-$attendeeKey-guide} {$form['products-' . $productKey . '-' . $attendeeKey . '-guide']->error}
										</div>
										<div class="col-md-4 price">
											{*$item->price|number:0:',':' '} Kč (bez DPH)<br>*}
											<a n:href="removeAttendee! p => $productKey, a => $attendeeKey"><i class="fa fa-close"></i> {$presenter->vocabulary('remove')}</a>
										</div>
									</div>

								</div>
							{/foreach}
						</div>

						<p class="pull-left">
							<a n:href="addAttendee! p => $productKey" onclick="javascript: document.frm-attendeesForm.submit()"><i class="fa fa-plus addPerson"></i>{$presenter->vocabulary('addNewAttendee')}</a> &nbsp;
							<a href="{plink removefromCart! remove => $productKey, localization => $localization}"><i class="fa fa-minus addPerson"></i>{$presenter->vocabulary('removeCourse')}</a>
						</p>
						<p class="pull-right"><strong class="final-price">{($item->price * $item->count)|number:0:',':' '}</strong> Kč ({$presenter->vocabulary('withoutTax')})</p>

					</div>
				{/foreach}
				<p class="text-right">{$presenter->vocabulary('total')} <strong class="final-price">{$totalPrice|number:0:',':' '}</strong> Kč ({$presenter->vocabulary('withoutTax')})</p>

				<p>{label note /} {input note}</p><br>

				<a n:href="ShoppingCart: localization => $localization" class="button submit green">{$presenter->vocabulary('back')}</a>
				{input submit class=>"pull-right"}

				<p><br>{$presenter->vocabulary('requiredItems')}</p>
			{/form}
FJP
Člen | 124
+
0
-

Aurielle napsal(a):

Co ti brání formulář jakoby submittnout, provést změny, které potřebuješ, a vrátit se na něj zpátky? Místo na $form->onSuccess můžeš navěšovat handlery přímo na jednotlivé SubmitButtony a tím rozlišit, jestli potřebuješ formulář uložit nebo jen změnit: $button->onClick[] = function(...) { ... };

(onClick handler se volá nad úspěšně zvalidovaným formulářem, případně můžeš využít i kombinaci $form->onSuccess a $form['submitbutton']->isSubmittedBy(), výsledný efekt bude stejný.)

Brání mi v tom, že odkaz, který volá ten handler není součástí formuláře.