Skip to content

Instantly share code, notes, and snippets.

@dwayne
Last active April 30, 2017 13:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dwayne/550341a5b27ba3c03ce7eba92d33873d to your computer and use it in GitHub Desktop.
Save dwayne/550341a5b27ba3c03ce7eba92d33873d to your computer and use it in GitHub Desktop.
Elm: Formatting a value as money
module Main exposing (..)
import Html exposing (..)
main =
view init
-- MODEL
type alias Model = List Float
init : Model
init =
[ 0.25
, 1.75
, 2345
, 100452.9
]
view : Model -> Html msg
view model =
ul [] <|
List.map
-- The best solution in my opinion would be to have a toMoney function
-- (\k -> li [] [ text <| toMoney k ])
(\k -> li [] [ text <| toString k ])
model
-- Main.elm
module Main exposing (..)
import Html exposing (..)
import Money exposing (Money)
main : Program Never Model Msg
main =
program
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
-- MODEL
type alias Model =
{ amounts : List Money
}
init : (Model, Cmd Msg)
init =
let
data =
[ 0.25
, 1.75
, 2345
, 100452.9
]
(amounts, cmds) =
data
|> List.indexedMap
(\i amount ->
let
(newAmount, newCmd) = Money.fromFloat amount
in
(newAmount, Cmd.map (SetMoney i) newCmd)
)
|> List.unzip
in
( Model amounts
, Cmd.batch cmds
)
type Msg
= SetMoney Int Money.Msg
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
SetMoney index moneyMsg ->
let
set i amount =
if i == index then
let
(newAmount, newCmd) = Money.update moneyMsg amount
in
(newAmount, Cmd.map (SetMoney i) newCmd)
else
(amount, Cmd.none)
(amounts, cmds) =
model.amounts
|> List.indexedMap set
|> List.unzip
in
( Model amounts
, Cmd.batch cmds
)
subscriptions : Model -> Sub Msg
subscriptions { amounts } =
Sub.batch <|
List.indexedMap
(\index amount -> Sub.map (SetMoney index) (Money.subscriptions amount))
amounts
view : Model -> Html Msg
view { amounts } =
let
asLi index amount =
li []
[ Html.map (SetMoney index) (Money.view amount)
]
in
ul [] <|
List.indexedMap asLi amounts
-- Money.elm
module Money
exposing
( Money
, fromFloat
, Msg
, update
, subscriptions
, view
)
import Html exposing (..)
import Format
type Money
= Raw Float
| Formatted Float String
fromFloat : Float -> (Money, Cmd Msg)
fromFloat value =
( Raw value
, Format.asMoney value
)
type Msg
= NewFormattedValue String
update : Msg -> Money -> (Money, Cmd Msg)
update msg money =
case money of
Raw value ->
case msg of
NewFormattedValue formattedValue ->
( Formatted value formattedValue
, Cmd.none
)
_ ->
( money, Cmd.none )
subscriptions : Money -> Sub Msg
subscriptions money =
case money of
Raw value ->
Format.moneyFormat NewFormattedValue
_ ->
Sub.none
view : Money -> Html Msg
view money =
case money of
Raw value ->
text (toString value)
Formatted _ formattedValue ->
text formattedValue
-- Format.elm
port module Format exposing (..)
port asMoney : Float -> Cmd msg
port moneyFormat : (String -> msg) -> Sub msg
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Format as money</title>
<script src="https://unpkg.com/accounting@0.4.1/accounting.min.js"></script>
<script src="main.js"></script>
</head>
<body>
<script>
var app = Elm.Main.fullscreen();
app.ports.asMoney.subscribe(function (value) {
var formattedValue = accounting.formatMoney(value);
app.ports.moneyFormat.send(formattedValue);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment