Réutiliser les formulaires à plusieurs endroits
Comment réutiliser le même formulaire à plusieurs endroits sans dupliquer le code ? C'est très facile à faire dans Nette et vous avez le choix entre plusieurs méthodes.
Form Factory
Créons une classe qui peut créer un formulaire. Une telle classe est appelée une fabrique. À l'endroit où nous voulons utiliser le formulaire (par exemple, dans le présentateur), nous demandons la fabrique comme dépendance.
Une partie de la fabrique est le code qui transmet les données pour un traitement ultérieur lorsque le formulaire est soumis
avec succès. Généralement vers la couche modèle. Elle vérifie également si tout s'est bien passé, et renvoie toute erreur au formulaire. Dans l'exemple
suivant, le modèle est représenté par la classe Facade
:
use Nette\Application\UI\Form;
class EditFormFactory
{
public function __construct(
private Facade $facade,
) {
}
public function create(/* parameters */): Form
{
$form = new Form;
// ajouter des éléments au formulaire
$form->addSubmit('send', 'Submit');
$form->onSuccess[] = [$this, 'processForm'];
return $form;
}
public function processForm(Form $form, array $values): void
{
try {
// traitement du formulaire
$this->facade->process($values);
} catch (AnyModelException $e) {
$form->addError('...');
}
}
}
Bien sûr, la fabrique peut être paramétrique, c'est-à-dire qu'elle peut recevoir des paramètres qui affecteront l'apparence du formulaire en cours de création.
Nous allons maintenant montrer comment passer la fabrique au présentateur. Tout d'abord, nous l'écrivons dans le fichier de configuration :
services:
- EditFormFactory
puis nous la demandons dans le présentateur. Il s'ensuit également l'étape suivante du traitement du formulaire soumis, qui consiste à rediriger vers la page suivante :
class MyPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private EditFormFactory $formFactory,
) {
}
protected function createComponentEditForm(): Form
{
$form = $this->formFactory->create();
$form->onSuccess[] = function (Form $form) {
$this->redirect('this');
};
return $form;
}
}
Puisque la redirection est gérée par le gestionnaire du présentateur, le composant peut être utilisé à plusieurs endroits et redirigé ailleurs à chaque endroit.
Composant avec formulaire
Une autre façon de procéder consiste à créer un nouveau composant qui contient un formulaire. Cela nous donne la possibilité de rendre le formulaire d'une manière spécifique, par exemple, puisque le composant inclut un modèle. Nous pouvons également utiliser des signaux pour la communication AJAX et le chargement d'informations dans le formulaire, par exemple pour l'autocomplétion, etc.
use Nette\Application\UI\Form;
class EditControl extends Nette\Application\UI\Control
{
public $onSave;
public function __construct(
private Facade $facade,
) {
}
protected function createComponentForm(): Form
{
$form = new Form;
// ajoute des éléments au formulaire
$form->addSubmit('send', 'Submit');
$form->onSuccess[] = [$this, 'processForm'];
return $form;
}
public function processForm(Form $form, array $values): void
{
try {
// traitement du formulaire
$this->facade->process($values);
} catch (AnyModelException $e) {
$form->addError('...');
return;
}
// invocation de l'événement
$this->onSave($this, $values);
}
}
Ensuite, nous allons créer la fabrique qui produira ce composant. Il suffit d'écrire son interface:
interface EditControlFactory
{
function create(): EditControl;
}
et de l'ajouter au fichier de configuration :
services:
- EditControlFactory
Et maintenant nous pouvons exiger l'usine et l'utiliser dans le présentateur :
class MyPresenter extends Nette\Application\UI\Presenter
{
public function __construct(
private EditControlFactory $controlFactory,
) {
}
protected function createComponentEditForm(): Form
{
$control = $this->controlFactory->create();
$control->onSave[] = function (EditControl $control, $data) {
$this->redirect('this');
// ou redirige vers le résultat de l'édition, par exemple:
// $this->redirect('detail', ['id' => $data->id]);
};
return $control;
}
}