Created
July 13, 2017 18:48
-
-
Save anonymous/29e370df7c9284011e15ebcedb5ee13a to your computer and use it in GitHub Desktop.
Untitled
This file contains 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
module Counter exposing (main) | |
import Html exposing (..) | |
import Html.Attributes exposing (..) | |
import Html.Events exposing (..) | |
import Time.DateTime as DateTime exposing (DateTime, date) | |
import Json.Decode as Decode exposing (Decoder) | |
-- Model | |
type Model | |
= HelloPage | |
| ItemFormPage Item | |
type alias Item = | |
{ title : String | |
, duration : Maybe Duration | |
} | |
type alias Duration = | |
{ begin : DateTime | |
, end : DateTime | |
} | |
decodeDuration : Decoder Duration | |
decodeDuration = | |
Decode.map2 Duration | |
(Decode.field "begin" decodeDateTime) | |
(Decode.field "end" decodeDateTime) | |
decodeDateTime : Decoder DateTime | |
decodeDateTime = | |
Decode.string |> Decode.andThen decodeDateTime_ | |
decodeDateTime_ : String -> Decoder DateTime | |
decodeDateTime_ s = | |
case DateTime.fromISO8601 s of | |
Err err -> | |
Decode.fail <| Debug.log "err" err | |
Ok date -> | |
Decode.succeed date | |
emptyItem : Item | |
emptyItem = | |
{ title = "This is title" | |
, duration = Nothing | |
} | |
mapItemForm : Model -> (Item -> Item) -> Model | |
mapItemForm model mapper = | |
case model of | |
ItemFormPage item -> | |
ItemFormPage <| mapper item | |
_ -> | |
model | |
-- Routing | |
type Route | |
= HelloPageRoute | |
| ItemFormRoute | |
-- Update | |
type Msg | |
= ChangeRoute Route | |
| TitleChanged String | |
| DurationChanged (Maybe Duration) | |
update : Msg -> Model -> ( Model, Cmd Msg ) | |
update msg model = | |
case msg of | |
ChangeRoute route -> | |
case route of | |
HelloPageRoute -> | |
HelloPage ! [] | |
ItemFormRoute -> | |
ItemFormPage emptyItem ! [] | |
TitleChanged title -> | |
mapItemForm model (\item -> { item | title = title }) ! [] | |
DurationChanged duration -> | |
mapItemForm model (\item -> { item | duration = duration }) ! [] | |
-- View | |
view : Model -> Html Msg | |
view model = | |
div [] (viewPage model) | |
viewPage : Model -> List (Html Msg) | |
viewPage model = | |
case model of | |
HelloPage -> | |
helloPage | |
ItemFormPage item -> | |
itemFormPage item | |
helloPage : List (Html Msg) | |
helloPage = | |
[ section [ class "content-header" ] | |
[ h3 [] [ text "Hello Page" ] ] | |
, section [] | |
[ button | |
[ class "btn btn-primary" | |
, onClick <| ChangeRoute ItemFormRoute | |
] | |
[ text "Edit an item" ] | |
] | |
] | |
itemFormPage : Item -> List (Html Msg) | |
itemFormPage item = | |
[ section [ class "content-header" ] | |
[ h3 [] [ text "Item Page" ] ] | |
, section [] [ itemForm item ] | |
] | |
itemForm : Item -> Html Msg | |
itemForm item = | |
Html.form [] | |
[ div [ class "form-group" ] | |
[ label [] [ text "Title" ] | |
, input | |
[ class "form-control" | |
, value item.title | |
, onInput TitleChanged | |
] | |
[] | |
] | |
, div [ class "form-group" ] | |
[ label [] [ text "Date range" ] | |
, input | |
[ class "form-control date-range" | |
, value <| formatMaybeDuration item.duration | |
, onDateRangePicker DurationChanged | |
] | |
[] | |
] | |
, button | |
[ type_ "button" | |
, class "btn btn-primary" | |
, onClick <| ChangeRoute HelloPageRoute | |
] | |
[ text "Go back" ] | |
, pre [] [ code [] [ text <| toString item ] ] | |
] | |
onDateRangePicker : (Maybe Duration -> Msg) -> Attribute Msg | |
onDateRangePicker tagger = | |
on "apply.daterangepicker" <| | |
Decode.map tagger <| | |
Decode.field "detail" <| | |
Decode.nullable decodeDuration | |
formatMaybeDuration : Maybe Duration -> String | |
formatMaybeDuration maybeDuration = | |
case maybeDuration of | |
Just d -> | |
(formatDateTime d.begin) ++ " - " ++ (formatDateTime d.end) | |
Nothing -> | |
"" | |
formatDateTime : DateTime -> String | |
formatDateTime d = | |
int00 (DateTime.day d) | |
++ "." | |
++ int00 (DateTime.month d) | |
++ "." | |
++ toString (DateTime.year d) | |
++ " " | |
++ int00 (DateTime.hour d) | |
++ ":" | |
++ int00 (DateTime.minute d) | |
int00 : Int -> String | |
int00 i = | |
String.padLeft 2 '0' (toString i) | |
main : Program Never Model Msg | |
main = | |
Html.program | |
{ view = view | |
, update = update | |
, subscriptions = \_ -> Sub.none | |
, init = ( HelloPage, Cmd.none ) | |
} |
This file contains 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
{ | |
"version": "1.0.0", | |
"summary": "Tell the world about your project!", | |
"repository": "https://github.com/user/project.git", | |
"license": "BSD3", | |
"source-directories": [ | |
"." | |
], | |
"exposed-modules": [], | |
"dependencies": { | |
"elm-lang/core": "5.1.1 <= v < 5.1.1", | |
"elm-lang/html": "2.0.0 <= v < 2.0.0", | |
"elm-community/elm-time": "1.0.1 <= v < 1.0.1" | |
}, | |
"elm-version": "0.18.0 <= v < 0.19.0" | |
} |
This file contains 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
<html> | |
<head> | |
<title></title> | |
<meta charset="utf8" /> | |
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap/3/css/bootstrap.css" /> | |
<link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.css" /> | |
</head> | |
<body> | |
<div id="demo-app"></div> | |
<script type="text/javascript" src="//cdn.jsdelivr.net/jquery/1/jquery.min.js"></script> | |
<script type="text/javascript" src="//cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script> | |
<script type="text/javascript" src="//cdn.jsdelivr.net/bootstrap.daterangepicker/2/daterangepicker.js"></script> | |
<script> | |
const main = document.getElementById("demo-app"); | |
const app = Elm.Counter.embed(main); | |
const observer = new MutationObserver(mutations => { | |
mutations.forEach(m => { | |
$(m.addedNodes).find('.date-range').each(function () { | |
createDatePicker($(this)); | |
}); | |
}); | |
}); | |
observer.observe(main, {childList: true, subtree: true}) | |
const createDatePicker = $elem => { | |
const format = 'DD.MM.YYYY HH:mm'; | |
const [start,end] = ($elem.val() || '').split(' - '); | |
const startEnd = (start && end | |
? { | |
startDate: moment(start, format), | |
endDate: moment(end, format) | |
} | |
: {}); | |
$elem.daterangepicker(Object.assign({}, startEnd, { | |
autoUpdateInput: false, | |
applyClass: 'btn-primary', | |
timePicker: true, | |
timePicker24Hour: true, | |
timePickerIncrement: 1, | |
locale: { | |
format, | |
cancelLabel: 'Clear' | |
} | |
})); | |
const publishUpdate = (elem, detail) => { | |
elem.dispatchEvent(new CustomEvent('apply.daterangepicker', { detail })); | |
}; | |
$elem.on('cancel.daterangepicker', function() { | |
publishUpdate(this, null); | |
}); | |
$elem.on('apply.daterangepicker hide.daterangepicker', function(e, picker) { | |
// https://github.com/elm-community/elm-time/issues/21 | |
const iso = d => d.toISOString().replace('.000Z', 'Z'); | |
publishUpdate(this, { | |
begin: iso(picker.startDate), | |
end: iso(picker.endDate) | |
}); | |
}); | |
}; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment