(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-prefix [prefix & rest] `(binding [*prefix* (into (or *prefix* []) ~prefix)] ~@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] `(let [new-cursor# (get *current* ~field ~default) new-cursor2# (if (not (deref new-cursor#)) (do (cursor/transact! *current* (fn [c#] (assoc c# ~field ~default))) (get *current* ~field ~default)) new-cursor#)] (with-cursor new-cursor2# ~@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 ([] (println "CURRENT IS" *current*) (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 (seq (field-value)) (doall (for [n cursor] (with-cursor n (f n)))))))