A simple clojurescript datepicker using rum, cljs-time and bulma for style
Last active
April 4, 2019 03:27
-
-
Save SneakyPeet/d872a6cf7def18141fdda249188c18af to your computer and use it in GitHub Desktop.
Clojurescript Date Selector
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns date-select.core | |
(:require [rum.core :as rum] | |
[cljs-time.core :as time])) | |
(defn initial-date | |
([] (let [selected (time/now)] | |
{:year (time/year selected) | |
:month (time/month selected) | |
:day (time/day selected)})) | |
([year] (initial-date year 1 1)) | |
([year month] (initial-date year month 1)) | |
([year month day] | |
(let [selected (time/date-time year month day)] | |
{:year (time/year selected) | |
:month (time/month selected) | |
:day (time/day selected)}))) | |
(rum/defcs DateCapture | |
"Params | |
start-year :int | |
end-year: int | |
label: string | |
change: fn taking a map as param. example {:year 2019 :month 2 :day 9} | |
initial-date: a map of {:year 2019 :month 2 :day 8} | use initial-date fn to construct" | |
< (rum/local nil ::year) (rum/local nil ::month) (rum/local nil ::day) | |
{:will-mount (fn [{*day ::day *month ::month *year ::year :as state}] | |
(let [now (time/now) | |
year (time/year now) | |
[start-year end-year _ change init-opts] (:rum/args state)] | |
(reset! *year (get init-opts :year year)) | |
(reset! *month (get init-opts :month (time/month now))) | |
(reset! *day (get init-opts :day (time/day now))) | |
(assoc state | |
::years (range start-year (inc end-year)) | |
::months (range 1 13) | |
::notify-change (fn [] (change {:year @*year :month @*month :day @*day}))))) | |
:did-update (fn [{notify-change ::notify-change :as state}] | |
(notify-change) | |
state)} | |
[{*day ::day *month ::month *year ::year :as state} start-year end-year label change] | |
(let [last-day-of-month (time/day (time/last-day-of-the-month @*year @*month)) | |
days (range 1 (inc last-day-of-month)) | |
on-change (fn [*k] | |
(fn [e] | |
(reset! *k (js/parseInt (.. e -target -value))) | |
(let [new-last-day-of-month (time/day (time/last-day-of-the-month @*year @*month))] | |
(when (< new-last-day-of-month @*day) | |
(reset! *day 1))))) | |
field (fn [range-coll *k] | |
[:div.field | |
[:div.control | |
[:div.select | |
[:select {:value @*k :on-change (on-change *k)} | |
(map-indexed (fn [i x] [:option {:key i} x]) range-coll)]]]])] | |
[:div.field.is-horizontal | |
[:div.field-label.is-normal | |
[:label.label label]] | |
[:div.field-body | |
(field (::years state) *year) | |
(field (::months state) *month) | |
(field days *day)]])) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(ns date-select.example | |
(:require [date-select.core :as ds])) | |
(def on-change prn) | |
(def label "My Date Selector") | |
(def initial-date (ds/initial-date 2018 1 1)) | |
(ds/DateCapture 2018 2020 label on-change initial-date) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment