Skip to content

Instantly share code, notes, and snippets.

@matchu
Created July 29, 2015 00:45
Show Gist options
  • Save matchu/3e1830f8ffb58059f01e to your computer and use it in GitHub Desktop.
Save matchu/3e1830f8ffb58059f01e to your computer and use it in GitHub Desktop.
Prompt in Elm
module Greeter where
import Html exposing (Html, div, text, button)
import Html.Events exposing (onClick)
import Signal exposing (Address)
type alias Model =
{ name : String
, awaitingName : Bool }
type Action = NoOp | RequestName | CancelNameRequest | NameResponse String
type alias View =
{ html: Html
, promptRequest: Maybe String }
view : Address Action -> Model -> View
view actionAddress model =
{ html =
div []
[ text ("Welcome, " ++ model.name ++ "!")
, div []
[ button [ onClick actionAddress RequestName ] [ text "Wrong name?" ] ] ]
, promptRequest = if model.awaitingName then Just "What's your name?" else Nothing }
update: Action -> Model -> Model
update action model =
case action of
NoOp -> model
RequestName -> { model | awaitingName <- True }
CancelNameRequest -> { model | awaitingName <- False }
NameResponse newName -> { model | awaitingName <- False, name <- newName }
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="elm.js"></script>
</head>
<body>
</body>
<script type="text/javascript">
var app = Elm.fullscreen(Elm.Main, { promptResponses: null });
app.ports.promptRequests.subscribe(function(message) {
if (message !== null) {
var response = window.prompt(message);
app.ports.promptResponses.send(response);
}
});
</script>
</html>
module Main where
import Greeter exposing (..)
import Html exposing (Html)
import Signal
-- Prompt ports
port promptResponses : Signal (Maybe String)
port promptRequests : Signal (Maybe String)
port promptRequests =
Signal.map (\v -> v.promptRequest) views
-- Model
initialModel : Model
initialModel = { name = "Guest", awaitingName = False }
model : Signal Model
model = Signal.foldp update initialModel actions
-- Actions
promptResponseToAction : (Maybe String) -> Action
promptResponseToAction response =
response
|> Maybe.map (NameResponse)
|> Maybe.withDefault (CancelNameRequest) -- window.prompt returns null (Nothing) on cancel
promptResponseActions : Signal Action
promptResponseActions = Signal.map promptResponseToAction promptResponses
htmlActions : Signal.Mailbox Action
htmlActions = Signal.mailbox NoOp
actions : Signal Action
actions = Signal.merge htmlActions.signal promptResponseActions
-- Views
views : Signal View
views = Signal.map (view htmlActions.address) model
-- Main
main : Signal Html
main = Signal.map (\v -> v.html) views
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment