Skip to content

Instantly share code, notes, and snippets.

@niquola
Last active August 29, 2015 14:17
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save niquola/e8d7e35c187b645e32e2 to your computer and use it in GitHub Desktop.
Save niquola/e8d7e35c187b645e32e2 to your computer and use it in GitHub Desktop.

Form builder (ala rails & simple form)

I'm going to open a cycle of small gist-posts - clojure one-filers - with implementations in clojure some ideas & API's from another realms, which occupy there usually a whole library, but in clojure could be just curled into project.

In this example we implement half of Rails form builder and simple_form library - nifty helpers for html forms:

;; 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"]))
@razum2um
Copy link

на #49 :form же не нужен, он есть на #28

@niquola
Copy link
Author

niquola commented Mar 31, 2015

ага спасиб :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment