Flask Message Flashing: Ersetzen Sie Bootstrap Alerts durch Toasts
Anzeigen von Benachrichtigungen an einer festen Position über dem Bildschirminhalt, nicht irgendwo in unser Layout gequetscht.
Wenn Sie eine Flask -Anwendung mit Bootstrap haben, verwenden Sie wahrscheinlich Bootstrap Alerts , um flashed messages anzuzeigen. Ich benutze sie, und sie funktionieren, aber ich bin nicht wirklich zufrieden. Standardmäßig sehen sie nicht schön aus, und in den meisten Fällen nehmen sie viel Platz auf dem Bildschirm ein. Und wollen Sie wirklich, dass Benachrichtigungen wie "Sie sind eingeloggt" ein Bootstrap Alert sind, der vom user geschlossen werden muss? Durch Hinzufügen einer Zeitüberschreitung können wir die Bootstrap Alert automatisch entfernen, aber das ist noch hässlicher!
Bootstrap Toasts
Mit Bootstrap Toasts können wir Benachrichtigungen erstellen, die an einer festen Position oberhalb des Bildschirminhalts platziert werden und nicht irgendwo in unser Layout gequetscht werden. Wir verwenden 'position-fixed' im 'toast-container', um den toast im viewport sichtbar zu machen. Ich habe mein toasts oben rechts platziert, aber mit einem gewissen Versatz zum oberen Rand des Bildschirms. Ich musste auch die 'z-index' erhöhen, um sicherzustellen, dass die toast immer oben liegt.
<style>
.toast-container-extra {
top: 30px;
z-index: 10000;
}
</style>
Wenn Sie mehrere toasts haben, wollen Sie wahrscheinlich nicht, dass toasts übereinander liegen, sondern gestapelt:
- Das zweite toast wird unter dem ersten angezeigt
- Das dritte toast wird unter dem zweiten angezeigt
- usw.
Das bedeutet, dass wir, wenn wir ein toast anzeigen wollen, etwas Javascript / JQuery-Code benötigen, um:
- Erstellen des toast HTML aus einer Vorlage
- Hinzufügen der Nachricht toast
- Fügen Sie die toast HTML an unsere toast-container an
- Sagen Sie Bootstrap , dass wir einen neuen toast haben
- Bootstrap soll den toast anzeigen
Sie verwenden wahrscheinlich bereits Flask Message Flashing mit Kategorien:
flash('Invalid password provided', 'error')
...
flash('Invalid password provided', 'info')
Im Folgenden habe ich die toast-container und zwei toast Vorlagen definiert, eine Vorlage für die Kategorie 'error' und eine Vorlage für die Kategorie 'info'. Die Vorlage 'error' toast benötigt die Vorlage user , um sie zu schließen, die Vorlage 'info' toast schließt sich automatisch nach einigen Sekunden.
Die Kategorievorlage wird durch das Attribut "data-stack-toast-category" identifiziert, wir wollen doppelte Id's vermeiden.
{# stacked toasts container - start #}
<div class="toast-container position-fixed end-0 p-3 pt-0 toast-container-extra" id="toast-stack-container">
</div>
{# stacked toasts container - end #}
{# stacked toast error template - start #}
<div
class="toast mt-0"
role="alert"
aria-live="assertive"
aria-atomic="true"
data-bs-autohide="false"
data-stack-toast-category="error">
<div class="toast-header border-bottom border-white">
<strong class="me-auto">
Error
</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body toast-message"></div>
</div>
{# stacked toast error template - end #}
{# stacked toast info template - start #}
<div class="toast mt-0"
role="status"
aria-live="polite"
aria-atomic="true"
data-stack-toast-category="info">
<div class="toast-header border-bottom border-white">
<strong class="me-auto">
Info
</strong>
<button type="button" class="btn-close" data-bs-dismiss="toast" aria-label="Close"></button>
</div>
<div class="toast-body toast-message"></div>
</div>
{# stacked toast info template - end #}
Hier ist der Code zum Hinzufügen einer toast, die zu Ihrer Website Javascript -Datei hinzugefügt werden soll:
const toast_stack_container_elem = document.getElementById('toast-stack-container');
const error_toast_template_elem = document.querySelector('[data-stack-toast-category="error"]');
const info_toast_template_elem = document.querySelector('[data-stack-toast-category="info"]');
function create_toast_add_to_stack(category, message){
var new_toast;
switch(category){
case 'error':
new_toast = error_toast_template_elem.cloneNode(true);
break;
default:
new_toast = info_toast_template_elem.cloneNode(true);
}
var toast_message_elem = new_toast.querySelector('.toast-message');
if(toast_message_elem){
toast_message_elem.innerHTML = message;
}
toast_stack_container_elem.append(new_toast);
const toast = bootstrap.Toast.getOrCreateInstance(new_toast);
toast.show();
return;
}
Jetzt möchten Sie wahrscheinlich zwei "show toast"-Buttons und etwas Code hinzufügen, um zu überprüfen, ob dies funktioniert.
Ändern der Basisvorlage
Wahrscheinlich haben Sie eine Basisvorlage mit folgendem Code, um flashed messages mit Bootstrap Alerts anzuzeigen:
{% with messages = get_flashed_messages(with_categories=true) -%}
{% for category, message in messages -%}
{% if category == 'error' -%}
{% set alert_class = 'alert-danger' -%}
{% else -%}
{% set alert_class = 'alert-info' -%}
{% endif -%}
<div class="alert {{ alert_class }} alert-dismissible mb-3" role="alert">
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
{{ message }}
</div>
{% endfor -%}
{% endwith -%}
Um Bootstrap toasts zu verwenden, müssen wir diesen Code ändern. Ich verwende hier JSON , um Content Security Policy (CSP) Fehler zu vermeiden.
{% with messages = get_flashed_messages(with_categories=true) -%}
{% set flashed_messages_page_data_js={} -%}
{% set x=flashed_messages_page_data_js.__setitem__('messages', messages) -%}
<script type="application/json" data-selector="flashed-messages-page-data-js">
{{ flashed_messages_page_data_js|tojson }}
</script>
{% endwith -%}
Und dann fügen Sie den folgenden Code in Ihre Website Javascript -Datei ein:
$(document).ready(function(){
try {
if($('script[data-selector="flashed-messages-page-data-js"]').length){
var flashed_messages_page_data_js = JSON.parse($('script[data-selector="flashed-messages-page-data-js"]').html());
if(flashed_messages_page_data_js.hasOwnProperty('messages')){
var messages = flashed_messages_page_data_js.messages;
for(var i = 0; i < messages.length; i++){
var category = messages[i][0];
var message = messages[i][1];
create_toast_add_to_stack(category, message);
}
}
}
}
catch(error){
// no-op
console.log('flashed messages, error = ');
console.log(error);
}
});
Zusammenfassung
Wir haben Bootstrap Alerts durch Bootstrap Toasts mit Flask Message Flashing ersetzt. Das ist schön, aber wir wollen wahrscheinlich eine feinere Kontrolle. Wir könnten zusätzliche Kategorien für Fälle hinzufügen, in denen wir immer noch Bootstrap -Warnungen wünschen, zum Beispiel:
- 'error-alert'
- Info-Warnung
Wir könnten auch die Funktion "flash()" außer Kraft setzen und Parameter hinzufügen wie:
- notification_type
- auto_hide
Aber bevor wir das Rad noch einmal neu erfinden, sollten wir vielleicht erst einmal prüfen, wie Benachrichtigungen und Warnungen auf Mobiltelefonen angezeigt werden. Ein anderes Mal ...
Links / Impressum
Bootstrap - Alerts
https://getbootstrap.com/docs/5.1/components/alerts
Bootstrap - Toasts
https://getbootstrap.com/docs/5.2/components/toasts
Flask - Message Flashing
https://flask.palletsprojects.com/en/2.1.x/patterns/flashing
Inline Data With a Content Security Policy
https://itnext.io/inline-data-with-a-content-security-policy-ab30dde2feb3
Toasts
https://preview.keenthemes.com/start/documentation/base/toasts.html
Neueste
- Ausblenden der Primärschlüssel der Datenbank UUID Ihrer Webanwendung
- Don't Repeat Yourself (DRY) mit Jinja2
- SQLAlchemy, PostgreSQL, maximale Anzahl von Zeilen pro user
- Anzeige der Werte in den dynamischen Filtern SQLAlchemy
- Sichere Datenübertragung mit Public Key Verschlüsselung und pyNaCl
- rqlite: eine hochverfügbare und distverteilte SQLite -Alternative
Meistgesehen
- Verwendung von Pythons pyOpenSSL zur Überprüfung von SSL-Zertifikaten, die von einem Host heruntergeladen wurden
- Verwendung von UUIDs anstelle von Integer Autoincrement Primary Keys mit SQLAlchemy und MariaDb
- Verbindung zu einem Dienst auf einem Docker -Host von einem Docker -Container aus
- PyInstaller und Cython verwenden, um eine ausführbare Python-Datei zu erstellen
- SQLAlchemy: Verwendung von Cascade Deletes zum Löschen verwandter Objekte
- Flask RESTful API Validierung von Anfrageparametern mit Marshmallow-Schemas