Skip to content

Instantly share code, notes, and snippets.

@TwistingTwists
Last active April 21, 2019 13:30
Show Gist options
  • Save TwistingTwists/56f4d36d5ec2e0484ece2994fad78fbb to your computer and use it in GitHub Desktop.
Save TwistingTwists/56f4d36d5ec2e0484ece2994fad78fbb to your computer and use it in GitHub Desktop.
module Upload exposing (main)
import Browser
import File exposing (File)
import File.Select as Select
import Html exposing (..)
import Html.Attributes exposing (checked, type_, value)
import Html.Events exposing (onClick, onInput)
import Http
import Json.Decode as Decode
import Json.Encode as Encode
--- MODEL
type alias Model =
{ name : String
, age : Int
, checked : Bool
, pdf : Maybe File
}
init : () -> ( Model, Cmd Msg )
init _ =
( { name = ""
, age = 0
, checked = False
, pdf = Nothing
}
, Cmd.none
)
--- API
encode : Model -> List ( String, Encode.Value )
encode model =
[ ( "name", Encode.string model.name )
, ( "age", Encode.int model.age )
, ( "checked", Encode.bool model.checked )
]
save : Model -> Cmd Msg
save model =
let
body =
case model.pdf of
Nothing ->
Http.jsonBody (Encode.object [ ( "person", Encode.object (encode model) ) ])
Just file ->
Http.multipartBody
(Http.filePart "person[pdf]" file
:: List.map
(\( l, v ) ->
Http.stringPart ("person[" ++ l ++ "]") (Encode.encode 0 v)
)
(encode model)
)
in
Http.post
{ url = "/persons"
, body = body
, expect = Http.expectJson Saved Decode.int
}
--- UPDATE
type Msg
= SelectFile
| FileSelected File
| ClearFile
| Save
| Saved (Result Http.Error Int)
| ChangedName String
| ChangedAge String
| Toggled
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
SelectFile ->
( model, Select.file [ "application/pdf" ] FileSelected )
FileSelected f ->
( { model | pdf = Just f }, Cmd.none )
ClearFile ->
( { model | pdf = Nothing }, Cmd.none )
Save ->
( model, save model )
Saved (Ok i) ->
( { model | pdf = Nothing }, Cmd.none )
Saved (Err _) ->
( model, Cmd.none )
ChangedName str ->
( { model | name = str }, Cmd.none )
ChangedAge str ->
( { model | age = String.toInt str |> Maybe.withDefault 0 }, Cmd.none )
Toggled ->
( { model | checked = not model.checked }, Cmd.none )
--- VIEW
view : Model -> Html Msg
view model =
let
pdfBtn =
case model.pdf of
Nothing ->
button [ onClick SelectFile ] [ text "Add PDF" ]
Just pdf ->
button [ onClick ClearFile ] [ text ("Remove " ++ File.name pdf) ]
in
div []
[ div [] [ text "Name" ]
, input [ type_ "text", value model.name, onInput ChangedName ] []
, label [] [ text "Age" ]
, input [ type_ "number", value (String.fromInt model.age), onInput ChangedAge ] []
, div [] [ text "Check this if you dare " ]
, input [ type_ "checkbox", checked model.checked, onClick Toggled ] []
, pdfBtn
, button [ onClick Save ] [ text "Save" ]
]
--- MAIN
main : Program () Model Msg
main =
Browser.element
{ init = init
, update = update
, view = view
, subscriptions = always Sub.none
}
module Main exposing (main)
import Browser
import Html exposing (..)
view : Flags -> Html msg
view { title, content } =
div []
[ h1 [] [ text title ]
, p [] [ text content ]
]
type alias Flags =
{ title : String
, content : String
}
main : Program Flags Flags ()
main =
Browser.element
{ init = \flags -> ( flags, Cmd.none )
, view = view
, update = \msg m -> ( m, Cmd.none )
, subscriptions = \_ -> Sub.none
}
<html>
<head>
<style>
/* you can style your program here */
h1 {
text-align: center;
}
p {
margin: 3rem;
}
</style>
</head>
<body>
<main></main>
<script>
var app = Elm.Main.init({ node: document.querySelector('main'),
flags: {
title: "Hello, Lorem!",
content: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
}
})
// you can use ports and stuff here
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment