Skip to content

Instantly share code, notes, and snippets.

@njj

njj/form.cljs Secret

Created April 3, 2019 20:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save njj/271054aead0c5644571460ad5c9dbe69 to your computer and use it in GitHub Desktop.
Save njj/271054aead0c5644571460ad5c9dbe69 to your computer and use it in GitHub Desktop.
;; Helpers
(defn generate-ident [{:keys [which-tab]}]
[which-tab :tab])
(def integer-fields #{:number_of_guests})
(def double-fields #{:subtotal_amount})
(defn generate-form-ident [{:keys [_id] :as props}]
[:booking/id _id])
(s/def ::number_of_guests (s/and string? #(seq (str/trim %))))
(s/def ::subtotal_amount (s/and string? #(seq (str/trim %))))
(def step->step-name
{1 "Details"
2 "Add-ons"
3 "Review"})
(defn is-active-step? [active step]
(= active (get step->step-name step)))
;; Main
(defn editable-input
([component field]
(let [form (prim/props component)
entity-ident (prim/get-ident component form)
id (str (first entity-ident) "-" (second entity-ident))
value (get form field "")
validity (fs/get-spec-validity form field)]
(dom/div
:.form-group
(dom/input
:.form-control
{:value value
:id id
:onBlur #(prim/transact! component `[(fs/mark-complete! {:field ~field
:entity-ident ~entity-ident})
:booking])
:onChange #(m/set-string! component field :event %)})))))
(defsc DetailsForm [this {:keys [_id number_of_guests subtotal_amount] :as props}]
{:query (fn [] ['*
:_id
:number_of_guests
:subtotal_amount
fs/form-config-join])
:ident (fn [] (generate-form-ident props))}
(dom/div
(dom/h4
(dom/strong "Date and Time"))
(dom/div
:.row
(dom/div
:.col-md-6
(dom/h4 "Current")
(dom/span
{:style {:color "#DBDBDB"}}))
(dom/div
:.col-md-6.text-right
(dom/h4 "New")))
(dom/hr {:style {:borderTopStyle "solid"}})
(dom/h4
(dom/strong "Attendees"))
(dom/div
:.row
(dom/div
:.col-md-6
(dom/h4 "Current")
(dom/span
{:style {:color "#DBDBDB"}}))
(dom/div
:.col-md-6.text-right
(dom/h4 "New")
(editable-input this :number_of_guests)))
(dom/hr {:style {:borderTopStyle "solid"}})
(dom/h4
(dom/strong "Estimated Price"))
(dom/div
:.row
(dom/div
:.col-md-6
(dom/h4 "Current")
(dom/span
{:style {:color "#DBDBDB"}}))
(dom/div
:.col-md-6.text-right
(dom/h4 "New")
(editable-input this :subtotal_amount)))))
(def ui-details-form (prim/factory DetailsForm))
(defsc AddonsForm [this props]
{:query (fn [] ['* fs/form-config-join])
:ident (fn [] (generate-form-ident props))}
(dom/div
"Addons"))
(def ui-addons-form (prim/factory AddonsForm))
(defsc ReviewForm [this props]
{:query (fn [] ['* fs/form-config-join])
:ident (fn [] (generate-form-ident props))}
(dom/div
"review"))
(def ui-review-form (prim/factory ReviewForm))
(defsc BookingForm [this props {:keys [step]}]
{:query [:_id
:number_of_guests
:subtotal_amount
fs/form-config-join]
:form-fields #{:_id
:number_of_guests
:subtotal_amount}
:ident (fn [] (generate-form-ident props))}
(dom/div
{:style {:padding "35px 27px"
:backgroundColor "#fff"
:border "1px solid #DBDBDB"}}
(case step
1 (ui-details-form props)
2 (ui-addons-form props)
3 (ui-review-form props))))
(def ui-booking-form (prim/factory BookingForm))
(defsc UpdateBooking [this {:keys [which-tab booking-id booking ui/step ui/max-step] :as props}]
{:query [[:web-env '_]
:which-tab
:booking-id
{:booking (prim/get-query BookingForm)}
:ui/step
:ui/max-step]
:ident (fn [] (generate-ident props))
:initial-state (fn [_] {:which-tab :update-booking
:ui/step 1
:ui/max-step 3
:booking (fs/add-form-config
BookingForm
(prim/get-initial-state
BookingForm {:_id nil
:number_of_guests nil
:subtotal_amount nil}))})}
(dom/div
:.container-fluid
(dom/ul
:.list-inline
{:style {:color "#C6C6C6"
:padding "42px 0"
:fontSize "20px"}}
(map-indexed (fn [i [k v]]
(dom/li {:style {:paddingRight 0} :key (str "step-" k)}
(if (is-active-step? v step)
(dom/span {:style {:color "#4B4B4B"}} v)
(dom/span v))
(if (not= (inc i) max-step) " >")))
step->step-name))
(case step
1 (dom/h3 "What do you want to change?")
2 (dom/h3 "Want to add any add-ons?")
3 (dom/h3 "Review the booking"))
(dom/div
:.row
(dom/div
:.col-md-12
(ui-booking-form (prim/computed booking {:step step}))))
(dom/hr {:style {:borderTopStyle "solid"}})
(dom/div
:.row
(dom/div
:.col-md-12
(if (> step 1)
(dom/button
:.btn.btn-primary
{:onClick #(prim/transact! this `[(update-booking/prev-step {:step ~step})])} "Previous"))
(if (not= step max-step)
(dom/button
:.btn.btn-primary.pull-right
{:onClick #(prim/transact! this `[(update-booking/next-step {:step ~step})])} (str "Continue to " (step->step-name step))))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment