Skip to content

Commit

Permalink
chore: added htmx example
Browse files Browse the repository at this point in the history
  • Loading branch information
mzeiher committed Nov 24, 2024
1 parent e409999 commit be708fb
Show file tree
Hide file tree
Showing 9 changed files with 1,152 additions and 0 deletions.
1 change: 1 addition & 0 deletions samples/todo-app/todo-htmx/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules
16 changes: 16 additions & 0 deletions samples/todo-app/todo-htmx/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM node:20-alpine AS builder

RUN mkdir -p /src
COPY . /src
WORKDIR /src
RUN npm i && npm run build

FROM node:20-alpine
RUN mkdir /app
COPY --from=builder /src/package.json /app/
COPY --from=builder /src/dist/* /app/

WORKDIR /app
RUN npm install --omit=dev

CMD ["node", "./index.js"]
45 changes: 45 additions & 0 deletions samples/todo-app/todo-htmx/dist/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import express, { urlencoded } from "express";
import { listTemplate, indexTemplate, todoTemplate } from "./templates.js";
import { randomUUID } from "crypto";
const todos = new Map();
const app = express();
// to automatically parse form-encoded data in post
app.use(urlencoded());
app.get("/", (req, res) => {
res.statusCode = 200;
res.header("content-type", "text/html");
res.end(indexTemplate());
});
app.post("/todos", (req, res) => {
const todoID = randomUUID();
todos.set(todoID, req.body.todo);
res.header("content-type", "x-html-fragment");
res.statusCode = 201;
res.end(todoTemplate(todoID, req.body.todo));
});
app.delete("/todos/:id", (req, res) => {
todos.delete(req.params["id"]);
res.statusCode = 202;
res.end();
});
app.get("/todos", (req, res) => {
res.header("content-type", "x-html-fragment");
res.statusCode = 200;
res.end(listTemplate(todos));
});
const server = app.listen(3000, "0.0.0.0", () => {
console.log("listening...");
});
process.on("SIGINT", () => {
console.log("got sigint");
server.closeAllConnections();
server.close((err) => {
if (err) {
console.error(err.message);
process.exit(1);
}
else {
process.exit(0);
}
});
});
37 changes: 37 additions & 0 deletions samples/todo-app/todo-htmx/dist/templates.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export function indexTemplate() {
return `<!DOCTYPE html>
<html>
<head>
<script src="https://unpkg.com/[email protected]"></script>
</head>
<body>
<h1>ToDo List</h1>
<div>
<form class="w-full max-w-sm mx-auto px-4 py-2" hx-post="/todos" hx-target="#list" hx-swap="beforeend">
<input type="text" placeholder="do something..." name="todo" required>
<button type="submit">
Add
</button>
</form>
</div>
<div hx-get="/todos" hx-trigger="load">
</div>
</body>
</html>
`;
}
export function todoTemplate(id, text) {
return `<li id="list-item-${id}">
<label>${text}</label><button hx-delete="/todos/${id}" hx-target="#list-item-${id}" hx-swap="delete swap:0.25s">Delete</button>
</li>
`;
}
export function listTemplate(todos) {
return `<ul id="list">
${Array.from(todos.entries())
.map(([id, text]) => {
return todoTemplate(id, text);
})
.join("\n")}
</ul>`;
}
Loading

0 comments on commit be708fb

Please sign in to comment.