HTMX 实现用户注册时邮箱地址实时查询可用性

HTMX 实现用户注册时邮箱地址实时查询可用性

HTMX 实现用户注册时邮箱地址实时查询可用性

HTMX 能够通过属性很容易地控制键盘事件触发、定时触发 HTTP 请求的操作,只需要在 HTML 标签内简单配置几个属性值即可。在实现用户注册时邮箱地址实时查询可用性、搜索框实时显示搜索列表等用户场景中使用会变得很便捷。

htmx 完整项目源码

完整的 htmx 模态弹出窗口源码已经上传至 GitHub

使用到的 htmx 特性

htmx 属性

htmx API

htmx 事件

项目结构

完整项目总共4个文件,按 Flask 默认的目录结构搭建。

  • app.py
  • templates/index.html
  • templates/email_check.html
  • static/htmx2.0.4.min.js

服务端

服务端使用 flask 实现,定义了3个路由,一个是首页:放置了一个用户注册的表单;第二是用来检查用户输入的邮箱地址是否已存在的链接;第三个是用户注册的链接。

服务端源码

app.py

from flask import Flask, render_template, request, jsonify

app = Flask(__name__)

# 模拟的已注册邮箱列表
REGISTERED_EMAILS = {"[email protected]", "[email protected]"}

@app.route('/')
def index():
    return render_template("index.html")

@app.route('/check_email')
def check_email():
    email = request.args.get("email", "")
    exists = email in REGISTERED_EMAILS
    return render_template("email_check.html", exists=exists)

@app.route('/register', methods=["POST"])
def register():
    email = request.form.get("email")
    password = request.form.get("password")

    if not email or not password:
        return "<div class='message error'>所有字段都是必填项</div>", 400

    if email in REGISTERED_EMAILS:
        return "<div class='message error'>邮箱已被注册</div>", 400

    # 模拟注册成功
    REGISTERED_EMAILS.add(email)
    return "<div class='message'>注册成功!欢迎你 🎉</div>"

if __name__ == '__main__':
    app.run(debug=True)

代码中的 REGISTERED_EMAILS 模拟了一个已经存在的 Email 列表,如果用户输入的 Email 已经存在于 REGISTERED_EMAILS 列表则视为 Email 已存在。

前端

前端主要是一个用户注册的表单,在 Email 的输入框会有一个 KeyUp Changed 的事件,延时500毫秒向后台发起 Email 是否存在的查询。后台会把查询结果返回并显示到输入框的下方。

用户点击注册按钮时,后台也会重新查询 Email 是否存在,并模拟注册及返回注册结果提示。如果 Email 已存在时,会返回 400 Bad Rquest ,所以需要在前端拦截 responseError 事件并作出处理。

前端源码

index.html

<body>
  <div class="container">
    <h1>注册账号</h1>
    <form hx-post="/register" hx-target="#form-messages" hx-swap="innerHTML"  hx-on:htmx:response-error="bad_request(event);">
      <div>
          <label for="email">邮箱</label>
          <input type="email" name="email" id="email"
          hx-get="/check_email"
          hx-trigger="keyup changed delay:500ms"
          hx-target="#email-status"
          hx-swap="innerHTML"
          >
          <div id="email-status" style="margin-bottom: 30px;"></div>
      </div>

      <div>
          <label for="password">密码</label>
          <input type="password" name="password" id="password">
      </div>

      <button type="submit">注册</button>
    </form>

    <div id="form-messages"></div>
  </div>
</body>
<script>
  // 服务器返回400时触发 hx-on:htmx:responseError
  function bad_request(event) {
    htmx.swap("#form-messages", event.detail.xhr.response, {swapStyle: "innerHTML"});
  }
</script>

email_check.html

{% if exists %}
  <span class="message error">这个邮箱已被注册</span>
{% elif request.args.get('email') %}
  <span class="message">邮箱可用</span>
{% endif %}

email_check.html 里面的内容是一些 html 片段,主要是根据后台查询 Email 是否存在的结果返回不同的提示,也可以省略这个文件,直接在 Python 代码里面返回相应的文本。

运行项目代码,在浏览器中打开 localhost:5000 就能看到用户注册的表单页面,在邮箱输入 [email protected][email protected] 就会发现页面提示邮箱已被注册,如果输入除上述的两个邮箱以外的合法邮箱地址则会提示邮箱可用。

htmx check email