Skip to content

Commit 0a4c2e0

Browse files
committed
don't raise SelectionChanged during parent-child synchronization
If a previously valid DateTime was selected (e.g. Jan 1 2019, 12:00AM), when we change the DateTime interval (e.g. Jan 1 2020, 1:00AM - Dec 31 2020, 11:59PM) to exclude the selection, Date selection is cleared but Time selection is not cleared (remains 12:00AM) instead having TimePicker disabled. When we make a new valid selection on Date (e.g. Jan 1 2020), since previously selected Time (12:00AM) no longer falls within the interval (1:00AM - 11:59PM), TimePicker, once received the updated interval, will clear the selected Time. But between DateTimePicker updates Date selection and the updated interval reaches TimePicker, there's a transient state of DateTimePicker (Jan 1 2020, 12:00AM) that doesn't fall within the specified interval and thus an incorrect value is raised through SelectionChanged. We add isWithinInterval predicate and raiseSelectionChanged handler to prevent this from happening.
1 parent 4b2da64 commit 0a4c2e0

File tree

1 file changed

+31
-4
lines changed

1 file changed

+31
-4
lines changed

src/DateTimePicker.purs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module Ocelot.DateTimePicker
1717
import Prelude
1818
import Data.DateTime (Date, DateTime(..), Month, Time, Year)
1919
import Data.DateTime as Date.DateTime
20+
import Data.Foldable as Data.Foldable
2021
import Data.Maybe (Maybe(..))
2122
import Data.Maybe as Data.Maybe
2223
import Data.Tuple.Nested (type (/\))
@@ -107,14 +108,14 @@ handleAction :: forall m. Action -> ComponentM m Unit
107108
handleAction = case _ of
108109
HandleDate msg -> case msg of
109110
DatePicker.SelectionChanged date' -> do
110-
time' <- H.gets _.time
111-
H.raise $ SelectionChanged (DateTime <$> date' <*> time')
111+
state <- H.get
112+
raiseSelectionChanged state.interval date' state.time
112113
H.modify_ _ { date = date' }
113114
_ -> H.raise $ DateOutput msg
114115
HandleTime msg -> case msg of
115116
TimePicker.SelectionChanged time' -> do
116-
date' <- H.gets _.date
117-
H.raise $ SelectionChanged (DateTime <$> date' <*> time')
117+
state <- H.get
118+
raiseSelectionChanged state.interval state.date time'
118119
H.modify_ _ { time = time' }
119120
_ -> H.raise $ TimeOutput msg
120121
Receive input -> do
@@ -147,6 +148,32 @@ initialState input =
147148
, time: input.selection <#> Date.DateTime.time
148149
}
149150

151+
-- check if a datetime is within a **closed** interval
152+
isWithinInterval :: Interval -> DateTime -> Boolean
153+
isWithinInterval interval x =
154+
Data.Foldable.and
155+
[ Data.Maybe.maybe true (_ <= x) interval.start
156+
, Data.Maybe.maybe true (x <= _) interval.end
157+
]
158+
159+
raiseSelectionChanged ::
160+
forall m.
161+
Maybe Interval ->
162+
Maybe Date ->
163+
Maybe Time ->
164+
ComponentM m Unit
165+
raiseSelectionChanged mInterval mDate mTime = case mInterval of
166+
Nothing -> H.raise $ SelectionChanged mDateTime
167+
Just interval -> case mDateTime of
168+
Nothing -> H.raise $ SelectionChanged mDateTime
169+
Just dateTime
170+
| isWithinInterval interval dateTime -> H.raise $ SelectionChanged mDateTime
171+
| otherwise -> pure unit -- NOTE transient state during parent-child synchronization
172+
where
173+
mDateTime :: Maybe DateTime
174+
mDateTime = DateTime <$> mDate <*> mTime
175+
176+
150177
render :: forall m. MonadAff m => ComponentRender m
151178
render state =
152179
HH.div

0 commit comments

Comments
 (0)