On a vu comment créer des classes bien organisées et se contentant d’effectuer leur tâche. Par contre au niveau des vues c’est une autre histoire. En général on utilise un framework CSS, par exemple Bootstrap dont je me suis servi dans les exemples de ce cours. Mais que se passe-t-il le jour où ce framework évolue ou si on décide d’en changer ?

On a vu que le composant laravelcollective/html (même s’il na pas que des partisans) permet de simplifier l’écriture du code des vues. Malgré tout il reste quand même toutes les classes nécessaires pour le framework CSS, et elles peuvent être nombreuses, par exemple pour Bootstrap.

Dans l’application d’exemple j’ai choisi d’utiliser la possibilité de laravelcollective/html de créer des composants à partir de templates pour obtenir des méthodes plus puissantes. Ce chapitre va décrire ce qui a été réalisé.

Le problème

Lorsqu’on a vu les ressources on a été amenés à écrire ce genre de code pour un formulaire :

{!! Form::model($user, ['route' => ['user.update', $user->id], 'method' => 'put', 'class' => 'form-horizontal panel']) !!}
    <div class="form-group {!! $errors->has('name') ? 'has-error' : '' !!}">
        {!! Form::text('name', null, ['class' => 'form-control', 'placeholder' => 'Nom']) !!}
        {!! $errors->first('name', '<small class="help-block">:message</small>') !!}
    </div>
    <div class="form-group {!! $errors->has('email') ? 'has-error' : '' !!}">
        {!! Form::email('email', null, ['class' => 'form-control', 'placeholder' => 'Email']) !!}
        {!! $errors->first('email', '<small class="help-block">:message</small>') !!}
    </div>
    {!! Form::submit('Envoyer', ['class' => 'btn btn-primary pull-right']) !!}
{!! Form::close() !!}

Il est facile de voir qu’il y a des répétitions de code pour les deux contrôles.

Dans les vues de l’application vous allez trouver plutôt ce genre de code pour un formulaire :

{!! Form::open(['url' => 'contact']) !!}  
    <div class="row">
        {!! Form::controlBootstrap('text', 6, 'name', $errors, trans('front/contact.name')) !!}
        {!! Form::controlBootstrap('email', 6, 'email', $errors, trans('front  
        {!! Form::submitBootstrap(trans('front/form.send'), 'col-lg-12') !!}
    </div>
{!! Form::close() !!}

Pourtant le code résultant sera sensiblement le même. Si vous cherchez la méthode controlBootstrap dans le composant laravelcollective/html vous n’allez pas le trouver, elle a été créée pour l’application.

Organisation du code

La notion de « service » est suffisamment générale pour inclure la plupart des tâches à réaliser dans une application. Il a donc été créé un service pour gérer les fonctionnalités pour les vues avec un fichier FormBuilder.php dans le dossier app/Services pour mettre le code dont nous avons besoin :

Nous y trouvons une classe comportant les définitions des composants.

Les templates correspondants se trouvent rangés avec les vues dans le dossier components :

Enfin tout ça est initialisé dans le fournisseur de service (service provider) app/Providers/AppServiceProvider :

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Services\FormBuilder;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        FormBuilder::boot();
    }

    ...
}

On utilise la méthode boot pour être sûr que tout a déjà été initialisé dans les méthodes register de tous les fournisseurs de services, en particulier pour qu’on dispose de la façade Form.

Un composant pour case à cocher

Pour comprendre comment tout ça est articulé on va prendre le cas de l’un des 6 composants définis que j’ai appelé checkboxBootstrap.

Dans la classe App/Services/FormBuilder on trouve sa définition :

<?php

namespace App\Services;

use Form;

class FormBuilder
{
    public static function boot()
    {
        ...
        Form::component('checkboxBootstrap', 'components.checkbox', [
            'name',
            'label',
        ]);
        ...    	
    }
}

On utilise la méthode component :

  • le premier paramètre est le nom de l’élément (checkboxBootstrap),
  • le second paramètre est destiné à localiser le fichier contenant le template, ici il sera donc localisé en resources/views/components/checkbox.blade.php.

Le dernier paramètre est un tableau qui permet de transmettre toutes les valeurs pour renseigner la vue. On peut définir des valeurs par défaut, ce qui n’est pas le cas ici.

On peut donc facilement créer le template à partir de tout ça :

<div class="checkbox col-lg-12">
    <label>
        {!! Form::checkbox($name) !!}
        {{ $label }}
    </label>
</div>

Ensuite on peut directement l’utiliser dans une vue, par exemple dans celle de la connexion (resources/views/auth/login.blade.php) :

{!! Form::checkboxBootstrap('memory', trans('front/login.remind')) !!}

Ce qui correspond à la case à cocher « Se rappeler de moi » :

Ce se traduit au final par ce code :

<div class="checkbox col-lg-12">
    <label>
        <input name="memory" type="checkbox" value="1">
        Se rappeler de moi
    </label>
</div>

C’est une procédure simple et très propre.

Un composant pour liste de choix

Voyons maintenant un exemple avec une liste de choix : selectBootstrap.

Dans la classe App/Services/FormBuilder on trouve sa définition :

Form::component('selectBootstrap', 'components.select', [
    'name',
    'list' => [],
    'selected' => null,
    'label' => null,
])

Dans ce cas on a éléments dans le tableau à transmettre à la vue dont les 3 derniers ont une valeur par défaut.

On peut donc facilement créer le template à partir de tout ça :

<div class="form-group" style="width:200px;">
    @if($label)
        {!! Form::label($name, $label, ['class' => 'control-label']) !!}
    @endif
    {!! Form::select($name, $list, $selected, ['class' => 'form-control']) !!}
</div>

Remarquez qu’on peut utiliser toutes les possibilités de Blade.

On a une exemple d’utilisation dans le formulaire de création d’un utilisateur dans la partie administration pour le choix du rôle (resources/views/back/users/create.blade.php‌) :

{!! Form::selectBootstrap('role', $select, null, trans('back/users.role')) !!}

Avec cet aspect déroulé :

Avec ce code généré :

<div class="form-group" style="width:200px;">
    <label for="role" class="control-label">Rôle</label>
    <select class="form-control" id="role" name="role">
        <option value="1">Administrator</option>
        <option value="2">Redactor</option>
        <option value="3">User</option>
    </select>
</div>

C’est pas mal avec une seule ligne de code dans la vue !

En résumé

  • Le composant laravelcollective/html permet de créer des composants avec une définition et un template.
Cours Laravel 5.3 – plus loin – des vues propres

Vous pourrez aussi aimer

Laisser un commentaire