blob: 35e8e3225c1e361b23c3d268127316d688805033 (
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
|
;; 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.validation
"Functions for validating form parameters."
(:use compojure.control
compojure.html.form-helpers
compojure.html.page-helpers
clojure.contrib.def))
(defvar *errors* {}
"Var containing validation errors.")
(load "validation/predicates")
(defn validate
"Validate a single parameter, or group of parameters, using a predicate. If
the predicate fails, a validation error is returned. For a single parameter,
use the following form:
(validate params name pred message)
This will use the value of (pred (params name)) to determine if the parameter
is valid. For multiple parameters:
(validate params pred message)
This will use the value of (pred params) to determine validity."
([params pred message]
(if (pred params)
{}
{nil [message]}))
([params name pred message]
(if (pred (params name))
{}
{name [message]})))
(defn merge-errors
"Merge a set of validation errors into a single hash map."
[& results]
(apply merge-with #(into [] (concat %1 %2)) results))
(defn validation
"Convinience function to perform a series of validations on a map of params.
Takes a set of params and a collection of argument vectors for the validate
function:
e.g. (validation params
[name pred message]
[pred message])
Is the same as:
(merge-errors
(validate params name pred message)
(validate params pred message))"
[params & validations]
(apply merge-errors
(map #(apply validate params %) validations)))
(defn validation-errors?
"True if there are errors in the var *errors*."
[]
(seq *errors*))
(defmacro with-validation
"Binds *errors* to (validation-fn *params*)."
[validation-fn & body]
`(binding [*errors* (~validation-fn *params*)]
~@body))
(defmacro with-validated-params
"Equivalent to (with-params params (with-validation validation-fn))."
[params validation-fn & body]
`(with-params ~params
(with-validation ~validation-fn
~@body)))
(defn error-summary
"Returns a summary of the errors on the form in HTML."
[]
(unordered-list (apply concat (vals *errors*))))
(defn error-class
"Decorator function that marks an input field with an error class if the
parameter has errors."
[func]
(fn [name & args]
(let [errors (*errors* name)
result (apply func name args)]
(if (seq errors)
[:div.error result]
result))))
|