Gästebuch Block
- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Ja - auf jeden Fall, ich verweise als Download auf Deine Seite:
https://www.mobirise-tutorials.com/AI-B ... tbuch.html
https://www.mobirise-tutorials.com/AI-B ... tbuch.html
Re: Gästebuch Block
Tommy halt dich fest
jetzt mache ich dieses Gästebuch auch noch im Bento Style und in einer Schlichten Version, so hat der User ebi Import der Erweiterung 3 Blöcke zur Auswahl
Super Idee
jetzt mache ich dieses Gästebuch auch noch im Bento Style und in einer Schlichten Version, so hat der User ebi Import der Erweiterung 3 Blöcke zur Auswahl
Super Idee
Re: Gästebuch Block
Tommy !!!!
Die KI hat geschlampt
Im Java Script die Smileys vergessen klickbar zu mache
Hier das Java Script für Dich
Im Zip gleich auch drin
Die KI hat geschlampt
Im Java Script die Smileys vergessen klickbar zu mache
Hier das Java Script für Dich
Code: Alles auswählen
<script>
(function() {
var inBuilder = (typeof MbrsiteApp !== 'undefined') || (window.self !== window.top && /mobirise/i.test(document.referrer));
if (inBuilder) return;
var apiPath = 'guestbook-api.php';
var feedContainer = document.getElementById('js-guestbook-feed');
var paginationContainer = document.getElementById('js-gb-pagination');
var form = document.getElementById('js-guestbook-form');
var statusDiv = document.getElementById('gb-status');
var msgField = document.getElementById('gb-message');
var currentSection = document.getElementById('js-guestbook-feed') ? document.getElementById('js-guestbook-feed').closest('section') : null;
var allEntries = [];
var currentPage = 1;
var itemsPerPage = parseInt('{{perPage}}') || 5;
var isAdmin = false;
var enteredPassword = '';
if (currentSection) {
var titleEl = currentSection.querySelector('.js-gb-main-title');
if (titleEl) {
titleEl.addEventListener('dblclick', function(e) {
e.preventDefault();
var pwCheck = prompt('Bitte Admin-Passwort eingeben:');
if (pwCheck !== null && pwCheck.trim() !== '') {
fetch(apiPath, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'checkLogin', password: pwCheck.trim() })
})
.then(response => response.json())
.then(data => {
if (data.success) {
isAdmin = true;
enteredPassword = pwCheck.trim();
alert('Login erfolgreich! Ungeprüfte Beiträge zeigen jetzt das Freischaltfeld. 🔓');
loadEntries();
} else {
alert(data.error);
}
});
}
});
}
// 🔥 FIX: Hier ist das Bindungs-Skript für deine Emoji-Bar!
var emojiButtons = currentSection.querySelectorAll('.emoji-bar .emoji-btn');
emojiButtons.forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.preventDefault();
var chosenEmoji = btn.textContent.replace('Anzeigen', '').trim(); // Bereinigt eventuelle Rückstände
if (msgField) {
var start = msgField.selectionStart;
var end = msgField.selectionEnd;
var text = msgField.value;
msgField.value = text.substring(0, start) + chosenEmoji + text.substring(end);
msgField.focus();
msgField.selectionStart = msgField.selectionEnd = start + chosenEmoji.length;
}
});
});
}
function renderFeed() {
if (!feedContainer) return;
if (!allEntries || allEntries.length === 0) {
feedContainer.innerHTML = '<div class="text-center py-4 text-fallback">Noch keine freigeschalteten Einträge vorhanden.</div>';
if (paginationContainer) paginationContainer.innerHTML = '';
return;
}
var startIndex = (currentPage - 1) * itemsPerPage;
var endIndex = startIndex + itemsPerPage;
var pageEntries = allEntries.slice(startIndex, endIndex);
var html = '';
pageEntries.forEach(function(entry) {
var date = new Date(entry.created_at.replace(/-/g, "/"));
var formattedDate = date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' }) + ' - ' + date.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }) + ' Uhr';
var styleOverride = (entry.status == 0) ? 'style="border: 1px solid #eab308 !important; background: rgba(234, 179, 8, 0.08) !important;"' : '';
var titleAddon = (entry.status == 0) ? ' <span style="color:#eab308;font-size:0.75rem;">(Wartet auf Freischaltung)</span>' : '';
html += '<div class="guestbook-entry-card mb-3 glass-card" data-id="' + entry.id + '" ' + styleOverride + '>';
html += ' <div class="entry-header">';
html += ' <strong class="entry-author">' + entry.name + titleAddon + '</strong>';
html += ' <div class="d-flex align-items-center gap-3">';
html += ' <span class="entry-date">' + formattedDate + '</span>';
if (isAdmin) {
html += ' <button class="btn-edit-entry" title="Eintrag bearbeiten" style="background:none; border:none; cursor:pointer; font-size:1.1rem; padding:0; line-height:1;">✏️</button>';
html += ' <button class="btn-delete-entry" title="Eintrag löschen" style="background:none; border:none; cursor:pointer; font-size:1.1rem; padding:0; line-height:1;">🗑️</button>';
}
html += ' </div>';
html += ' </div>';
html += ' <p class="entry-text js-entry-text-target">' + entry.message.replace(/\n/g, '<br>') + '</p>';
if (isAdmin && entry.status == 0) {
html += ' <div class="mt-3 text-end js-approve-wrapper">';
html += ' <button class="btn btn-sm btn-success btn-approve-action" style="padding: 6px 14px; font-size: 0.85rem; font-weight: bold; border-radius: 6px; border: none; background-color: #22c55e !important; color: #fff !important;">';
html += ' ✅ Eintrag freischalten';
html += ' </button>';
html += ' </div>';
}
html += '</div>';
});
feedContainer.innerHTML = html;
if (isAdmin) {
feedContainer.querySelectorAll('.btn-approve-action').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.stopPropagation();
var card = btn.closest('.guestbook-entry-card');
var id = card.getAttribute('data-id');
approveEntry(id, card);
});
});
feedContainer.querySelectorAll('.btn-delete-entry').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.stopPropagation();
var card = btn.closest('.guestbook-entry-card');
var id = card.getAttribute('data-id');
if (confirm('Möchtest du diesen Eintrag wirklich unwiderruflich löschen?')) {
deleteEntry(id, card);
}
});
});
feedContainer.querySelectorAll('.btn-edit-entry').forEach(function(btn) {
btn.addEventListener('click', function(e) {
e.stopPropagation();
var card = btn.closest('.guestbook-entry-card');
var id = card.getAttribute('data-id');
var textP = card.querySelector('.js-entry-text-target');
if (card.classList.contains('is-editing')) return;
card.classList.add('is-editing');
var origEntry = allEntries.find(item => item.id == id);
var currentRawText = origEntry ? origEntry.message : textP.innerText;
textP.innerHTML = '<textarea class="form-control mb-2 js-edit-textarea" rows="4" style="color:#000 !important; background:#fff !important;">' + currentRawText + '</textarea>' +
'<button class="btn btn-sm btn-success js-save-edit-btn" style="padding:4px 10px; font-size:0.8rem;">💾 Speichern</button> ' +
'<button class="btn btn-sm btn-danger js-cancel-edit-btn" style="padding:4px 10px; font-size:0.8rem;">Abbrechen</button>';
card.querySelector('.js-save-edit-btn').addEventListener('click', function() {
var newText = card.querySelector('.js-edit-textarea').value;
updateEntryText(id, newText, card);
});
card.querySelector('.js-cancel-edit-btn').addEventListener('click', function() {
renderFeed();
});
});
});
}
renderPaginationControls();
}
function approveEntry(id, card) {
fetch(apiPath, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'approve', id: id, password: enteredPassword })
})
.then(response => response.json())
.then(data => {
if (data.success) {
var entry = allEntries.find(item => item.id == id);
if (entry) entry.status = 1;
renderFeed();
} else {
alert(data.error);
}
})
.catch(err => alert('Fehler bei der Freischaltung.'));
}
function updateEntryText(id, newText, card) {
fetch(apiPath, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'update', id: id, message: newText, password: enteredPassword })
})
.then(response => response.json())
.then(data => {
if (data.success) {
var entry = allEntries.find(item => item.id == id);
if (entry) entry.message = newText;
renderFeed();
} else {
alert(data.error);
}
})
.catch(err => alert('Fehler beim Speichern.'));
}
function renderPaginationControls() {
if (!paginationContainer) return;
var totalPages = Math.ceil(allEntries.length / itemsPerPage);
if (totalPages <= 1) {
paginationContainer.innerHTML = '';
return;
}
var html = '';
html += '<button class="pag-btn" data-page="' + (currentPage - 1) + '"' + (currentPage === 1 ? ' disabled' : '') + '>«</button>';
for (var i = 1; i <= totalPages; i++) {
html += '<button class="pag-btn' + (i === currentPage ? ' active' : '') + '" data-page="' + i + '">' + i + '</button>';
}
html += '<button class="pag-btn" data-page="' + (currentPage + 1) + '"' + (currentPage === totalPages ? ' disabled' : '') + '>»</button>';
paginationContainer.innerHTML = html;
paginationContainer.querySelectorAll('.pag-btn').forEach(function(btn) {
btn.addEventListener('click', function() {
var targetPage = parseInt(btn.getAttribute('data-page'));
if (targetPage >= 1 && targetPage <= totalPages) {
currentPage = targetPage;
renderFeed();
feedContainer.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
});
});
}
function loadEntries() {
var url = apiPath + (isAdmin ? '?adminCheck=' + encodeURIComponent(enteredPassword) : '');
fetch(url)
.then(response => response.json())
.then(data => {
if (!data.success) {
feedContainer.innerHTML = '<div class="alert alert-danger">' + data.error + '</div>';
return;
}
allEntries = data.entries || [];
renderFeed();
})
.catch(err => {
if(feedContainer) {
feedContainer.innerHTML = '<div class="text-center py-4 text-fallback">Warte auf ersten Eintrag...</div>';
}
});
}
function deleteEntry(id, card) {
fetch(apiPath, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ action: 'delete', id: id, password: enteredPassword })
})
.then(response => response.json())
.then(data => {
if (data.success) {
card.style.transition = 'all 0.3s ease';
card.style.opacity = '0';
card.style.transform = 'scale(0.9)';
setTimeout(function() {
allEntries = allEntries.filter(entry => entry.id != id);
var totalPages = Math.ceil(allEntries.length / itemsPerPage);
if (currentPage > totalPages && currentPage > 1) {
currentPage = totalPages;
}
renderFeed();
}, 300);
} else {
alert(data.error);
}
});
}
if (form) {
form.addEventListener('submit', function(e) {
e.preventDefault();
var nameVal = document.getElementById('gb-name').value;
var msgVal = msgField.value;
statusDiv.style.display = 'block';
statusDiv.className = 'mt-3 small text-fallback';
statusDiv.textContent = 'Eintrag wird zur Prüfung gesendet... ⏳';
fetch(apiPath, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: nameVal, message: msgVal })
})
.then(response => response.json())
.then(data => {
if (data.success) {
statusDiv.textContent = 'Vielen Dank! Dein Eintrag wird geprüft und bald freigeschaltet. 🎉';
form.reset();
currentPage = 1;
loadEntries();
setTimeout(function() { statusDiv.style.display = 'none'; }, 5000);
} else {
statusDiv.textContent = data.error;
}
})
.catch(err => {
statusDiv.textContent = 'Fehler beim Senden.';
});
});
}
loadEntries();
})();
</script>- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Alles klar, mache ich morgen früh ...
Re: Gästebuch Block
Mein Bento Style GB ist auch fertig
https://www.niederastroth.de/bentogb/
Obs gefällt ? ich weiß es nicht, aber ist halt Bento Style
Und ich hab es geschafft
Das war mir wichtig 
https://www.niederastroth.de/bentogb/
Obs gefällt ? ich weiß es nicht, aber ist halt Bento Style
- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Moin Volker,
danke nochmals für das schöne Gästebuch
Bei mir funktionieren nun auch wieder die Smileys:
https://www.mobirise-tutorials.com/AI-B ... tbuch.html
Ich habe mir jetzt eine eigene Erweiterung als .mbrext nochmals neu erstellt, denn bei Deiner fehlen jetzt die Bilder und daher kann man diese unter den Mobirise Erweiterungen nicht mehr ausmachen, man sieht nur eine leere Kachel.
Weiterhin ist die Vorlage für die SMTP Mail bei Dir mangelhaft, so weiß niemand, was er da eintragen soll, wenn Du alles leer lässt und keine Kommentare schreibst. Bei mir sieht das jetzt so aus:
Das solltest Du schnell nochmals neu erstellen - prüfst Du denn die Dateien, die Du erstellst, nicht
Grundsätzlich solltest Du auch darüber nachdenken, nicht immer dasselbe Bild für jede Anwendung zu verwenden. So sind die Anwendungen nur schwer zu finden. Das Prinzip von Mobirise ist doch, jeder Erweiterung eine aussagekräftige Beschreibung und ein passendes Bild zuzuordnen.
Das "Bento Gästebuch" ist jetzt für mich persönlich etwas zu wild - aber warum nicht - ist mal etwas anderes
danke nochmals für das schöne Gästebuch
Bei mir funktionieren nun auch wieder die Smileys:
Ich habe mir jetzt eine eigene Erweiterung als .mbrext nochmals neu erstellt, denn bei Deiner fehlen jetzt die Bilder und daher kann man diese unter den Mobirise Erweiterungen nicht mehr ausmachen, man sieht nur eine leere Kachel.
Weiterhin ist die Vorlage für die SMTP Mail bei Dir mangelhaft, so weiß niemand, was er da eintragen soll, wenn Du alles leer lässt und keine Kommentare schreibst. Bei mir sieht das jetzt so aus:
Code: Alles auswählen
// 🔒 1. DEIN ADMIN-PASSWORT FÜR BROWSER-LOGIN (DOPPELKLICK)
$apiPassword = 'DeinSicheresPasswort';
// 📧 2. SMTP & MAIL EMPFÄNGER CONFIGURATION
$adminEmail = 'mail@DeineDomain.de';
$websiteUrl = 'https://www.DeineDomain.de/eventuelles-Projekt-Verzeichnis/'; // Wichtig für den Freischaltlink!
// 📧 SMTP KONFIGURATION - Leer lassen, wenn du normales PHP-Mail nutzen willst!
// oder jede Zeile mit zwei // deaktivieren, wenn normales PHP-Mail verwendet wird.
define('SMTP_HOST', 'smtp.ionos.de'); // z.B. smtp.ionos.de
define('SMTP_PORT', 465); // 465 (SSL) oder 587 (TLS)
define('SMTP_CRYPT', 'ssl'); // 'ssl', 'tls' oder ''
define('SMTP_USER', 'mail@DeineDomain.de'); // Deine SMTP-Mailadresse
define('SMTP_PASS', '**SMTP-Passwort**'); // Dein echtes Mail-Passwort (leer lassen für PHP-Mail)
Das solltest Du schnell nochmals neu erstellen - prüfst Du denn die Dateien, die Du erstellst, nicht
Grundsätzlich solltest Du auch darüber nachdenken, nicht immer dasselbe Bild für jede Anwendung zu verwenden. So sind die Anwendungen nur schwer zu finden. Das Prinzip von Mobirise ist doch, jeder Erweiterung eine aussagekräftige Beschreibung und ein passendes Bild zuzuordnen.
Das "Bento Gästebuch" ist jetzt für mich persönlich etwas zu wild - aber warum nicht - ist mal etwas anderes
Re: Gästebuch Block
Moin Tommy,
Du bist echt der Knaller
JA hab die Bilder vergessen - ist aber auch ein bisschen Stress gewesen - immer einen Tommy im Nacken der immer alles will
Ich habe jetzt alles ordentlich im Zip. Auch das Bento Style ist nun als Block da verfügbar
Klar prüfe ich alle meine Scripte und Blöcke immer - durch Dich
Wofür hab ich dich denn ?

