RequestButton

Tlačítko umožňující z rozpracovaného formuláře přejít na jiný formulář (nebo signál) a vrátit se zpět se zachováním dat rozpracovaného formuláře.

Verze 0.1
Download RequestButton-0.1.zip
Example http://addons.petrp.cz/…tton/Example
Autor Petr Procházka (petr@petrp.cz @Petr_P)
Licence „New“ BSD License
Homepage http://petrp.cz/…equestbutton

Vzniklo za podpory společnosti Clevis s.r.o.

Živá ukázka

Živá aplikace k vyzkoušení zde. Zdrojové kódy jsou přiloženy v archivu ve složce Example.

Instalace

Stáhněte si archiv RequestButton.zip a obsah složky /Components vložte do adresáře %appDir%/Components ve vašem projektu.

Komponenta byla vyvíjena a testována v Nette 0.9.3-dev a PHP 5.2, ale není žádný důvod, aby nefungovala i ve starších verzích Nette (může se ale změnit použití; např. před verzí 0.9 nebyly super továrničky).

Když nepoužíváte Nette\RobotLoader, musíte komponentu načíst.

require_once APP_DIR . '/Components/RequestButton/RequestButton.php';

Dále přidejte metody na FormContainer například v BasePresenter::startup():

FormContainer::extensionMethod('FormContainer::addRequestButton', array('RequestButtonHelper','addRequestButton'));
FormContainer::extensionMethod('FormContainer::addRequestButtonBack', array('RequestButtonHelper','addRequestButtonBack'));

Příklad použití

Vytvoření RequestButtonu

Základní použití je po kliknutí na tlačítko přesměrování někam, odkud se lze vrátit na formulář ve stavu v jakém jste ho opustily.

Místo AppForm použijete jeho potomka RequestButtonReceiver, který se stará o správné naplnění dat po návratu. (Jak nepoužít RequestButtonReceiver se dočtete níže.)

Přidáte RequestButton který funguje jako normální SubmitButton, s tím rozdílem že po odeslání se nevalidují data, a přesměruje se na Presenter:action (i s parametrama) které si nastavíte.

// User:edit

protected function createComponentEditUser($name)
{
  $form = new RequestButtonReceiver($this, $name);

  $form->addText('username', 'Jméno uživatele')
    ->addRule(Form::FILLED,'Vyplňte jméno uživatele.');
  ;

  $form->addText('age', 'Věk uživatele')
    ->addRule(Form::NUMERIC,'Věk musí být číslo.');
  ;

  $form->addRequestButton('addphone', 'Přidat telefon k uživateli.', 'Phone:add', array(
    'userId' => $this->getParam('userId')
  ));

}

Form může obsahovat více RequestButtonů i další normální tlačítka.

Není řečeno co bude po přesměrování na požadavek reagovat. Většinou to bude další formulář nebo signál:

Form na Form

Přesměrování z jednoho formuláře na druhý a po odeslání druhého se vrátit na první ve stavu v jakém jste ho opustily.

Znovu použijete RequestButtonReceiver místo AppForm, zde se stará o návrat po přesměrování (je možné ho také nepoužít viz níže.)

Nepřijde-li přesměrování z RequetButtonu, tak se RequestButtonReceiver chová jako normální Form.

Můžete získat userId, které jste nastavily v RequestButtonu.

Po odeslání se zpracují všechny callbacky které si nastavíte a přesměruje se zpět na místo kde se kliklo na RequestButton.

Přesměrování v callbackách bude potlačeno a vždy přesměrováno na RequestButton. Nezapomeňte v callbacku ale přesměrování uvést, kdyby nepřišel požadavek z RequestButtonu tak se normálně použije.

// Phone:add

protected function createComponentAddPhone($name)
{
  $form = new RequestButtonReceiver($this, $name);

  $userId = $this->getParam('userId');

  $form->addText('phone', 'Telefoní číslo')
    ->addRule(Form::FILLED,'Vyplňte telefonní číslo.');
  ;

  $form->addSubmit('send', 'Uložit');

  $form->onSubmit[] = array($this, 'save');
}

public function save(AppForm $form)
{
  $this->model->savePhone($this->getParam('userId'), $this->getParam('phoneId'), $form->getValues());

  $this->flashMessage('Upraven telefon.');

  $this->redirect('Phone:default');
}

Form na signál

Další možnost je přesměrování na signál a po jeho vykonání se hned vrátit zpět.

