Form wizard – vicekrokovy formular

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

Prohledaval jsem diskuzi, ale reseni jsem nenasel :(
Jake jsou moznosti vytvoreni vicekrokoveho formulare (napr. 2–3 screeny s polozkami formulare a buttony pro pohyb na dalsi wizard page formular), ktery dobre funguje ve vsech beznych prohlizecich?
Diky.
Lukas

fikus1234
Člen | 23
+
0
-

Jj. Cetl a hledal i v doplncich, kde jsem ale zadnou finalni verzi nenasel.
Ty posty popisuji postup pripravy wizarda, jestli neco z toho rozumne funguje jsem nezkousel.
Proto jsem se take ptal, jestli se doslo k nejakemu finalnimu reseni.
Dik.

zdenek.hrib
Člen | 2
+
0
-

Při šel jsi na něco? Dost by mě to taky zajímalo. Chci udělat aplikaci, která bude v podstatě jeden velký „wizard“. Rozhoduju se mezi více frameworkama – konkrétně Yii, Kohana a Nette a tohle je v podstatě moje základní výběrové kritérium.

fikus1234
Člen | 23
+
0
-

Bohuzel jsem na nic rozumneho nenarazil :-/

zdenek.hrib
Člen | 2
+
0
-

Dostal jsem odpověď mailem od _Martin_ na dotaz na tu hotovou komponentu, kterou zmiňuje v těch příspěvcích na které jsou tu odkazy:

*Ahoj,
rád bych pomohl, ale obávám se, že už to nepůjde. Komponentu jsem psal pro jednoho dřívějšího odběratele, pro něhož již nepracuji. Zdrojové kódy, které jsem měl u sebe v PC, skončily v křemíkovém nebi poté, co mi z ničeho nic odešel starý disk.

Pokud se do této komponenty pustíš sám, doporučuji nastudovat nové možnosti Nette a také addon Request Button (https://componette.org/search/?…), který by ti v tom mohl pomoci.

Přeji hodně úspěchů s vývojem,
Martin*

Filip111
Člen | 244
+
0
-

Ahoj, sám jsem před pár dny řešil podobnou otázku pro eshop – šel jsem trochu jinou cestou a vytvořil třídu StepManagera, který obstarává jednotlivé kroky. Každý krok je implementován vlastní komponentou/formulářem a konfiguruje se přes neon. Lze tedy jednoduše přidávat jednotlivé kroky nebo měnit pro různé klienty.
Každý krok si sám musí zajistit vykreslení a uložení dat, takže je vhodné jim předat v konstruktoru nějaké úložiště (to mám zatím vyřešené trochu prasácky a předávám celou session).

Konfigurace:

factories:
	orderStep1:
		class: web123\Eshop\OrderStepCustomer
		arguments: [@cart]
	orderStep2:
		class: web123\Eshop\OrderStepPayShipping
		arguments: [@session, @cart]
	orderStep4:
		class: web123\Eshop\OrderStepRecap
		arguments: [@cart, @orderManager]

services:
	orderSteps:
		class: web123\Eshop\StepManager
		arguments: [@session::getSection('orderSteps'), [@orderStep1, @orderStep2, orderStep4]]

Interface – jeden krok:

interface IStep
{
	function getTitle();	// nazev kroku
	function setManager($manager);
	function render();	// vykresleni formulare nebo komponenty
	function reset();	// reset stavu kroku
}

Interface vlastniho step managera – asi nakonec neni potreba:

interface IStepManager
{
	function getCurrentStep();
	function setCurrentStep($step);
	function reset();
	function getSteps();
	function setSteps($steps);
}

Implemetace:

class StepManager extends Nette\Object implements IStepManager {

	private $current; // aktualni krok
	private $repository;
	private $steps;
	private $activated; // pole jiz aktivnich kroku
	private $presenter;

	public function __construct($repository, $steps) {
		$this->repository = $repository;
		$this->steps = $steps;
		$this->registerSteps();

		if ($repository->activated)
			$this->activated = $repository->activated;
		else {
			// inicialni naplneni pole
			$this->activated = array();
			$i = 0;
			foreach ($this->steps as $step) {
				$this->activated[$i] = false;
				$i++;
			}
		}

		if ($repository->current > '')
			$this->current = $repository->current;
		else
			$this->setCurrentStep(0);
	}

	public function __destruct() {
		$this->repository->current = $this->current;
		$this->repository->activated = $this->activated;
	}

	public function reset() {
		$this->activated = array();
		$this->current = null;

		// projdu jednotlive komponenty a zavolam reset
		if (!empty($this->steps)) {
			foreach ($this->steps as $step) {
				$step->reset();
			}
		}

		if ($this->presenter)
			$this->presenter->redirect('default');
	}

	public function nextStep() {
		$this->setCurrentStep($this->current + 1);
	}

	public function getCurrentStep() {
		return $this->current;
	}

	public function getActivatedSteps() {
		return $this->activated;
	}

	public function setCurrentStep($step) {
		// oznacim krok jako jiz jednou aktivovany
		$this->activated[$step] = true;

		if (count($this->steps) >= $step)
		// dalsi krok
			$this->current = $step;
		//else konec

		// musim si sem predat referenci na presenter
		if ($this->presenter)
			$this->presenter->redirect('default');
	}

	public function registerPresenter($presenter) {
		$this->presenter = $presenter;
	}

	public function getPresenter() {
		return $this->presenter;
	}

	public function setSteps($steps) {
		$this->steps = $steps;
	}

	public function getSteps() {
		return $this->steps;
	}

	public function registerSteps() {
		// kazdemu kroku nastavim referenci na tento manager aby az udela svoji praci, zavolal callback
		if (!empty($this->steps)) {
			foreach ($this->steps as $step) {
				$step->setManager($this);
			}
		}
	}
}

Nevěděl jsem jak vyřešit redirect, takže zatím řeším oberličkou a v prezenteru si musím StepManager doregistrovat pomocí registerPresenter().

Pro samotné použití pak volám v latte {control orderStepForm} a v presenteru mám k této komponentě továrničku:

public function createComponentOrderStepForm() {
	$steps = $this->stepsManager->getSteps();
	$step = $steps[$this->stepsManager->getCurrentStep()];
	return $step->render();
}

O vykreslení navigačního okna, které přepíná mezi jednotlivými kroky se samostatná komponenta, které předávám celou službu stepManagera.

Určitě by se to dalo zjednodušit nebo udělat jednodušší, ale chtěl jsem mít možnost konfigurovat kroky přes neon a nahradit některé kroky klientským řešením.

Jestli k tomu máte nějaké návrhy, budu rád (ale ne že mi napíšete stejný řešení na 10 řádků, to bych byl dost nasr… :)

maarlin
Člen | 207
+
0
-

Filip111 napsal(a):

Ahoj, sám jsem před pár dny řešil podobnou otázku pro eshop – šel jsem trochu jinou cestou a vytvořil třídu StepManagera, který obstarává jednotlivé kroky. Každý krok je implementován vlastní komponentou/formulářem a konfiguruje se přes neon. Lze tedy jednoduše přidávat jednotlivé kroky nebo měnit pro různé klienty.

Tvoje řešení vypadá celkem fajn, asi ho s určitými modifikacemi použiju.
Moje hlavní requirements na „wizarda“ jsou tyto:

  1. možnost dokreslovat jednotlivé kroky pod sebe s nějakými fancy efekty (= možno získat další step nějak skrze AJAJ/AJAX)
  2. možnost odkázat na nějaký krok s parametry, které předvyplní předchozí kroky