https://www.niederastroth.de/gaestebuch.html
Du bist echt der Knaller
JA hab die Bilder vergessen - ist aber auch ein bisschen Stress gewesen - immer einen Tommy im Nacken der immer alles will
Ich habe jetzt alles ordentlich im Zip. Auch das Bento Style ist nun als Block da verfügbar
Klar prüfe ich alle meine Scripte und Blöcke immer - durch Dich
https://www.niederastroth.de/gaestebuch.html
- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Schöne Gästebuchseite --- NUR --- ohne Download-Button 
Re: Gästebuch Block
Das ist doch auch mein richtiges GB für meine Seite.
Der Download kommt gleich auch noch wie bei allen meiner Blöcke als separate Seite
Der Download kommt gleich auch noch wie bei allen meiner Blöcke als separate Seite
Re: Gästebuch Block
Hier die offizielle Download Seite :
https://www.niederastroth.de/gaestebuch_block.html
Hab mal bei Dir abgeschrieben
https://www.niederastroth.de/gaestebuch_block.html
Hab mal bei Dir abgeschrieben
- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Sehr schön - alles fertig - dann können wir ja ½ Stunde Pause machen 
- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Du musst den Text an einer Stelle etwas anpassen:
Original:
Die meinem Download beiliegende .mbrext-Datei gastbuch.mbrext
Sollte auf Deiner Seite heißen:
Die meinem Download beiliegende .mbrext-Datei gaestebuch.mbrext
Original:
Die meinem Download beiliegende .mbrext-Datei gastbuch.mbrext
Sollte auf Deiner Seite heißen:
Die meinem Download beiliegende .mbrext-Datei gaestebuch.mbrext
Re: Gästebuch Block
Ha ha
blind abschreiben ist immer ein Fehler
blind abschreiben ist immer ein Fehler
- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Im Gästebuch können Admins übrigens HTML-Code verwenden, sodass sich beliebige Darstellungen realisieren lassen – zum Beispiel Links, Bilder oder Videos:
https://www.mobirise-tutorials.com/AI-B ... tbuch.html
Re: Gästebuch Block
Hi Tommy,
mit deinen Code Verbesserungen werde ich deine mbrext in mein Zip legen wenn das OK für Dich ist
mit deinen Code Verbesserungen werde ich deine mbrext in mein Zip legen wenn das OK für Dich ist
- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Natürlich ist das OK, das sind jetzt aber nicht Verbessererungen, sondern eher Anpassungen an meine Seite. Ich weiß zum Beispiel nicht genau, ob das mit dem neuen Anker der Pagenierung auch bei anderen dann stimmt. Teste das mal. Ansonsten habe ich das im Script kommentiert, sodass man die Höhe auch alleine anpassen kann oder den alten Zustand wieder herstellen kann.
Re: Gästebuch Block
oder ich bau es ins zahnrad dann ist felxibell
- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Solange das Design der Eingabebox sich nicht ändert, sollte das eigentlich passen.
Ich würde das nicht flexibel machen, denn das geht schief beim Benutzen vom User.
Beim Seitenwechsel soll der Gästebuchblock ja nur halbwegs logisch beginnen, auch am Handy. Das ist jetzt der Fall.
Ich würde das nicht flexibel machen, denn das geht schief beim Benutzen vom User.
Beim Seitenwechsel soll der Gästebuchblock ja nur halbwegs logisch beginnen, auch am Handy. Das ist jetzt der Fall.
Re: Gästebuch Block
Ich bau es trotzdem mal ein, ist doch einfacher für nutzer als das per hand im code zu ändern. Heute Abend ist das in der mbrext, dann testest du das mal und wenn ok, hauen wir das in die mbrext
Schoieber schon drin
passe ich heute Abend an
PADDING: Oben (rem) — (Steuert den inneren Abstand nach oben)
PADDING: Rechts (rem) — (Steuert den inneren Abstand nach rechts)
PADDING: Unten (rem) — (Steuert den inneren Abstand nach unten)
PADDING: Links (rem) — (Steuert den inneren Abstand nach links)
Ein kurzes Beispiel zur Funktionsweise:
Stellst du den Schieber auf -100 (Standard), springt die Seite beim Klicken auf Seite 2 so weit hoch, dass über dem Feed noch 100 Pixel Platz frei bleiben (gut, damit der Feed nicht direkt unter die klebrige Menüleiste knallt).
Stellst du ihn auf 0, springt der Browser exakt bündig an die Kante des Feeds.
Stellst du ihn auf -200, bleibt noch mehr Platz nach oben frei.
wenn schon denn schon Tommy
Schoieber schon drin
PADDING: Oben (rem) — (Steuert den inneren Abstand nach oben)
PADDING: Rechts (rem) — (Steuert den inneren Abstand nach rechts)
PADDING: Unten (rem) — (Steuert den inneren Abstand nach unten)
PADDING: Links (rem) — (Steuert den inneren Abstand nach links)
Ein kurzes Beispiel zur Funktionsweise:
Stellst du den Schieber auf -100 (Standard), springt die Seite beim Klicken auf Seite 2 so weit hoch, dass über dem Feed noch 100 Pixel Platz frei bleiben (gut, damit der Feed nicht direkt unter die klebrige Menüleiste knallt).
Stellst du ihn auf 0, springt der Browser exakt bündig an die Kante des Feeds.
Stellst du ihn auf -200, bleibt noch mehr Platz nach oben frei.
wenn schon denn schon Tommy
- Tommy Herrmann
- Site Admin

- Beiträge: 8564
- Registriert: So 6. Dez 2020, 07:37
- Wohnort: Berlin
- Kontaktdaten:
Re: Gästebuch Block
Du musst den Block unter einem Header-Block einbauen, nicht ganz oben.
Im Original sprang der Seitenwechsel irgendwo in die Beiträge, aber eben nicht nach oben.
Im Original sprang der Seitenwechsel irgendwo in die Beiträge, aber eben nicht nach oben.
Wer ist online?
Mitglieder in diesem Forum: Dieter53 und 2 Gäste
