Skip to content

Commit 1e79541

Browse files
committed
Add date and time inputs, closes #15
1 parent a839195 commit 1e79541

File tree

5 files changed

+127
-6
lines changed

5 files changed

+127
-6
lines changed

bower.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717
},
1818
"dependencies": {
1919
"purescript-foldable-traversable": "^1.0.0",
20-
"purescript-dom": "^1.0.0",
21-
"purescript-signal": "^6.0.0",
20+
"purescript-dom": "^2.0.0",
21+
"purescript-signal": "^6.1.0",
2222
"purescript-canvas": "^1.0.0",
2323
"purescript-drawing": "^1.0.0",
2424
"purescript-smolder": "^4.0.0",
25-
"purescript-nonempty": "^1.0.0"
25+
"purescript-nonempty": "^1.0.0",
26+
"purescript-datetime": "^1.0.0"
2627
}
2728
}

html/index.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,19 @@ <h3>Example 16: Using other Signal functions (here: since)</h3>
215215
<div id="controls16"></div>
216216
<div id="output16"></div>
217217

218+
<h3>Example 17: Date input</h3>
219+
<pre>
220+
ui = showDiff &lt;$&gt; date &quot;Date 1&quot; (fromMaybe bottom date1)
221+
&lt;*&gt; date &quot;Date 2&quot; (fromMaybe bottom date2)
222+
where
223+
date1 = canonicalDate &lt;$&gt; toEnum 1986 &lt;*&gt; toEnum 7 &lt;*&gt; toEnum 3
224+
date2 = canonicalDate &lt;$&gt; toEnum 2016 &lt;*&gt; toEnum 8 &lt;*&gt; toEnum 5
225+
showDiff d1 d2 = &quot;Days between the dates: &quot; &lt;&gt;
226+
show (round $ abs $ unDays $ diff d1 d2)
227+
</pre>
228+
<div id="controls17"></div>
229+
<div id="output17"></div>
230+
218231
<script type="text/javascript" src="main.js"></script>
219232
</body>
220233
</html>

src/Flare.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,4 +327,48 @@ exports.cColor = createComponent("color",
327327
}
328328
);
329329

330+
function padNumber(num) {
331+
var str = num.toString();
332+
if (str.length == 1) {
333+
str = "0" + str;
334+
}
335+
return str;
336+
}
337+
338+
exports.cDate = createComponent("date",
339+
function(initial) {
340+
var input = document.createElement("input");
341+
input.type = "date";
342+
input.value = initial.year.toString() + "-" +
343+
padNumber(initial.month) + "-" +
344+
padNumber(initial.day);
345+
return input;
346+
},
347+
"input",
348+
function(t, initial) {
349+
var parts = t.value.split("-");
350+
return { year: parseInt(parts[0], 10),
351+
month: parseInt(parts[1], 10),
352+
day: parseInt(parts[2])
353+
};
354+
}
355+
);
356+
357+
exports.cTime = createComponent("time",
358+
function(initial) {
359+
var input = document.createElement("input");
360+
input.type = "time";
361+
input.value = padNumber(initial.hours.toString()) + ":" +
362+
padNumber(initial.minutes.toString());
363+
return input;
364+
},
365+
"input",
366+
function(t, initial) {
367+
var parts = t.value.split(":");
368+
return { hours: parseInt(parts[0], 10),
369+
minutes: parseInt(parts[1], 10)
370+
};
371+
}
372+
);
373+
330374
// vim: ts=2:sw=2

src/Flare.purs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ module Flare
3131
, radioGroup_
3232
, color
3333
, color_
34+
, date
35+
, date_
36+
, time
37+
, time_
3438
, fieldset
3539
, applyUIFlipped
3640
, (<**>)
@@ -53,6 +57,10 @@ import Data.Maybe.First (First(..), runFirst)
5357
import Data.Monoid (class Monoid, mempty)
5458
import Data.Foldable (class Foldable, traverse_, foldMap)
5559
import Data.Traversable (class Traversable, traverse)
60+
import Data.Enum (toEnum, fromEnum)
61+
import Data.Date (Date, exactDate)
62+
import Data.Date as Date
63+
import Data.Time (Time(..))
5664

5765
import Control.Apply (lift2)
5866
import Control.Monad.Eff (Eff)
@@ -130,6 +138,12 @@ foreign import cSelect :: forall a. Array a -> (a -> String) -> CreateComponent
130138
foreign import cRadioGroup :: forall a. Array a -> (a -> String) -> CreateComponent a
131139
foreign import cColor :: CreateComponent String
132140

141+
type DateRec = { year :: Int, month :: Int, day :: Int }
142+
type TimeRec = { hours :: Int, minutes :: Int }
143+
144+
foreign import cDate :: CreateComponent DateRec
145+
foreign import cTime :: CreateComponent TimeRec
146+
133147
-- | Set up the HTML element for a given component and create the corresponding
134148
-- | signal channel.
135149
createUI :: forall e a. (CreateComponent a) -> Label -> a -> UI e a
@@ -279,6 +293,40 @@ color label default = (fromMaybe default <<< fromHexString) <$>
279293
color_ :: forall e. Color -> UI e Color
280294
color_ = color ""
281295

296+
-- | Creates a date input field from a label and default `Date`.
297+
date :: forall e. Label -> Date -> UI e Date
298+
date label default = (fromMaybe default <<< toDate) <$>
299+
createUI cDate label { year: fromEnum (Date.year default)
300+
, month: fromEnum (Date.month default)
301+
, day: fromEnum (Date.day default)
302+
}
303+
where
304+
toDate :: DateRec -> Maybe Date
305+
toDate { year, month, day } = do
306+
y <- toEnum year
307+
m <- toEnum month
308+
d <- toEnum day
309+
exactDate y m d
310+
311+
-- | Like `date`, but without a label.
312+
date_ :: forall e. Date -> UI e Date
313+
date_ = date ""
314+
315+
-- | Creates a time input field from a label and default `Time`.
316+
time :: forall e. Label -> Time -> UI e Time
317+
time label default = (fromMaybe default <<< toTime) <$>
318+
createUI cTime label { hours: 0, minutes: 30 }
319+
where
320+
toTime :: TimeRec -> Maybe Time
321+
toTime { hours, minutes } = Time <$> toEnum hours
322+
<*> toEnum minutes
323+
<*> toEnum 0
324+
<*> toEnum 0
325+
326+
-- | Like `time`, but without a label.
327+
time_ :: forall e. Time -> UI e Time
328+
time_ = time ""
329+
282330
foreign import toFieldset :: Label -> Array Element -> Element
283331

284332
-- | Group the components of a UI inside a fieldset element with a given title.

test/Main.purs

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ import Control.Monad.Eff (Eff)
66
import Control.Apply (lift2)
77
import Data.Array (cons, (..), length, zipWith)
88
import Data.NonEmpty ((:|))
9-
import Data.Maybe (maybe)
9+
import Data.Maybe (maybe, fromMaybe)
1010
import Data.Monoid (mempty)
11+
import Data.Enum (toEnum)
1112
import Data.Foldable (foldMap, sum)
12-
import Data.Int (toNumber)
13+
import Data.Int (toNumber, round)
1314
import Data.Traversable (traverse)
15+
import Data.Date (canonicalDate, diff)
16+
import Data.Time.Duration (unDays)
1417
import Math (pow, sin, cos, pi, abs)
1518

1619
import DOM (DOM)
@@ -27,7 +30,8 @@ import Text.Smolder.HTML.Attributes as A
2730

2831
import Flare (UI, runFlareShow, runFlareWith, runFlare, button, liftSF, buttons,
2932
foldp, select, intSlider, numberSlider, string, intSlider_,
30-
boolean_, lift, color, number_, int_, string_, number, (<**>))
33+
boolean_, lift, color, number_, int_, string_, number, (<**>),
34+
date)
3135
import Flare.Drawing (Color, Drawing, runFlareDrawing, rgb, hsl, cssStringHSLA,
3236
path, lineWidth, black, outlineColor, outlined, fillColor,
3337
filled, circle)
@@ -218,6 +222,16 @@ light on = H.with H.div arg mempty
218222
ui16 :: forall e. UI e H.Markup
219223
ui16 = light <$> liftSF (since 1000.0) (button "Switch on" unit unit)
220224

225+
-- Example 17
226+
227+
ui17 :: forall e. UI e String
228+
ui17 = showDiff <$> date "Date 1" (fromMaybe bottom date1)
229+
<*> date "Date 2" (fromMaybe bottom date2)
230+
where
231+
date1 = canonicalDate <$> toEnum 1986 <*> toEnum 7 <*> toEnum 3
232+
date2 = canonicalDate <$> toEnum 2016 <*> toEnum 8 <*> toEnum 5
233+
showDiff d1 d2 = "Days between the dates: " <> show (round $ abs $ unDays $ diff d1 d2)
234+
221235

222236
-- Render everything to the DOM
223237

@@ -239,3 +253,4 @@ main = do
239253
runFlareWith "controls14a" inner ui14
240254
runFlareShow "controls15" "output15" ui15
241255
runFlareHTML "controls16" "output16" ui16
256+
runFlare "controls17" "output17" ui17

0 commit comments

Comments
 (0)