|
|
@ -1,6 +1,7 @@
|
|
|
|
(ns formulare.core
|
|
|
|
(ns formulare.core
|
|
|
|
(:require [formulare.theme :as theme]
|
|
|
|
(:require [formulare.theme :as theme]
|
|
|
|
[clojure.spec.alpha :as spec]
|
|
|
|
[clojure.spec.alpha :as spec]
|
|
|
|
|
|
|
|
[clojure.spec.test.alpha :as spectest]
|
|
|
|
[hiccup.form :as hform]
|
|
|
|
[hiccup.form :as hform]
|
|
|
|
[hiccup.core :as hcore]
|
|
|
|
[hiccup.core :as hcore]
|
|
|
|
[ring.util.anti-forgery :refer [anti-forgery-field]]))
|
|
|
|
[ring.util.anti-forgery :refer [anti-forgery-field]]))
|
|
|
@ -34,8 +35,6 @@
|
|
|
|
:opt-un [::form-specs]))
|
|
|
|
:opt-un [::form-specs]))
|
|
|
|
|
|
|
|
|
|
|
|
(defn form-data [form-def req]
|
|
|
|
(defn form-data [form-def req]
|
|
|
|
(when-not (spec/valid? ::form form-def)
|
|
|
|
|
|
|
|
(throw (ex-info "Form def fails spec" (spec/explain-data ::form form-def))))
|
|
|
|
|
|
|
|
(reduce (fn [coll [id field]]
|
|
|
|
(reduce (fn [coll [id field]]
|
|
|
|
(let [value (get-in req [:params id])]
|
|
|
|
(let [value (get-in req [:params id])]
|
|
|
|
(assoc coll
|
|
|
|
(assoc coll
|
|
|
@ -46,6 +45,11 @@
|
|
|
|
{}
|
|
|
|
{}
|
|
|
|
(:fields form-def)))
|
|
|
|
(:fields form-def)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(spec/fdef form-data
|
|
|
|
|
|
|
|
:args (spec/cat :form-def ::form :req map?)
|
|
|
|
|
|
|
|
:ret map?)
|
|
|
|
|
|
|
|
(spectest/instrument `form-data)
|
|
|
|
|
|
|
|
|
|
|
|
(defn form-specs-valid? [form-def req]
|
|
|
|
(defn form-specs-valid? [form-def req]
|
|
|
|
(reduce (fn [valid? form-spec]
|
|
|
|
(reduce (fn [valid? form-spec]
|
|
|
|
(if (spec/valid? form-spec req)
|
|
|
|
(if (spec/valid? form-spec req)
|
|
|
@ -66,11 +70,15 @@
|
|
|
|
(:fields form-def)))
|
|
|
|
(:fields form-def)))
|
|
|
|
|
|
|
|
|
|
|
|
(defn valid? [form-def req]
|
|
|
|
(defn valid? [form-def req]
|
|
|
|
{:pre [(spec/assert ::form form-def)]}
|
|
|
|
|
|
|
|
(let [data (form-data form-def req)]
|
|
|
|
(let [data (form-data form-def req)]
|
|
|
|
(and (field-specs-valid? form-def req)
|
|
|
|
(and (field-specs-valid? form-def req)
|
|
|
|
(form-specs-valid? form-def req))))
|
|
|
|
(form-specs-valid? form-def req))))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(spec/fdef valid?
|
|
|
|
|
|
|
|
:args (spec/cat :form-def ::form :req map?)
|
|
|
|
|
|
|
|
:ret map?)
|
|
|
|
|
|
|
|
(spectest/instrument `valid?)
|
|
|
|
|
|
|
|
|
|
|
|
(def ^:dynamic *row-theme* theme/row)
|
|
|
|
(def ^:dynamic *row-theme* theme/row)
|
|
|
|
(def ^:dynamic *widget-error-theme* theme/widget-error)
|
|
|
|
(def ^:dynamic *widget-error-theme* theme/widget-error)
|
|
|
|
(def ^:dynamic *form-error-theme* theme/form-error)
|
|
|
|
(def ^:dynamic *form-error-theme* theme/form-error)
|
|
|
@ -108,9 +116,6 @@
|
|
|
|
(get-in req [:params :__form-hash])))
|
|
|
|
(get-in req [:params :__form-hash])))
|
|
|
|
|
|
|
|
|
|
|
|
(defn render-widgets [form-def values req]
|
|
|
|
(defn render-widgets [form-def values req]
|
|
|
|
(when-not (spec/valid? ::form form-def)
|
|
|
|
|
|
|
|
(throw (ex-info "Form def fails spec"
|
|
|
|
|
|
|
|
(spec/explain-data ::form form-def))))
|
|
|
|
|
|
|
|
(let [validate? (validate? form-def values req)
|
|
|
|
(let [validate? (validate? form-def values req)
|
|
|
|
form-errors (when (and validate?
|
|
|
|
form-errors (when (and validate?
|
|
|
|
(not (form-specs-valid? form-def
|
|
|
|
(not (form-specs-valid? form-def
|
|
|
@ -129,3 +134,10 @@
|
|
|
|
[form-errors])
|
|
|
|
[form-errors])
|
|
|
|
all-widgets)
|
|
|
|
all-widgets)
|
|
|
|
all-widgets)))
|
|
|
|
all-widgets)))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(spec/fdef render-widgets
|
|
|
|
|
|
|
|
:args (spec/cat :form-def ::form
|
|
|
|
|
|
|
|
:values (spec/or :no-values nil?
|
|
|
|
|
|
|
|
:values map?))
|
|
|
|
|
|
|
|
:ret map?)
|
|
|
|
|
|
|
|
(spectest/instrument `render-widgets)
|
|
|
|