Definice RequestButtonu směrující na signál:

// ...
$form->addRequestButton('delphone', 'Smazat.', 'Phone:', array(
  'do' => 'del',
  'userId' => $this->getParam('userId'),
  'phoneId' => $phone->id,
));
// ...

(není ten parametr do znásilňování nette?)

A v obsluze signálu jen zavoláte RequestButtonHelper::redirectBack() které vyvolá redirect, když je požadavek z RequestButtonu.

Nezapomeňte na další přesměrování v případě že nepřišel požadavek z RequestButtonu.

public function handleDel($userId, $phoneId)
{
  $this->model->delPhone($userId, $phoneId);
  $this->flashMessage('Telefon vymazán.');

  RequestButtonHelper::redirectBack();

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

Zavoláním RequestButtonHelper::redirectBack()lze reagovat na požadavek RequestButtonu v jakékoli části kódu.

Přesměrování zpět a neuložení formuláře

FormControl RequestButtonBack umožní se vrátit zpět na RequestButton ale neuložit stávající formulář.

RequestButtonBack se zobrazuje jen když přišel požadavek od RequestButtonu.

// Phone:add

protected function createComponentAddPhone($name)
{
  $form = new RequestButtonReceiver($this, $name);

  $userId = $this->getParam('userId');

  $form->addText('phone', 'Telefoní číslo')
    ->addRule(Form::FILLED,'Vyplňte telefonní číslo.');
  ;

  $form->addSubmit('send', 'Uložit');

  $form->addRequestButtonBack('back', 'Neukládat a vrátit zpět.');

  $form->onSubmit[] = array($this, 'save');
}

Funkčnost bez použití RequestButtonReceiveru

Můžou nastat situace kdy nebudete moct použít RequestButtonReceiver, protože používáte nějaké vlastní rozšíření, nebo nějaký jiný addons.

Funkčnost lze ale snadno nahradit zavoláním RequestButtonHelper::prepareForm($form).

RequestButtonHelper::prepareForm($form) SE MUSÍ VOLAT AŽ PO přidání všech FormControlů do Formu a po připojení na Presenter.

Tady je definice předchozí komponenty:

// Phone:add

protected function createComponentEditUser($name)
{
  $form = new AppForm($this, $name);

  $form->addText('username', 'Jméno uživatele')
    ->addRule(Form::FILLED,'Vyplňte jméno uživatele.');
  ;

  $form->addText('age', 'Věk uživatele')
    ->addRule(Form::NUMERIC,'Věk musí být číslo.');
  ;

  $form->addRequestButton('addphone', 'Přidat telefon k uživateli.', 'Phone:add', array(
    'userId' => $this->getParam('userId')
  ));

  RequestButtonHelper::prepareForm($form);
}

U formu který reaguje na RequestButton je potřeba zavolat RequestButtonHelper::prepareForm() a ještě přidat přesměrování do callbacku (RequestButtonHelper::redirectBack()).

// Phone:add

protected function createComponentAddPhone($name)
{
  $form = new AppForm($this, $name);

  $userId = $this->getParam('userId');

  $form->addText('phone', 'Telefoní číslo')
    ->addRule(Form::FILLED,'Vyplňte telefonní číslo.');
  ;

  $form->addSubmit('send', 'Uložit');

  $form->onSubmit[] = array($this, 'save');

  RequestButtonHelper::prepareForm($form);
}

public function save(AppForm $form)
{
   $this->model->savePhone($this->getParam('userId'), $this->getParam('phoneId'), $form->getValues());

  $this->flashMessage('Upraven telefon.');

  RequestButtonHelper::redirectBack();

  $this->redirect('Phone:default');
}

Petr Procházka

Programátor, kodér a webový vývojář na volné noze.

kontakt

Twitter

Petr Procházka před rokem
Z tiskárny si vždy na flashce přinesu virus. To neslyšeli o antivirech a zakázání autorunu?

Petr Procházka před rokem
Blbne mi aplikace budík. NEJDE vypnout buzení. To je nejhorší porucha která může nastat. #android

Petr Procházka před rokem
Pracovní počítač mi zkolabuje skoro vždy když přeskládávám větší množství commitů. Dnes mi to naprosto zlikvidovalo repository. #git

Petr Procházka před rokem
Na mém HTC Hero se mi v aplikaci zobrazuje google reklama „Mobil od Googlu HTC Hero“. Kontextová reklama dotažená do dokonalosti.

PetrP na twitteru