Dans Laravel, la meilleure façon de transmettre différents types de messages flash dans la session

115

Je crée ma première application dans Laravel et j'essaie de comprendre les messages flash de la session. Pour autant que je sache dans l'action de mon contrôleur, je peux définir un message flash soit en allant

Redirect::to('users/login')->with('message', 'Thanks for registering!'); //is this actually OK?

Dans le cas d'une redirection vers une autre route, ou

Session::flash('message', 'This is a message!'); 

Dans mon modèle de lame maître, j'aurais alors:

@if(Session::has('message'))
<p class="alert alert-info">{{ Session::get('message') }}</p>
@endif

Comme vous avez sans doute remarqué que je utilise Bootstrap 3 dans mon application et je voudrais utiliser les différentes classes de messages: alert-info, alert-warning, alert-dangeretc.

En supposant que dans mon contrôleur, je connais le type de message que je configure, quelle est la meilleure façon de le transmettre et de l'afficher dans la vue? Dois-je définir un message distinct dans la session pour chaque type (par exemple Session::flash('message_danger', 'This is a nasty message! Something's wrong.');)? Ensuite, j'aurais besoin d'une instruction if distincte pour chaque message de mon modèle de lame.

Tout conseil apprécié.

harryg
la source
itsolutionstuff.com/post/ ... m'a été utile.
Ryan le

Réponses:

193

Une solution serait de flasher deux variables dans la session:

  1. Le message lui-même
  2. La "classe" de votre alerte

par exemple:

Session::flash('message', 'This is a message!'); 
Session::flash('alert-class', 'alert-danger'); 

Ensuite, à votre avis:

@if(Session::has('message'))
<p class="alert {{ Session::get('alert-class', 'alert-info') }}">{{ Session::get('message') }}</p>
@endif

Remarque J'ai mis une valeur par défaut dans le fichier Session::get(). de cette façon, vous n'avez besoin de le remplacer que si l'avertissement doit être autre chose que la alert-infoclasse.

