Khi nói đến xây dựng form trên web, hầu hết lập trình viên sẽ nghĩ ngay đến việc sử dụng JavaScript — đôi khi là kết hợp với các framework như React hoặc Vue. Tuy nhiên, trong bài viết này, bạn sẽ thấy cách để tạo một smart form chỉ với HTML thuần và một chút hỗ trợ từ HMPL, mà hoàn toàn không cần viết JavaScript tùy chỉnh.
Cấu trúc dự án
Dự án mẫu có cấu trúc thư mục như sau:
📁 smart-form
├── 📁 components
│ └── 📁 Register
│ └── index.html
├── 📁 src
│ ├── global.css
│ ├── global.js
│ └── index.html
├── app.js
└── routes └── post.js
Chúng ta sử dụng:
Server: Node.js
+ Express
để xử lý route và phản hồi
Frontend: HTML
, CSS
thuần và HMPL
để render component, trigger request động mà không dùng JavaScript truyền thống
Css cho Form
Hãy bắt đầu với giao diện đơn giản
body { font-family: Arial, sans-serif; background: #f4f4f4; padding: 50px;
} form { background: white; padding: 20px; border-radius: 6px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); max-width: 400px; margin: auto;
} .form-example { margin-bottom: 15px;
} label { display: block; margin-bottom: 5px;
} input[type="text"],
input[type="password"] { width: 100%; padding: 8px; box-sizing: border-box;
} input[type="submit"] { background-color: #649606; color: white; border-radius: 5px; padding: 10px 15px; cursor: pointer;
}
Thiết lập API
Tạo một Express server
với route POST
để submit Form
const express = require("express");
const path = require("path");
const cors = require("cors"); const app = express();
const PORT = 8000; app.use(cors());
app.use(express.urlencoded({ extended: true }));
app.use(express.json()); app.use(express.static(path.join(__dirname, "src"))); const postRoutes = require("./routes/post");
app.use("/api", postRoutes); app.get("/", (_, res) => { res.sendFile(path.join(__dirname, "src/index.html"));
}); app.listen(PORT, () => { console.log(`Server running on http://localhost:${PORT}`);
});
const express = require("express");
const router = express.Router(); router.post("/register", (req, res) => { const { login, password } = req.body; if (!login || !password) { return res.status(400).send("<p style='color: red;'>Missing fields!</p>"); } console.log("User Registered:", login); res.send(`<p style='color: green;'>Welcome, ${login}!</p>`);
}); module.exports = router;
Tạo form động không dùng JavaScript
Form này sẽ gửi dữ liệu bằng cách sử dụng request block của HMPL, mà không cần viết bất kỳ sự kiện JavaScript nào.
<div> <form onsubmit="function prevent(e){e.preventDefault();};return prevent(event);" id="form"> <div class="form-example"> <label for="login">Login:</label> <input type="text" name="login" id="login" required /> <br/> <label for="password">Password:</label> <input type="password" name="password" id="password" required /> </div> <div class="form-example"> <input type="submit" value="Register!" /> </div> </form> <p> {{#request src="/api/register" after="submit:#form" repeat=false indicators=[ { trigger: "pending", content: "<p>Loading...</p>" } ] }} {{/request}} </p>
</div>
Phân tích
onsubmit
: Ngăn reload trang khi submit#request
: Cấu trúc đặc biệt từ HMPL để thực hiện AJAX callafter="submit:#form"
: Trigger gọi API sau sự kiện submitindicators
: Hiển thị trạng thái phản hồi (pending/loading)
📌 Không cần fetch
, không cần async/await
, không cần viết JavaScript thêm! Tất cả đều qua cú pháp của HMPL.
Sử dụng Component với HMPL
Sử dụng component trên bằng HMPL
<!DOCTYPE html>
<html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"/> <title>Smart Form</title> <link rel="stylesheet" href="global.css" /> </head> <body> <div id="wrapper"></div> <script src="https://unpkg.com/json5/dist/index.min.js"></script> <script src="https://unpkg.com/dompurify/dist/purify.min.js"></script> <script src="https://unpkg.com/hmpl-js/dist/hmpl.min.js"></script> <script> import { compile } from "hmpl-js"; const templateFn = compile(` {{#request src="/components/Register/index.html"}}{{/request}} `); const obj = templateFn(); document.getElementById("wrapper").append(obj.response); </script> </body>
</html>
Có thể tách logic này thành một tệp global.js
riêng nếu muốn đảm bảo tính module.
Kết quả
- Một Form đơn giản
- Gửi dữ liệu bất đồng bộ chỉ với HTML + HMPL
- Validate và trả về result — tất cả không cần logic JavaScript tùy chỉnh
Tại sao chọn cách này?
- Không cần framework JavaScript: Không React, không Angular.
- Bạn mô tả điều gì sẽ xảy ra, không cần cách thực hiện.
- Đơn giản và có thể mở rộng: Phù hợp cho landing pages, admin tools và MVPs.
- Bạn thậm chí có thể mở rộng mô hình này để hỗ trợ multi-step forms, loaders, xử lý lỗi hoặc tự động lưu theo khoảng thời gian định kỳ.
Kết luận
HMPL là một giải pháp đơn giản nhưng mạnh mẽ cho những ai muốn xây dựng ứng dụng web có khả năng tương tác mà không cần phụ thuộc vào JavaScript. Đặc biệt, với những dự án yêu cầu tối ưu hóa hiệu năng, hoặc khi bạn muốn hạn chế client-side scripting, HMPL là một lựa chọn rất đáng cân nhắc.