Clojure (Hiccup):我如何知道在表单中按下了哪个提交按钮?

Clojure (Hiccup): How can I know which submit button got pressed in a form?

我有一个表格,使用打嗝框架。它看起来像这样:

(form-to {:enctype "multipart/form-data"}
  [:post "/add-data"]

  ...

  (submit-button {:class "btn"} "Save")
  (submit-button {:class "btn} "Clone"))

我如何知道按下了哪个提交按钮,没有 使用 jQuery/javascript?

我查看了 request 的 Hiccup 文档。但是,request 元素没有很多文档。

submit-button 生成 HTML <input type="text" ...> 元素。您可以为它们添加 "name" 和 "value" 属性:

(submit-button {:name "button" :value "save" :class "btn"} "Save")
(submit-button {:name "button" :value "clone" :class "btn"} "Clone")

并在您的服务器端代码中找到它。在您的情况下,使用了 lib-noir。但是最新版本的 lib-noir 不再提供用于解构请求的实用程序,并鼓励人们使用其他库,如 Compojure 或 bare Ring。

基本上你需要: - 确保您的服务器端应用程序使用 wrap-params Ring 中间件 - 如果单击上面的 "Save" 按钮,[:post "/add-data"] 的服务器端处理程序应该收到这样的哈希映射:

{:http-method :post
 :uri "/add-data"
 :form-params {"button" "save"
               ;; other form data as key/value pairs
               ;; where: key is input element's "name" attribute and value is input element's "value" attribute
               ...
               }
 ...}

我希望你能自己弄清楚如何在这样的地图中找到你需要的值。

更深入的阅读:

https://github.com/mmcgrana/ring/wiki/Parameters

一个完整的例子如下:

(ns myapp.routes.home
  (:use [hiccup core form])
  (:require [compojure.core :refer :all]))

(defn quick-form [& [name message error]]   
  (html
   (form-to {:enctype "multipart/form-data"}
    [:post "/form-out"]
   (text-field "Hello")
   (submit-button {:class "btn" :name "submit"} "Save")
   (submit-button {:class "btn" :name "submit"} "Clone"))))

请注意,为两个提交按钮使用相同的名称允许您在结果映射中对 "submit" 键进行简单查找。

(defroutes home-routes
 (GET "/form-in" [] (quick-form))
 (POST "/form-out" [:as request] (str (request :multipart-params))))

打开以下页面时:

 http://localhost:3000/form-in

并填写表格,POST 路线的结果是:

 {"submit" "Save", "Hello" "hello2"}

顺便说一下,我发现了一个关于 Compojure 中 request map is structured 方式的古老有用的 post,因此它可以更容易地在 Clojure 代码中解构它。