(c'est un exemple rapide et non testé :))

msturdy
la source
3
Intéressant, je ne connaissais pas le paramètre par défaut pour Session::get() Cela sera très pratique.
Nick Coad
1
Comme la plupart des solutions de messages flash, cela ne concerne qu'un seul message. Très souvent, il est nécessaire de pouvoir déclencher un tas de messages, chacun peut-être d'une gravité différente, et de les afficher tous.
Jason
2
Voici ce que nous utilisons dans nos projets gist.github.com/YavorK/7aa6e839dbe93e8854e4b033e31836a4
Hop hop
1
C'est tellement contre-productif ... Pourquoi tout le monde vote-t-il pour cela?
Goowik
14
@Goowik - Dire que c'est contre-productif sans offrir une solution plus productive est contre-productif.
SupaMonkey
49

À votre avis:

<div class="flash-message">
  @foreach (['danger', 'warning', 'success', 'info'] as $msg)
    @if(Session::has('alert-' . $msg))
    <p class="alert alert-{{ $msg }}">{{ Session::get('alert-' . $msg) }}</p>
    @endif
  @endforeach
</div>

Ensuite, définissez un message flash dans le contrôleur:

Session::flash('alert-danger', 'danger');
Session::flash('alert-warning', 'warning');
Session::flash('alert-success', 'success');
Session::flash('alert-info', 'info');
danelips
la source
35

Ma façon est de toujours Rediriger :: back () ou Redirect :: to ():

Redirect::back()->with('message', 'error|There was an error...');

Redirect::back()->with('message', 'message|Record updated.');

Redirect::to('/')->with('message', 'success|Record updated.');

J'ai une fonction d'assistance pour le faire fonctionner pour moi, généralement dans un service séparé:

function displayAlert()
{
      if (Session::has('message'))
      {
         list($type, $message) = explode('|', Session::get('message'));

         $type = $type == 'error' : 'danger';
         $type = $type == 'message' : 'info';

         return sprintf('<div class="alert alert-%s">%s</div>', $type, message);
      }

      return '';
}

Et dans ma vue ou ma mise en page, je fais

{{ displayAlert() }}
Antonio Carlos Ribeiro
la source
4
C'est tout simplement génial mais comment ça marche$type = $type == 'error' : 'danger';
débordement du
1
Où placez-vous votre assistant dans une classe d'aide distincte?
utdev
16

Vous pouvez créer plusieurs messages et avec différents types. Suivez ces étapes ci-dessous:

  1. Créez un fichier: " app/Components/FlashMessages.php"
namespace App\Components;

trait FlashMessages
{
  protected static function message($level = 'info', $message = null)
  {
      if (session()->has('messages')) {
          $messages = session()->pull('messages');
      }

      $messages[] = $message = ['level' => $level, 'message' => $message];

      session()->flash('messages', $messages);

      return $message;
  }

  protected static function messages()
  {
      return self::hasMessages() ? session()->pull('messages') : [];
  }

  protected static function hasMessages()
  {
      return session()->has('messages');
  }

  protected static function success($message)
  {
      return self::message('success', $message);
  }

  protected static function info($message)
  {
      return self::message('info', $message);
  }

  protected static function warning($message)
  {
      return self::message('warning', $message);
  }

  protected static function danger($message)
  {
      return self::message('danger', $message);
  }
}
  1. Sur votre contrôleur de base " app/Http/Controllers/Controller.php".
namespace App\Http\Controllers;

use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesResources;

use App\Components\FlashMessages;

class Controller extends BaseController
{
    use AuthorizesRequests, AuthorizesResources, DispatchesJobs, ValidatesRequests;

    use FlashMessages;
}

Cela rendra le FlashMessagestrait disponible à tous les contrôleurs qui étendent cette classe.

  1. Créez un modèle de lame pour nos messages: " views/partials/messages.blade.php"
@if (count($messages))
<div class="row">
  <div class="col-md-12">
  @foreach ($messages as $message)
      <div class="alert alert-{{ $message['level'] }}">{!! $message['message'] !!}</div>
  @endforeach
  </div>
</div>
@endif
  1. Sur " boot()" méthode de " app/Providers/AppServiceProvider.php":
namespace App\Providers;

use Illuminate\Support\ServiceProvider; 

use App\Components\FlashMessages;

class AppServiceProvider extends ServiceProvider
{
  use FlashMessages;

    public function boot()
    {
        view()->composer('partials.messages', function ($view) {

          $messages = self::messages();

          return $view->with('messages', $messages);
      });
    }

    ...
}

Cela rendra la $messagesvariable disponible pour le views/partials/message.blade.phpmodèle " " chaque fois qu'elle sera appelée.

  1. Dans votre modèle, incluez notre modèle de messages - " views/partials/messages.blade.php"
<div class="row">
  <p>Page title goes here</p>
</div>

@include ('partials.messages')

<div class="row">
  <div class="col-md-12">
      Page content goes here
  </div>
</div>

Il vous suffit d'inclure le modèle de messages là où vous souhaitez afficher les messages sur votre page.

  1. Sur votre contrôleur, vous pouvez simplement le faire pour envoyer des messages flash:
use App\Components\FlashMessages;

class ProductsController {

  use FlashMessages;

  public function store(Request $request)
  {
      self::message('info', 'Just a plain message.');
      self::message('success', 'Item has been added.');
      self::message('warning', 'Service is currently under maintenance.');
      self::message('danger', 'An unknown error occured.');

      //or

      self::info('Just a plain message.');
      self::success('Item has been added.');
      self::warning('Service is currently under maintenance.');
      self::danger('An unknown error occured.');
  }

  ...

J'espère que ça vous aidera.

clemquinones
la source
13

Renvoyez simplement avec le «drapeau» que vous souhaitez traiter sans utiliser de fonction utilisateur supplémentaire. Le controlle:

return \Redirect::back()->withSuccess( 'Message you want show in View' );

Notez que j'ai utilisé le drapeau «Succès».

La vue:

@if( Session::has( 'success' ))
     {{ Session::get( 'success' ) }}
@elseif( Session::has( 'warning' ))
     {{ Session::get( 'warning' ) }} <!-- here to 'withWarning()' -->
@endif

Oui, ça marche vraiment!

Richelly Italo
la source
Vous avez une tonne de fautes de frappe dans votre réponse, mais votre approche fonctionne très bien.
Bat Lanyard
6

Une autre solution serait de créer une classe d'assistance Comment créer des classes d'assistance ici

class Helper{
     public static function format_message($message,$type)
    {
         return '<p class="alert alert-'.$type.'">'.$message.'</p>'
    }
}

Ensuite, vous pouvez le faire.

Redirect::to('users/login')->with('message', Helper::format_message('A bla blah occured','error'));

ou

Redirect::to('users/login')->with('message', Helper::format_message('Thanks for registering!','info'));

et à votre avis

@if(Session::has('message'))
    {{Session::get('message')}}
@endif
Ayobami Opeyemi
la source
5
Je ne sais pas si je recommanderais cette approche car elle supprime le HTML de la vue et le transforme en code.
Nick Coad
5

Pas un grand fan des solutions fournies (c'est-à-dire: plusieurs variables, des classes d'assistance, une boucle à travers des «variables éventuellement existantes»). Vous trouverez ci-dessous une solution qui utilise à la place un tableau par opposition à deux variables distinctes. Il est également facilement extensible pour gérer plusieurs erreurs si vous le souhaitez, mais pour plus de simplicité, je l'ai conservé dans un seul message flash:

Redirection avec le tableau de messages flash :

    return redirect('/admin/permissions')->with('flash_message', ['success','Updated Successfully','Permission "'. $permission->name .'" updated successfully!']);

Sortie basée sur le contenu du tableau:

@if(Session::has('flash_message'))
    <script type="text/javascript">
        jQuery(document).ready(function(){
            bootstrapNotify('{{session('flash_message')[0]}}','{{session('flash_message')[1]}}','{{session('flash_message')[2]}}');
        });
    </script>
@endif

Sans rapport puisque vous pourriez avoir votre propre méthode / plugin de notification - mais juste pour plus de clarté - bootstrapNotify est juste pour lancer bootstrap-notify depuis http://bootstrap-notify.remabledesigns.com/ :

function bootstrapNotify(type,title = 'Notification',message) {
    switch (type) {
        case 'success':
            icon = "la-check-circle";
            break;
        case 'danger':
            icon = "la-times-circle";
            break;
        case 'warning':
            icon = "la-exclamation-circle";
    }

    $.notify({message: message, title : title, icon : "icon la "+ icon}, {type: type,allow_dismiss: true,newest_on_top: false,mouse_over: true,showProgressbar: false,spacing: 10,timer: 4000,placement: {from: "top",align: "right"},offset: {x: 30,y: 30},delay: 1000,z_index: 10000,animate: {enter: "animated bounce",exit: "animated fadeOut"}});
}
SupaMonkey
la source
4

Pour mon application, j'ai créé une fonction d'assistance:

function message( $message , $status = 'success', $redirectPath = null )
{
     $redirectPath = $redirectPath == null ? back() : redirect( $redirectPath );

     return $redirectPath->with([
         'message'   =>  $message,
         'status'    =>  $status,
    ]);
}

mise en page de message, main.layouts.message:

@if($status)
   <div class="center-block affix alert alert-{{$status}}">
     <i class="fa fa-{{ $status == 'success' ? 'check' : $status}}"></i>
     <span>
        {{ $message }}
     </span>
   </div>
@endif

et importez partout où afficher le message:

@include('main.layouts.message', [
    'status'    =>  session('status'),
    'message'   =>  session('message'),
])
ivahidmontazer
la source
3

Je fais ça d'habitude

dans ma fonction store (), je mets une alerte de succès une fois qu'elle a été enregistrée correctement.

\Session::flash('flash_message','Office successfully updated.');

dans ma fonction destroy (), je voulais colorer l'alerte en rouge afin de notifier qu'elle est supprimée

\Session::flash('flash_message_delete','Office successfully deleted.');

Remarquez, nous créons deux alertes avec des noms de flash différents.

Et à mon avis, j'ajouterai des conditions pour savoir quand le bon moment, l'alerte spécifique sera appelée

@if(Session::has('flash_message'))
    <div class="alert alert-success"><span class="glyphicon glyphicon-ok"></span><em> {!! session('flash_message') !!}</em></div>
@endif
@if(Session::has('flash_message_delete'))
    <div class="alert alert-danger"><span class="glyphicon glyphicon-ok"></span><em> {!! session('flash_message_delete') !!}</em></div>
@endif

Ici vous pouvez trouver différents messages flash stlyes Flash Messages dans Laravel 5

Ikong
la source
3

Vous pouvez utiliser les macros Laravel.

Vous pouvez créer macros.php dans app/helperset inclure routes.php.

si vous souhaitez mettre vos macros dans un fichier de classe à la place, vous pouvez consulter ce tutoriel: http://chrishayes.ca/blog/code/laravel-4-object-oriented-form-html-macros-classes-service- fournisseur

HTML::macro('alert', function($class='alert-danger', $value="",$show=false)
{

    $display = $show ? 'display:block' : 'display:none';

    return
        '<div class="alert '.$class.'" style="'.$display.'">
            <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
            <strong><i class="fa fa-times"></i></strong>'.$value.'
        </div>';
});

Dans votre contrôleur:

Session::flash('message', 'This is so dangerous!'); 
Session::flash('alert', 'alert-danger');

Dans votre vue

@if(Session::has('message') && Session::has('alert') )
  {{HTML::alert($class=Session::get('alert'), $value=Session::get('message'), $show=true)}}
@endif
Emeka Mbah
la source
3

Je pense que ce qui suit fonctionnerait bien avec une ligne de codes moindre.

        session()->flash('toast', [
        'status' => 'success', 
        'body' => 'Body',
        'topic' => 'Success']
    );

J'utilise un paquet de grille-pain, mais vous pouvez avoir quelque chose comme ça dans votre vue.

             toastr.{{session('toast.status')}}(
              '{{session('toast.body')}}', 
              '{{session('toast.topic')}}'
             );
Segun Kess
la source
2

Dans le contrôleur:

Redirect::to('/path')->with('message', 'your message'); 

Ou

Session::flash('message', 'your message'); 

dans le message d'affichage de la lame dans la lame selon le modèle souhaité:

@if(Session::has('message'))
    <div class="alert alert-className">
        {{session('message')}}
    </div>
@endif
PraKash
la source
Comment passez-vous le className?
Boss COTIGA
1

Envoyez simplement un tableau dans la session plutôt qu'une chaîne, comme ceci:

Session::flash('message', ['text'=>'this is a danger message','type'=>'danger']);

@if(Session::has('message'))
    <div class="alert alert-{{session('message')['type']}}">
        {{session('message')['text']}}
    </div>
@endif
shamaseen
la source
0

Je suis tombé sur cette manière élégante de flasher des messages. Il a été fabriqué par Jeffrey Way de Laracast. Découvrez-le ... https://github.com/laracasts/flash

Johan H.
la source
0

Si vous souhaitez utiliser Bootstrap Alert pour rendre votre vue plus interactive. Vous pouvez faire quelque chose comme ceci:

Dans votre fonction: -

if($author->save()){
    Session::flash('message', 'Author has been successfully added');
    Session::flash('class', 'success'); //you can replace success by [info,warning,danger]
    return redirect('main/successlogin');

À votre avis: -

@if(Session::has('message'))
    <div class="alert alert-{{Session::get('class')}} alert-dismissible fade show w-50 ml-auto alert-custom"
        role="alert">
        {{ Session::get('message') }}
        <button type="button" class="close" data-dismiss="alert" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
@endif
Riwaj Chalise
la source