Formuláře „dvojfázově“ – náhled před uložením – nedělám to moc složitě?

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

Zdravím,

potýkám se s MVC a formuláři v Nette Application. O co mi jde: Chci zobrazit formulář, nechat jej vyplnit, a po jeho odeslání jej NEULOŽIT do databáze, ale zobrazit co uživatel vyplnil (pro kontrolu) s tím, že se buď může vrátit na „původní“ formulář, nebo to odeslat (a opravdu uložit). Tedy de facto „náhled před uložením“.

Ono mi to funguje, ale přijde mi, že to dělám moc složitě:

V prezenteru tedy mám:

<?php
  function renderAdd($formvalues) {
    $form = $this->getComponent('addForm');
    if (is_array($formvalues)) $form->setDefaults($formvalues);
  }

  public function addFormSubmitted(AppForm $form) {
    if ($form['save']->isSubmittedBy()) {
      $this->redirect('addValidate',array($form->getValues()));
    }
    $this->redirect('default');
  }

  public function renderAddValidate ($formvalues) {
    $this->template->formvalues = $formvalues;
    $form = $this->getComponent('addValidateForm');
    $form->setDefaults($formvalues);
  }

  public function addValidateFormSubmitted(AppForm $form) {
    if ($form['save']->isSubmittedBy()) {
      $hodnoty = $form->getValues();
      //tady by byl zápis a flashmessage ...
    }
    elseif ($form['back']->isSubmittedBy()){
      $this->redirect('add',array($form->getValues()));
    }
  }

  protected function createComponent($name) {
    switch ($name) {
      case 'addForm':
        $form = new AppForm($this, $name);
        $form->addText('jmeno', 'Jméno:')->addRule(Form::FILLED, 'Zadejte jméno');
        $form->addSubmit('save', 'Uložit');
        $form->onSubmit[] = array($this, 'addFormSubmitted');
        return;
      case 'addValidateForm':
        $form = new AppForm($this, $name);
        $form->addHidden('jmeno', 'Jméno:');
        $form->addSubmit('back', '<< Zpět');
        $form->addSubmit('save', 'Uložit >>');
        $form->onSubmit[] = array($this, 'addValidateFormSubmitted');
        return;

      default:
        parent::createComponent($name);
    }
  }
?>

no, a v šablonách pak:
add.phtml

{control addForm}

a
addValidate.phtml

Jméno: {$formvalues['jmeno']}

{control addValidateForm}
  1. Nedělám to zbytečně složitě?
  2. Je způsob, jakým používám setDefaults a getValues „politicky korektní“, nebo je to paskvil způsobený mojí neznalostí věci?
  3. Nedal by se namísto REDIRECTu použít FORWARD?
Honza Kuchař
Člen | 1662
+
0
-

Nedal by se namísto REDIRECTu použít FORWARD?

Forward raději nepoužívej. Co jsem tak viděl, tak jsou s ním zatím dost problémy.

xzajic
Člen | 19
+
0
-

Forward raději nepoužívej. Co jsem tak viděl, tak jsou s ním zatím dost problémy.

Jojo, na to jsem si už právě onehdá naběhl. Ale to, co popisuju výše, se mi zase nelíbí kvůli tomu neustálému předávání setValues a getValues. Pokud to ale jinak nepůjde, tak to nevadí…

xzajic
Člen | 19
+
0
-

Nikdo neporadí? Škoda, protože se zdá, že se mi to povedlo pomocí forward o dost zjednodušit, tzn. teď mi stačí:

<?php
  function renderAdd() {
    $form = $this->getComponent('addForm');
    $form->setDefaults($_POST);
  }

  public function addFormSubmitted(AppForm $form) {
    if ($form['save']->isSubmittedBy()) {
      $this->forward('addValidate');
    }
    $this->redirect('default');
  }

  public function renderAddValidate () {
    $this->template->formvalues = $_POST;
    $form = $this->getComponent('addValidateForm');
    $form->setDefaults($_POST);
  }

  public function addValidateFormSubmitted(AppForm $form) {
    if ($form['save']->isSubmittedBy()) {
      $hodnoty = $form->getValues();
      //tady by byl zápis a flashmessage ... a pochopitelně redirect
    }
    elseif ($form['back']->isSubmittedBy()){
      $this->forward('add');
    }
  }
?>

Ovšem moje nejistota trvá. Je tohle košer? Pokud použiju přímo hodnoty z $_POST a forward, tak se mi zdá, že to dělá to co má (za cenu nabourání „svatého patternu POST-REDIRECT-GET“, ale to mi přece zrovna v tomto případě vůbec nevadí, ne?)

Nebo jak řešíte v NETTE vyplnit formulář – zkontrolovat (s možností návrat či definitivně zapsat) Vy?

Editoval xzajic (19. 10. 2009 17:51)

Honza Marek
Člen | 1664
+
0
-

Rozhodně místo $_POST používej Environment::getHttpRequest()->getPost() pokud si nemůžeš být jistý nastavením magic quotes.

Tomik
Nette Evangelist | 485
+
0
-

Proč prostě nezobrazit ten formulář znovu? Dokonce tak uživateli odpadne, pokud něco špatně vyplní, jeden krok.

Tedy:

Zobrazím form => uživatel vyplní => odešle => pokud byl form odeslán tlačítkem 1, toto skryju a zobrazím tlačítko 2 a form opět vypíšu (i s vyplněnýma hodnota) a nějakým "pozorně si překontrolujte údaje" => uživatel překontroluj (případně upraví) => odešle tlačítkem 2 => uložím

Asi tak.

xzajic
Člen | 19
+
0
-

Tomik napsal(a):

Proč prostě nezobrazit ten formulář znovu? Dokonce tak uživateli odpadne, pokud něco špatně vyplní, jeden krok.

Protože kontrola údajů nemusí spočívat pouze v tupém opisu věcí z formuláře; může jít o výpočet. Koupíš si 3× něco a na té kontrolní stránce bude třeba vypočítána cena s DPH.

Oggy
Člen | 306
+
0
-

není lepší řešení si hodnoty ukládat do sessions? .. mám za úkol takovýto náhled také udělat. pokoukávám po řešení..