How to display Flash Messages in Different Colors

I want to use the full gamut of Bootstrap Alert ‘types’ (and their associated colors);
primary, secondary, success, danger, warning, info, light and dark.

In Phoenix:
put_flash(:info, message) displays a Bootstrap ‘info’ alert
put_flash(:error, message) displays a Bootstrap ‘danger’ alert

I’ve tried a put_flash(:success, message) command but it results in no flash message being displayed.

Some Questions:
Why does Phoenix translate an :error type to :danger? It results in the coloring I would have expected but wouldn’t it have been easier(?) to set the CSS class in strict accordance with the Bootstrap CSS classes? I realize that not everyone utilizes Bootstrap so they may feel a bit ‘left out in the cold’.

With the above being the case, is there a way to build a transformation process for Phoenix such that, if you are using Bootstrap, use the first argument (an atom) of the put_flash/2 function as the CSS alert-X class to be used for displaying the flash message?

Examples:

put_flash(:success, "The Message") 
<p class="alert alert-success" role="alert">The Message</p>

put_flash(:warning, "The Message") 
<p class="alert alert-warning" role="alert">The Message</p>
1 Like

All put_flash does is store a text string in conn.private under the :phoenix_flash key. You can display the message however you’d like by changing it in layout.eex.html

It looks like a good use case to write specific bootstrap view helpers. I don’t think Phoenix helpers should be linked to Bootstrap.

This is an (untested) example of how you could get whatever flash key and flash message you’d like and then display it with the boostrap conventions you’re describing. layout.html.eex only has templating to display :info and :error by default.

<%= Enum.map(get_flash(@conn), fn {flash_key, flash_message} -> %>
  <p class="alert alert-<%= flash_key %>"><%= flash_message %></p>
<% end) %>
6 Likes

This is from a default app-layout:

      <p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
      <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>

So, as you can see, there is no magic involved in the defaults, they are very explicit, and I usually rewrite this into a loop and a conditional.

3 Likes

Ahhh! Thanks people!! Its easy once you know to look in the obvious places.

I found these lines in the layout.html.eex file:

  <p class="alert alert-info" role="alert"><%= get_flash(@conn, :info) %></p>
  <p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>

With voughtdq’s example I should be good to go.

Thank you for your time and helpful answers!!

1 Like

In Liveview, app.scss offers styling for the alerts and the alert classes are defined in live.html.leex

/* Alerts and form errors */
.alert {
  padding: 15px;
  margin-bottom: 20px;
  border: 1px solid transparent;
  border-radius: 4px; }

.alert-info {
  color: #31708f;
  background-color: #d9edf7;
  border-color: #bce8f1; }

.alert-info {
  color: #31708f;
  background-color: #d9edf7;
  border-color: #bce8f1; }

.alert-warning {
  color: #8a6d3b;
  background-color: #fcf8e3;
  border-color: #faebcc; }

.alert-danger {
  color: #a94442;
  background-color: #f2dede;
  border-color: #ebccd1; }

.alert p {
  margin-bottom: 0; }

Reference of what is available with bootstrap alerts

Bootstrap JS Alert Reference (w3schools.com)