guestbook test
This commit is contained in:
parent
d96cc85a8b
commit
08e35c4cf6
28
content/guestbook.html
Normal file
28
content/guestbook.html
Normal file
@ -0,0 +1,28 @@
|
||||
---
|
||||
title: "Guestbook"
|
||||
date: 2025-06-26T20:17:07-07:00
|
||||
---
|
||||
<script type="module" src="/guestbook.js"></script>
|
||||
|
||||
<form action="https://beta.webweav.ing/websites/26wxzbrx/guestbook/comments/create/remote" method="post">
|
||||
<div>
|
||||
<label for="authorname">Name</label>
|
||||
<input type="text" name="authorname" id="authorname" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="authoremail">Email (Optional) </label>
|
||||
<input type="text" name="authoremail" id="authoremail" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="authorsite">Site Url (Optional) </label>
|
||||
<input type="text" name="authorsite" id="authorsite" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="content">Comment</label>
|
||||
<textarea name="content" id="content"></textarea>
|
||||
</div>
|
||||
<div>
|
||||
<input type="submit" value="Submit" />
|
||||
</div>
|
||||
</form>
|
||||
<comment-list src="https://beta.webweav.ing/websites/26wxzbrx/guestbook/comments"></comment-list>
|
106
static/guestbook.js
Normal file
106
static/guestbook.js
Normal file
@ -0,0 +1,106 @@
|
||||
|
||||
class CommentList extends HTMLElement {
|
||||
static get observedAttributes() {
|
||||
return ['src'];
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.attachShadow({ mode: 'open' });
|
||||
this.comments = [];
|
||||
this.loading = false;
|
||||
this.error = null;
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (this.hasAttribute('src')) {
|
||||
this.fetchComments();
|
||||
}
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (name === 'src' && oldValue !== newValue) {
|
||||
this.fetchComments();
|
||||
}
|
||||
}
|
||||
|
||||
async fetchComments() {
|
||||
const src = this.getAttribute('src');
|
||||
if (!src) return;
|
||||
this.loading = true;
|
||||
this.error = null;
|
||||
this.render();
|
||||
|
||||
try {
|
||||
const response = await fetch(src);
|
||||
if (!response.ok) throw new Error(`HTTP error: ${response.status}`);
|
||||
const data = await response.json();
|
||||
this.comments = Array.isArray(data) ? data : [];
|
||||
this.loading = false;
|
||||
this.render();
|
||||
} catch (err) {
|
||||
this.error = err.message;
|
||||
this.loading = false;
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
formatDate(isoString) {
|
||||
if (!isoString) return '';
|
||||
const date = new Date(isoString);
|
||||
return date.toLocaleString();
|
||||
}
|
||||
|
||||
render() {
|
||||
this.shadowRoot.innerHTML = `
|
||||
<style>
|
||||
.comment-list {
|
||||
font-family: Arial, sans-serif;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 6px;
|
||||
padding: 1em;
|
||||
background: #fafafa;
|
||||
}
|
||||
.comment {
|
||||
border-bottom: 1px solid #eee;
|
||||
padding: 0.7em 0;
|
||||
}
|
||||
.comment:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
.author {
|
||||
font-weight: bold;
|
||||
margin-right: 1em;
|
||||
}
|
||||
.timestamp {
|
||||
color: #888;
|
||||
font-size: 0.85em;
|
||||
}
|
||||
.text {
|
||||
margin: 0.2em 0 0 0;
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<div class="comment-list">
|
||||
${this.loading
|
||||
? `<div>Loading comments...</div>`
|
||||
: this.error
|
||||
? `<div class="error">Error: ${this.error}</div>`
|
||||
: this.comments.length === 0
|
||||
? `<div>No comments found.</div>`
|
||||
: this.comments.map(comment => `
|
||||
<div class="comment">
|
||||
<span class="author">${comment.AuthorName || 'Unknown Author'}</span>
|
||||
<span class="timestamp">${this.formatDate(comment.Created)}</span>
|
||||
<div class="text">${comment.CommentText || ''}</div>
|
||||
</div>
|
||||
`).join('')
|
||||
}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define('comment-list', CommentList);
|
Loading…
x
Reference in New Issue
Block a user