|  |  |  | @ -39,9 +39,7 @@ | 
		
	
		
			
				|  |  |  |  |      (spec/explain-data spec-key field-value))))) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | (defn field-valid?[value spec-key req] | 
		
	
		
			
				|  |  |  |  |   (or (or (and (contains? req :form-params) | 
		
	
		
			
				|  |  |  |  |                (empty? (:form-params req))) | 
		
	
		
			
				|  |  |  |  |           (empty? req)) | 
		
	
		
			
				|  |  |  |  |   (or (empty? (:form-params req)) | 
		
	
		
			
				|  |  |  |  |       (spec/valid? spec-key value))) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | (defn field | 
		
	
	
		
			
				
					|  |  |  | @ -109,38 +107,40 @@ | 
		
	
		
			
				|  |  |  |  |    true | 
		
	
		
			
				|  |  |  |  |    (:params req))) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | (defn render-input [id {:keys [label required spec]} values] | 
		
	
		
			
				|  |  |  |  |   (let [value (id values)] | 
		
	
		
			
				|  |  |  |  |     (list (when-not (field-valid? value spec values) | 
		
	
		
			
				|  |  |  |  |             (spec-to-errmsg label spec value)) | 
		
	
		
			
				|  |  |  |  |           (hform/label id label) | 
		
	
		
			
				|  |  |  |  |           (hform/text-field {:required (when required "required")} | 
		
	
		
			
				|  |  |  |  |                             id | 
		
	
		
			
				|  |  |  |  |                             value)))) | 
		
	
		
			
				|  |  |  |  | (defn render-input [id {:keys [label required spec]} value req-value validate?] | 
		
	
		
			
				|  |  |  |  |   (list | 
		
	
		
			
				|  |  |  |  |    (when (and validate? (not (spec/valid? spec req-value))) | 
		
	
		
			
				|  |  |  |  |      (spec-to-errmsg label spec req-value)) | 
		
	
		
			
				|  |  |  |  |    (hform/label id label) | 
		
	
		
			
				|  |  |  |  |    (hform/text-field {:required (when required "required")} | 
		
	
		
			
				|  |  |  |  |                      id | 
		
	
		
			
				|  |  |  |  |                      (if validate? req-value value)))) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | (defn render-checkbox [id {:keys [label spec]} values] | 
		
	
		
			
				|  |  |  |  |   (let [value (id values)] | 
		
	
		
			
				|  |  |  |  |     (list | 
		
	
		
			
				|  |  |  |  |      (when-not (field-valid? value spec values) | 
		
	
		
			
				|  |  |  |  |        (spec-to-errmsg label spec value)) | 
		
	
		
			
				|  |  |  |  |      (hform/label id label) | 
		
	
		
			
				|  |  |  |  |      (hform/check-box id (some? value) value)))) | 
		
	
		
			
				|  |  |  |  | (defn render-checkbox [id {:keys [label spec]} value req-value validate?] | 
		
	
		
			
				|  |  |  |  |   (list | 
		
	
		
			
				|  |  |  |  |    (when (and validate? (not (spec/valid? spec req-value))) | 
		
	
		
			
				|  |  |  |  |      (spec-to-errmsg label spec value)) | 
		
	
		
			
				|  |  |  |  |    (hform/label id label) | 
		
	
		
			
				|  |  |  |  |    (hform/check-box id | 
		
	
		
			
				|  |  |  |  |                     (and (some? value) (not= 0 value)) | 
		
	
		
			
				|  |  |  |  |                     (if validate? req-value value)))) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | (defn render-textarea [id {:keys [label spec]} values] | 
		
	
		
			
				|  |  |  |  |   (let [value (id values)] | 
		
	
		
			
				|  |  |  |  |     (list | 
		
	
		
			
				|  |  |  |  |      (when-not (field-valid? value spec values) | 
		
	
		
			
				|  |  |  |  |        (spec-to-errmsg label spec value)) | 
		
	
		
			
				|  |  |  |  |      (hform/label id label) | 
		
	
		
			
				|  |  |  |  |      (hform/text-area id value)))) | 
		
	
		
			
				|  |  |  |  | (defn render-textarea [id {:keys [label spec]} value req-value validate?] | 
		
	
		
			
				|  |  |  |  |   (list | 
		
	
		
			
				|  |  |  |  |    (when (and validate? (not (spec/valid? spec req-value))) | 
		
	
		
			
				|  |  |  |  |      (spec-to-errmsg label spec value)) | 
		
	
		
			
				|  |  |  |  |    (hform/label id label) | 
		
	
		
			
				|  |  |  |  |    (hform/text-area id | 
		
	
		
			
				|  |  |  |  |                     (if validate? req-value value)))) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | (defn render-select [id {:keys [label spec options]} values] | 
		
	
		
			
				|  |  |  |  |   (let [value (id values)] | 
		
	
		
			
				|  |  |  |  |     (list | 
		
	
		
			
				|  |  |  |  |      (when-not (field-valid? value spec values) | 
		
	
		
			
				|  |  |  |  |        (spec-to-errmsg label spec value)) | 
		
	
		
			
				|  |  |  |  |      (hform/label id label) | 
		
	
		
			
				|  |  |  |  |      (hform/drop-down id options value)))) | 
		
	
		
			
				|  |  |  |  | (defn render-select [id {:keys [label spec options]} value req-value validate?] | 
		
	
		
			
				|  |  |  |  |   (list | 
		
	
		
			
				|  |  |  |  |    (when (and validate? (not (spec/valid? spec req-value))) | 
		
	
		
			
				|  |  |  |  |      (spec-to-errmsg label spec value)) | 
		
	
		
			
				|  |  |  |  |    (hform/label id label) | 
		
	
		
			
				|  |  |  |  |    (hform/drop-down id | 
		
	
		
			
				|  |  |  |  |                     options | 
		
	
		
			
				|  |  |  |  |                     (if validate? req-value value)))) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | (def render-mapping | 
		
	
		
			
				|  |  |  |  |   {:input render-input | 
		
	
	
		
			
				
					|  |  |  | @ -148,29 +148,25 @@ | 
		
	
		
			
				|  |  |  |  |    :textarea render-textarea | 
		
	
		
			
				|  |  |  |  |    :select render-select}) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | (defn cleaned-values | 
		
	
		
			
				|  |  |  |  |   "Removes keys from value map that are not configured in the form" | 
		
	
		
			
				|  |  |  |  |   [form-def values] | 
		
	
		
			
				|  |  |  |  |   (reduce-kv | 
		
	
		
			
				|  |  |  |  |    (fn [agg value-key value] | 
		
	
		
			
				|  |  |  |  |      (if (contains? (:fields form-def) value-key) | 
		
	
		
			
				|  |  |  |  |        (assoc agg value-key value) | 
		
	
		
			
				|  |  |  |  |        agg)) | 
		
	
		
			
				|  |  |  |  |    {} | 
		
	
		
			
				|  |  |  |  |    values)) | 
		
	
		
			
				|  |  |  |  | 
 | 
		
	
		
			
				|  |  |  |  | (defn render-form [form-def values] | 
		
	
		
			
				|  |  |  |  | (defn render-form [form-def values req] | 
		
	
		
			
				|  |  |  |  |   {:pre [(spec/valid? ::form form-def)]} | 
		
	
		
			
				|  |  |  |  |   (let [cleaned-values (cleaned-values form-def values)] | 
		
	
		
			
				|  |  |  |  |   (let [form-hash (str (hash [form-def values])) | 
		
	
		
			
				|  |  |  |  |         submitted-hash (get-in req [:params :__form-hash]) | 
		
	
		
			
				|  |  |  |  |         validate? (= form-hash submitted-hash)] | 
		
	
		
			
				|  |  |  |  |     (conj (map | 
		
	
		
			
				|  |  |  |  |            (fn [[field-id field-def]] | 
		
	
		
			
				|  |  |  |  |              (let [{:keys [options widget]} field-def | 
		
	
		
			
				|  |  |  |  |                    value (field-id values) | 
		
	
		
			
				|  |  |  |  |                    req-value (get-in req [:params field-id]) | 
		
	
		
			
				|  |  |  |  |                    widget (cond (some? widget) widget | 
		
	
		
			
				|  |  |  |  |                                 (some? options) :select | 
		
	
		
			
				|  |  |  |  |                                 :else :input) | 
		
	
		
			
				|  |  |  |  |                    widget-renderer (widget render-mapping)] | 
		
	
		
			
				|  |  |  |  |                (widget-renderer field-id | 
		
	
		
			
				|  |  |  |  |                                 field-def | 
		
	
		
			
				|  |  |  |  |                                 cleaned-values))) | 
		
	
		
			
				|  |  |  |  |                                 value | 
		
	
		
			
				|  |  |  |  |                                 req-value | 
		
	
		
			
				|  |  |  |  |                                 validate?))) | 
		
	
		
			
				|  |  |  |  |            (:fields form-def)) | 
		
	
		
			
				|  |  |  |  |           (hform/hidden-field "__form-hash" form-hash) | 
		
	
		
			
				|  |  |  |  |           (anti-forgery-field)))) | 
		
	
	
		
			
				
					|  |  |  | 
 |