-
Notifications
You must be signed in to change notification settings - Fork 3
Add custom start week to date picker #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
238d323
50f14af
b683844
0164482
4e14d27
d725ddc
103a110
2601efa
7a239e3
af69ba7
56e8157
7007be9
486c568
78c6a51
f5fa906
bbfa9d4
d33040f
5a60f77
351a66d
6812225
ee2a10c
791cd38
036298f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,14 +9,20 @@ | |
;; TODO translate | ||
(defonce days-short ["Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"]) | ||
|
||
(defn- build-previous-month-days [date] | ||
(let [current-month (time/date-time (time/year date) (time/month date)) | ||
weekday-current-month (time/day-of-week current-month) | ||
previous-month (time/minus current-month (time/months 1)) | ||
(defn- build-previous-month-days [date week-start] | ||
(let [current_month (time/month date) | ||
first-day-of-month (time/date-time (time/year date) current_month) | ||
weekday-current-month (time/day-of-week first-day-of-month) | ||
previous-month (time/minus first-day-of-month (time/months 1)) | ||
last-day (time/number-of-days-in-the-month previous-month) | ||
days-to-fill (range (inc (- last-day (dec weekday-current-month))) (inc last-day))] | ||
days-to-fill (range (inc | ||
(- last-day | ||
(case week-start | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. que problema le ves a esto? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. mm te referis al uso de case? o notas un bug en el calculo? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. si es por el case, no tiene valor por default lo que causario un error por el nil. No se lo agregue porque la funcion principal ya tiene un default con el :or. Pero podria agregarse para hacerlo mas robusto supongo There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. claro, si paso nil va a funcionar, pero si paso algo que no es :sunday o :monday va a reventar, yo esperaría o que defaultea a :monday que es el 90% de los casos, o que directamente te avise que la inicialización está mal y que los valores esperados son :monday :sunday (usar otra cosa ya es extremadamente raro) |
||
:monday (dec weekday-current-month) | ||
:sunday weekday-current-month))) | ||
(inc last-day))] | ||
(mapv (fn [d] {:day d | ||
:month (- 1 (time/month date)) | ||
:month (if (= current_month 1) 12 (dec current_month)) | ||
:year (time/year date) | ||
:belongs-to-month :previous}) days-to-fill))) | ||
|
||
|
@@ -55,8 +61,8 @@ | |
[...] | ||
[{:day 1 :month 3 :year 2014 :belongs-to-month :next}] ] | ||
" | ||
[date] | ||
(let [previous-days (build-previous-month-days date) | ||
[date week-start] | ||
(let [previous-days (build-previous-month-days date week-start) | ||
currrent-days (build-current-month-days date) | ||
next-days (build-next-month-days date) | ||
days (into [] (concat previous-days currrent-days next-days))] | ||
|
@@ -167,13 +173,13 @@ | |
om/IDisplayName | ||
(display-name [_] "DatepickerWeeks") | ||
om/IRenderState | ||
(render-state [this {:keys [date path onChange] :as state}] | ||
(render-state [this {:keys [date path onChange week-start] :as state}] | ||
(apply dom/tbody nil | ||
(map (fn [week] | ||
(apply dom/tr nil | ||
(map (fn [d] | ||
(om/build day-component app {:state {:day d :path path :date date :onChange onChange}})) week))) | ||
(build-weeks date)))))) | ||
(build-weeks date week-start)))))) | ||
|
||
(defn- year-component [app owner] | ||
(reify | ||
|
@@ -202,7 +208,7 @@ | |
om/IDisplayName | ||
(display-name [_] "DatepickerBody") | ||
om/IRenderState | ||
(render-state [this {:keys [path date onChange] :as state}] | ||
(render-state [this {:keys [path date onChange week-start] :as state}] | ||
(dom/div #js {:className "datepicker datepicker-days" :style #js {:display "block"}} | ||
(dom/table #js {:className "table-condensed"} | ||
(dom/thead nil | ||
|
@@ -223,10 +229,12 @@ | |
:onClick (fn [e] | ||
(om/set-state! owner :date (time/plus date (time/months 1))))} ">")) | ||
(apply dom/tr nil | ||
(om/build-all day-header days-short))) | ||
(om/build-all day-header (case week-start | ||
:monday days-short | ||
:sunday (concat [(last days-short)] (butlast days-short)))))) | ||
|
||
;; datepicker body | ||
(om/build weeks-component app {:state {:path path :date date :onChange onChange}})))))) | ||
(om/build weeks-component app {:state {:path path :date date :onChange onChange :week-start week-start}})))))) | ||
|
||
(defn datepicker | ||
"Datepicker public API | ||
|
@@ -237,13 +245,17 @@ | |
app >> the cursor | ||
path >> the internal path to update the cursor | ||
|
||
opts: | ||
- week-start: defines whether the week starts on Monday or Sunday. Dafults to Monday | ||
|
||
note: we assume today date if the cursor does not have a date | ||
" | ||
[app path {:keys [id hidden onChange] :or {hidden true}}] | ||
[app path {:keys [id hidden onChange week-start] :or {hidden true week-start :monday}}] | ||
(om/build body-component app {:state {:id id | ||
:hidden hidden | ||
:date (if (instance? js/Date (utils/om-get app [path])) | ||
(time/date-time (utils/om-get app [path])) | ||
(time/now)) | ||
:week-start week-start | ||
:path path | ||
:onChange onChange}})) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,8 +6,8 @@ | |
[cljs-time.format :as time-format] | ||
[cljs-time.coerce :as timec] | ||
[goog.object :as gobj] | ||
[pallet.thread-expr :as th])) | ||
|
||
[pallet.thread-expr :as th] | ||
[clojure.string :as str])) | ||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||
(def date-local-mask "00/00/0000") | ||
|
@@ -41,20 +41,20 @@ | |
(time-format/unparse (time-format/formatter fmt) dt))) | ||
|
||
(defn- convert-input | ||
[input-type value] | ||
[input-type value fmt] | ||
(condp = input-type | ||
"date" (try | ||
(string-from-date value (infer-date-format-pattern)) | ||
(string-from-date value (or fmt (infer-date-format-pattern))) | ||
(catch js/Error e | ||
;; assume empty string for unhandled values | ||
(str value))) | ||
value)) | ||
|
||
(defn- convert-output | ||
[output-type value] | ||
[output-type value fmt] | ||
(condp = output-type | ||
"date" (try | ||
(date-from-localstring value (infer-date-format-pattern)) | ||
(date-from-localstring value (or fmt (infer-date-format-pattern))) | ||
(catch js/Error e | ||
value)) | ||
"numeric" (let [f (js/parseFloat value)] | ||
|
@@ -132,11 +132,11 @@ | |
:mask)) | ||
|
||
(defn- update-target | ||
[target owner {:keys [input-format path onChange private-state] :as state} bInternal] | ||
[target owner {:keys [input-format date-format path onChange private-state] :as state} bInternal] | ||
(when (and target | ||
(not= 0 (:cbtimeout @private-state))) | ||
(let [dom-node (:dom-node @private-state) | ||
value (convert-output input-format (.-value dom-node))] | ||
value (convert-output input-format (.-value dom-node) date-format)] | ||
(do | ||
(.clearTimeout js/window (:cbtimeout @private-state)) | ||
(swap! private-state assoc :cbtimeout 0 :prev-value value) | ||
|
@@ -331,11 +331,11 @@ | |
(recur (next mv) (next cv) (conj r (if (re-matches m c) c \_)))) | ||
r))) | ||
(:mask-vector @private-state) | ||
(vec (convert-input (:input-format state) value))) | ||
(vec (convert-input (:input-format state) value (:date-format state)))) | ||
prev-value (:prev-value @private-state) | ||
new-value (apply str entered-values) | ||
dom-node (:dom-node @private-state)] | ||
(when (and (not= prev-value new-value) dom-node) | ||
(when (and value (not= prev-value new-value) dom-node) | ||
(do | ||
(swap! private-state assoc :entered-values entered-values | ||
:prev-value new-value) | ||
|
@@ -451,10 +451,12 @@ | |
:onPaste #(if (false? (handlepaste target owner state %)) | ||
(.preventDefault %) | ||
nil) | ||
:placeholder (:placeholder state) | ||
:placeholder (if (:date-format state) | ||
(str/upper-case (:date-format state)) | ||
(:placeholder state)) | ||
:disabled (:disabled state) | ||
;:typing-timeout (:typing-timeout state) | ||
:type (condp = (:input-format state) | ||
:type (case (:input-format state) | ||
"password" "password" | ||
"numeric" "number" | ||
"text") | ||
|
@@ -471,22 +473,25 @@ | |
(merge {:resize (name (:resize state))})))))))) | ||
|
||
(defn textinput | ||
[target path {:keys [input-class input-format align] :as opts | ||
"Opts: | ||
- date-format: only applied when input-format is \"date\". Should be one of the valid values, otherwise is ignored" | ||
[target path {:keys [input-class input-format date-format align] :as opts | ||
:or {input-class ""}}] | ||
(om/build create-textinput target | ||
{:state (-> opts | ||
(cond-> (nil? (:read-only opts)) | ||
(assoc :read-only false)) | ||
(merge {:path path | ||
:input-mask (cond | ||
(= input-format "numeric") "numeric" | ||
(= input-format "integer") "numeric" | ||
(= input-format "currency") "numeric" | ||
(= input-format "date") date-local-mask | ||
:else input-format) | ||
:currency (if (= input-format "currency") true false) | ||
:align (or align | ||
(cond (= input-format "numeric") "right" | ||
(= input-format "integer") "right" | ||
(= input-format "currency") "right" | ||
:else "left"))}))})) | ||
(let [valid-date-formats #{"MM/dd/yyy" "dd/MM/yyyy"}] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. particularmente creo que llevaría este let más cerca de donde se usa y no en la raíz del componente (porque en general algo a ese nivel asumimos que va a ser usado por todos lados pero no es el caso) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sisi, es verdad, podria moverse tranquilamente a la llave :date-format |
||
(om/build create-textinput target | ||
{:state (-> opts | ||
(cond-> (nil? (:read-only opts)) | ||
(assoc :read-only false)) | ||
(merge {:path path | ||
:input-mask (case input-format | ||
("numeric" "integer" "currency") "numeric" | ||
"date" date-local-mask | ||
input-format) | ||
:date-format (when (and (= input-format "date") | ||
(valid-date-formats date-format)) | ||
date-format) | ||
:currency (= input-format "currency") | ||
:align (or align | ||
(case input-format | ||
("numeric" "integer" "currency") "right" | ||
"left"))}))}))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ojo que snake case no se usa en clj
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
si... fue un typo...