(ns auto-ap.ssr.form-cursor (:require [auto-ap.ssr.utils :refer [path->name2]] [auto-ap.cursor :as cursor])) (def ^:dynamic *prefix* []) (def ^:dynamic *form-data*) (def ^:dynamic *form-errors*) (def ^:dynamic *prev-cursor* nil) (def ^:dynamic *current* nil) (defmacro start-form [form-data errors & rest] `(binding [*form-data* ~form-data *form-errors* (or ~errors {})] (binding [*current* (if (cursor/cursor? *form-data*) *form-data* (cursor/cursor *form-data*))] ~@rest))) (defmacro start-form-with-prefix [prefix form-data errors & rest] `(binding [*prefix* ~prefix] (start-form ~form-data ~errors ~@rest))) (defmacro with-cursor [cursor & rest] `(binding [*current* ~cursor] ~@rest)) (defmacro with-field [field & rest] `(with-cursor (get *current* ~field ) ~@rest)) (defmacro with-field-default [field default & rest] `(with-cursor (get *current* ~field ~default) ~@rest)) (defn field-name ([] (field-name *current*)) ([cursor] (apply path->name2 (into (or *prefix* []) (cursor/path cursor))))) (defn field-value ([] (field-value *current*)) ([cursor] @cursor)) (defn field-errors ([] (field-errors *current*)) ([cursor] (get-in *form-errors* (cursor/path cursor)))) (defn error? ([] (error? *current*)) ([cursor] (let [errors (get-in *form-errors* (cursor/path cursor))] (and (sequential? errors) (every? string? errors))))) (defn cursor-map ([f] (cursor-map *current* f)) ([cursor f] (when (field-value) (doall (for [n cursor] (with-cursor n (f n)))))))