blob: 9da2ef94ab9cfc4bec1041bbe12605e2a9723b3e (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
|
;; Copyright (c) James Reeves. All rights reserved.
;; The use and distribution terms for this software are covered by the Eclipse
;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which
;; can be found in the file epl-v10.html at the root of this distribution. By
;; using this software in any fashion, you are agreeing to be bound by the
;; terms of this license. You must not remove this notice, or any other, from
;; this software.
(ns compojure.html.form-helpers
"Functions for generating HTML forms and input fields."
(:use compojure.html.gen
compojure.control
compojure.str-utils
clojure.contrib.def
clojure.contrib.seq-utils))
;; Global parameters for easy default values
(defvar *params* {}
"Parameter map var that form input field functions use to populate their
default values.")
(defmacro with-params
"Bind a map of params to *params*."
[params & body]
`(binding [*params* ~params]
~@body))
;; Form input fields
(defn- input-field
"Creates a form input field."
[type name value]
(let [name (str* name)
attrs {:type type, :name name, :id name}
attrs (if value
(assoc attrs :value value)
attrs)]
[:input attrs]))
(defn hidden-field
"Creates a hidden input field."
([name] (hidden-field name (*params* name)))
([name value] (input-field "hidden" name value)))
(defn text-field
"Creates a text input field."
([name] (text-field name (*params* name)))
([name value] (input-field "text" name value)))
(defn password-field
"Creates a password input field."
[name]
(input-field "password" name ""))
(defn check-box
"Creates a check box."
([name]
(check-box name (*params* name)))
([name checked?]
(check-box name checked? "true"))
([name checked? value]
[:input {:type "checkbox"
:name (str* name)
:id (str* name)
:value value
:checked checked?}]))
(defn radio-button
"Creates a radio button."
([group]
(radio-button group (*params* group)))
([group checked?]
(radio-button group checked? "true"))
([group checked? value]
[:input {:type "radio"
:name (str* group)
:id (str* group "_" value)
:value value
:checked checked?}]))
(defn select-options
"Turn a collection into a set of option tags."
([options]
(select-options options nil))
([options selected]
(let [select (fn [opt attrs]
(if (and selected (= opt (str* selected)))
(merge attrs {:selected "selected"})
attrs))]
(domap [opt options]
(if (vector? opt)
(let [text (opt 0)
value (str* (opt 1))]
[:option (select value {:value value}) text])
[:option (select opt {}) opt])))))
(defn drop-down
"Creates a drop-down box using the 'select' tag."
([name options]
(drop-down name options (*params* name)))
([name options selected]
[:select {:name (str* name) :id (str* name)}
(select-options options selected)]))
(defn text-area
"Creates a text area element."
([name]
(text-area name (*params* name)))
([name value]
[:textarea {:name (str* name) :id (str* name)} value]))
(defn file-upload
"Creates a file upload input."
[name]
[:input {:type "file", :name (str* name), :id (str* name)}])
(defn label
"Create a label for an input field with the supplied name."
[name text]
[:label {:for (str* name)} text])
(defn submit-button
"Create a submit button."
[text]
[:input {:type "submit" :value text}])
(defn reset-button
"Create a form reset button."
[text]
[:input {:type "reset" :value text}])
(defn form-to
"Create a form that points to a particular method and route.
e.g. (form-to [:put \"/post\"]
...)"
[[method action] & body]
(let [method-str (upcase-name method)]
(into []
(concat
(if (includes? [:get :post] method)
[:form {:method method-str :action action}]
[:form {:method "POST" :action action}
(hidden-field "_method" method-str)])
body))))
(decorate-with optional-attrs
hidden-field
text-field
check-box
drop-down
text-area
file-upload
label
submit-button
reset-button
form-to)
(defmacro decorate-fields
"Wrap all input field functions in a decorator."
[decorator & body]
`(decorate-bind ~decorator
[text-field
password-field
check-box
drop-down
text-area
file-upload]
(list ~@body)))
|