4
votes

I have a form, using hiccup framework. It looks like this:

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

  ...

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

How do I know which submit button got pressed, without using jQuery/javascript?

I looked at the Hiccup's documentation for request. But, the request element does not have a lot of documentation.

2

2 Answers

5
votes

A complete example looks like:

(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"))))

Note that using the same name for both submit buttons allows you to do a simple lookup of the "submit" key in the result map.

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

When opening the following page:

 http://localhost:3000/form-in

And filling the form, the result out of the POST route is:

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

By the way, I found an old useful post about the way the request map is structured in Compojure, so it makes it easier to destructure it in the Clojure code.

2
votes

submit-button generate HTML <input type="text" ...> element. You can add "name" and "value" attributes to them:

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

and find it out in your server side code. In your case lib-noir is used. But recent version of lib-noir no longer provide utils for destructuring requests and encourage people to utilize other libraries like Compojure or bare Ring.

Basically you need: - ensure your server side app use wrap-params Ring middleware - in case the above "Save" button is click, your server side handler for [:post "/add-data"] should receive a hash map like this:

{: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
               ...
               }
 ...}

I hope you can figure out yourself how to find the value you need in such a map.

More in-depth reading:

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