Notificaciones Toast
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeUna parte importante de cualquier sitio bonito y funcional es un sistema de notificaciones. En Symfony, a menudo pensamos en mensajes flash: mensajes que mostramos cerca de la parte superior de la página, por ejemplo, después de que el usuario envíe un formulario. Y sí, a eso me refiero. Pero no nos basta con mostrarlos en la parte superior de la página. En lugar de eso, quiero mostrarlas como notificaciones ricas de estilo tostado en la parte superior derecha, que desaparezcan automáticamente con transiciones CSS y que puedan atarme los zapatos por mí.
Representación de mensajes Flash
En nuestros controladores CRUD, ya estoy configurando un mensaje flash success
... pero no lo estoy renderizando en ninguna parte. En el directorio templates/
, crea un nuevo _flashes.html.twig
. Para empezar, simplemente haz un bucle sobre los mensajes de éxito con for message in
app.flashes('success')
... y endfor
:
{% for message in app.flashes('success') %} | |
// ... lines 2 - 4 | |
{% endfor %} |
Dentro, pegaré un mensaje flash muy sencillo, que empezará a fijarse en la parte inferior de la página:
{% for message in app.flashes('success') %} | |
<div class="fixed bottom-0 right-0 m-4 p-4 bg-green-500 text-white rounded shadow"> | |
{{ message }} | |
</div> | |
{% endfor %} |
A continuación, en base.html.twig
, en lugar de poner los flashes en algún lugar cerca de la parte superior del cuerpo, ponlos en la parte inferior. Digamos <div id="flash-container">
y luego{{ include('_flashes.html.twig') }}
:
<html> | |
// ... lines 3 - 15 | |
<body class="bg-black text-white font-mono"> | |
// ... lines 17 - 51 | |
<div id="flash-container"> | |
{{ include('_flashes.html.twig') }} | |
</div> | |
</body> | |
</html> |
El id="flash-container"
no es importante todavía, pero será útil más adelante cuando hablemos de los flujos Turbo.
Veamos si funciona Pulsa "Guardar" y... ¡ya está! Está en un sitio raro, pero aparece.
Hacer bonita la notificación
Para que quede más bonito, vamos a Flowbite. Busca "tostada". Ah, esto tiene algunos ejemplos geniales de diferentes estilos de notificaciones tostadas. ¡Esto me hace sentir peligroso!
Tip
También recomiendo añadir un atributo data-turbo-temporary
a la raíz <div>
. Esto eliminará el mensaje flash antes de que Turbo tome su "instantánea" para el almacenamiento en caché, Esto significa que si el usuario hace clic en "Volver" a una página, el brindis no seguirá siendo visible.
De vuelta en _flashes.html.twig
, pegaré algo de contenido:
{% for message in app.flashes('success') %} | |
<div | |
class="fixed top-5 right-5 flex items-center w-full max-w-xs p-4 mb-4 text-gray-500 bg-white rounded-lg shadow dark:text-gray-400 dark:bg-gray-800" | |
role="alert" | |
> | |
<div class="inline-flex items-center justify-center flex-shrink-0 w-8 h-8 text-green-500 bg-green-100 rounded-lg dark:bg-green-800 dark:text-green-200"> | |
<svg class="w-5 h-5" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="currentColor" viewBox="0 0 20 20"> | |
<path d="M10 .5a9.5 9.5 0 1 0 9.5 9.5A9.51 9.51 0 0 0 10 .5Zm3.707 8.207-4 4a1 1 0 0 1-1.414 0l-2-2a1 1 0 0 1 1.414-1.414L9 10.586l3.293-3.293a1 1 0 0 1 1.414 1.414Z"/> | |
</svg> | |
<span class="sr-only">Check icon</span> | |
</div> | |
<div class="ms-3 text-sm font-normal">{{ message }}</div> | |
<button | |
type="button" | |
class="ms-auto -mx-1.5 -my-1.5 bg-white text-gray-400 hover:text-gray-900 rounded-lg focus:ring-2 focus:ring-gray-300 p-1.5 hover:bg-gray-100 inline-flex items-center justify-center h-8 w-8 dark:text-gray-500 dark:hover:text-white dark:bg-gray-800 dark:hover:bg-gray-700" | |
aria-label="Close" | |
> | |
<span class="sr-only">Close</span> | |
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14"> | |
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6"/> | |
</svg> | |
</button> | |
</div> | |
{% endfor %} |
Esto está muy inspirado en los ejemplos de Flowbite. Pero en realidad no ha cambiado nada: seguimos haciendo bucles sobre la misma colección y seguimos volcando el mensaje. Sólo tenemos un bonito marcado alrededor de esto.
¡Y no puedo querer verlo! Voy a editar y a "Guardar". Qué maravilla! En la parte superior derecha, donde yo quiero, y todo hecho con CSS.
Hacer que la tostada se pueda cerrar
Aunque todavía no se cierra automáticamente. Demonios, ¡no se cierra en absoluto! Como "cerrar" cosas será un problema común, vamos a crear un controlador Stimulus reutilizable que pueda hacerlo.
En assets/controller/
, añade un nuevo closeable_controller.js
. Haré trampas y cogeré el código de otro controlador... límpialo... y luego añade un método close()
. Cuando se llame a éste, eliminará todo el elemento al que está unido el controlador:
import { Controller } from '@hotwired/stimulus'; | |
export default class extends Controller { | |
close() { | |
this.element.remove(); | |
} | |
} |
Para utilizar esto, en _flashes.html.twig
, adjunta el controlador al elemento de nivel superior, porque eso es lo que debe eliminarse al cerrarse. A continuación, en el botóndata-action="closeable#close"
:
{% for message in app.flashes('success') %} | |
<div | |
// ... lines 3 - 4 | |
data-controller="closeable" | |
> | |
// ... lines 7 - 13 | |
<button | |
// ... lines 15 - 17 | |
data-action="closeable#close" | |
> | |
// ... lines 20 - 23 | |
</button> | |
</div> | |
{% endfor %} |
No necesitamos el click
porque esto es un button
, así que Stimulus ya sabe que queremos que esto se active en el evento click
.
¡Vamos a probarlo! Pulsa editar y Guardar. Ya está... ha desaparecido.
En sólo unos minutos de trabajo, ¡hemos creado un bonito y funcional sistema de notificación de tostadas! Pero, ¡maldita sea, esto no es lo suficientemente guay para nuestra misión 30 Días de LAST Stack! Así que mañana lo mejoraremos con autocierre, transiciones CSS y una barra de temporizador animada.
The problem with "code blocks" (and with this comment I refer to Flowbite Toast component) is that it is difficult to find.
I expect to find separately, maybe in a comment (as done by ToG for first version of _flashes.html.twig ), but there is not.
So my second idea is to search in "Course code"... but where? There are 2 folders: "start" and "finish". I naturally go inside "start" because I think that "start" is the "actual-state-of-code-at-the-start-of-the-lesson".
Moreover I am not sure that in "finish" directory contains the current version of the script I need. I am not sure, for example, that content of
_flashes.html.twig
is the same as in the video.Let's say the
_flashes.htm.twig
will be also modified in lesson 23, the question is: which version of that file will I find in "finish" directory? Version in lesson 16 or the modified one in lesson 23?Cheers
Danilo