|
;; hiccup is used as template |
|
|
|
(defn uuid [] (str (java.util.UUID/randomUUID))) |
|
|
|
(defn mk-input [{scope :scope i18n :i18n data :data errors :errors}] |
|
(fn [name-kw type-kw & [{label :label :as i-opts}]] |
|
(let [i-id (uuid) |
|
i-name (if scope |
|
(str scope "[" (name name-kw) "]") |
|
(name name-kw)) |
|
i-type (name type-kw) |
|
i18n (or i18n str) |
|
label (or label (i18n name-kw)) |
|
i-value (get data name-kw) |
|
errs (get errors name-kw) |
|
i-opts (merge (or i-opts {}) |
|
{:id i-id :name i-name :value i-value})] |
|
[:div.form-group {:class (when errs "has-error")} |
|
[:label.control-label {:for i-id} label] |
|
(cond |
|
(= type-kw :textarea) [:textarea.form-control i-opts i-value] |
|
:else [:input.form-control i-opts]) |
|
(when errs [:span.help-block (cs/join ", " errs)])]))) |
|
|
|
(defmacro form-for [inp opts & cnt] |
|
`(let [input# (mk-input ~opts)] |
|
(let [~(symbol inp) input#] |
|
[:form ~opts ~@cnt]))) |
|
|
|
(defn form-actions [& actions] |
|
(into |
|
[:div.form-actions {:style "border-top: 1px solid #ddd; padding-top: 10px;"}] |
|
(interpose " " actions))) |
|
|
|
(defn form-errors [errors {i18n :i18n}] |
|
(when errors |
|
[:div.alert.alert-danger |
|
[:ul |
|
(for [[k errs] errors] |
|
[:li [:b (i18n k)] " " (cs/join ", " errs)])]])) |
|
|
|
(def strings {:name "Name"}) |
|
|
|
(defn i18n [k] |
|
(or (get strings k) (name k))) |
|
|
|
(form-for |
|
input {:data data :errors errors :method "POST" :action "" :i18n i18n :scope "user"} |
|
[:h3 "New entity"] |
|
(form-errors errors {:i18n i18n}) |
|
(input :name :text {:required true}) |
|
(input :email :email) |
|
(input :details :textarea) |
|
(form-actions |
|
[:button.btn.btn-success "Save"] |
|
[:a {:href "#"} "Cancel"])) |
на #49
:form
же не нужен, он есть на #28