added 03: forms
This commit is contained in:
commit
a18e94708e
|
@ -0,0 +1,84 @@
|
|||
module Main exposing (..)
|
||||
|
||||
-- Press buttons to increment and decrement a counter.
|
||||
--
|
||||
-- Read how it works:
|
||||
-- https://guide.elm-lang.org/architecture/buttons.html
|
||||
--
|
||||
-- Changes by maxmoon:
|
||||
-- - br import and added a new line for the reset button
|
||||
-- - Increment and decrement by 10
|
||||
-- - Reset number
|
||||
|
||||
|
||||
import Browser
|
||||
import Html exposing (Html, button, div, text, br)
|
||||
import Html.Events exposing (onClick)
|
||||
|
||||
|
||||
|
||||
-- MAIN
|
||||
|
||||
|
||||
main =
|
||||
Browser.sandbox { init = init, update = update, view = view }
|
||||
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
||||
|
||||
type alias Model = Int
|
||||
|
||||
|
||||
init : Model
|
||||
init =
|
||||
0
|
||||
|
||||
|
||||
|
||||
-- UPDATE
|
||||
|
||||
|
||||
type Msg
|
||||
= Increment
|
||||
| Increment10
|
||||
| Decrement
|
||||
| Decrement10
|
||||
| Reset
|
||||
|
||||
|
||||
update : Msg -> Model -> Model
|
||||
update msg model =
|
||||
case msg of
|
||||
Increment ->
|
||||
model + 1
|
||||
|
||||
Increment10 ->
|
||||
model + 10
|
||||
|
||||
Decrement ->
|
||||
model - 1
|
||||
|
||||
Decrement10 ->
|
||||
model - 10
|
||||
|
||||
Reset ->
|
||||
0
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
div []
|
||||
[ button [ onClick Decrement ] [ text "-1" ]
|
||||
, button [ onClick Decrement10 ] [ text "-10" ]
|
||||
, div [] [ text (String.fromInt model) ]
|
||||
, button [ onClick Increment ] [ text "+1" ]
|
||||
, button [ onClick Increment10 ] [ text "+10"]
|
||||
, br [] []
|
||||
, button [ onClick Reset ] [ text "reset" ]
|
||||
]
|
|
@ -0,0 +1,62 @@
|
|||
-- A text input for reversing text. Very useful!
|
||||
--
|
||||
-- Read how it works:
|
||||
-- https://guide.elm-lang.org/architecture/text_fields.html
|
||||
--
|
||||
-- Changes by maxmoon:
|
||||
-- - Converted String.length (int) to string
|
||||
-- - New text field to show the length of the string
|
||||
|
||||
import Browser
|
||||
import Html exposing (Html, Attribute, div, input, text)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onInput)
|
||||
|
||||
|
||||
-- MAIN
|
||||
|
||||
|
||||
main =
|
||||
Browser.sandbox { init = init, update = update, view = view }
|
||||
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ content : String
|
||||
}
|
||||
|
||||
|
||||
init : Model
|
||||
init =
|
||||
{ content = "" }
|
||||
|
||||
|
||||
|
||||
-- UPDATE
|
||||
|
||||
|
||||
type Msg
|
||||
= Change String
|
||||
|
||||
|
||||
update : Msg -> Model -> Model
|
||||
update msg model =
|
||||
case msg of
|
||||
Change newContent ->
|
||||
{ model | content = newContent }
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
div []
|
||||
[ input [ placeholder "Text to reverse", value model.content, onInput Change ] []
|
||||
, div [] [ text ("Reverse: " ++ String.reverse model.content) ]
|
||||
, div [] [ text ("Length: " ++ String.fromInt (String.length model.content)) ]
|
||||
]
|
|
@ -0,0 +1,99 @@
|
|||
-- Input a user name and password. Make sure the password matches.
|
||||
--
|
||||
-- Read how it works:
|
||||
-- https://guide.elm-lang.org/architecture/forms.html
|
||||
--
|
||||
-- Changes by maxmoon:
|
||||
-- - import Char
|
||||
-- - check if String contains upper letters
|
||||
-- - check if String contains lower letters
|
||||
-- - check if String contians digits
|
||||
-- - check if password has at least 8 chars
|
||||
|
||||
import Browser
|
||||
import Html exposing (..)
|
||||
import Html.Attributes exposing (..)
|
||||
import Html.Events exposing (onInput)
|
||||
import Char
|
||||
|
||||
|
||||
|
||||
-- MAIN
|
||||
|
||||
|
||||
main =
|
||||
Browser.sandbox { init = init, update = update, view = view }
|
||||
|
||||
|
||||
|
||||
-- MODEL
|
||||
|
||||
|
||||
type alias Model =
|
||||
{ name : String
|
||||
, password : String
|
||||
, passwordAgain : String
|
||||
}
|
||||
|
||||
|
||||
init : Model
|
||||
init =
|
||||
Model "" "" ""
|
||||
|
||||
|
||||
|
||||
-- UPDATE
|
||||
|
||||
|
||||
type Msg
|
||||
= Name String
|
||||
| Password String
|
||||
| PasswordAgain String
|
||||
|
||||
|
||||
update : Msg -> Model -> Model
|
||||
update msg model =
|
||||
case msg of
|
||||
Name name ->
|
||||
{ model | name = name }
|
||||
|
||||
Password password ->
|
||||
{ model | password = password }
|
||||
|
||||
PasswordAgain password ->
|
||||
{ model | passwordAgain = password }
|
||||
|
||||
|
||||
|
||||
-- VIEW
|
||||
|
||||
|
||||
view : Model -> Html Msg
|
||||
view model =
|
||||
div []
|
||||
[ viewInput "text" "Name" model.name Name
|
||||
, viewInput "password" "Password" model.password Password
|
||||
, viewInput "password" "Re-enter Password" model.passwordAgain PasswordAgain
|
||||
, viewValidation model
|
||||
]
|
||||
|
||||
|
||||
viewInput : String -> String -> String -> (String -> msg) -> Html msg
|
||||
viewInput t p v toMsg =
|
||||
input [ type_ t, placeholder p, value v, onInput toMsg ] []
|
||||
|
||||
|
||||
viewValidation : Model -> Html msg
|
||||
viewValidation model =
|
||||
if String.filter Char.isUpper model.password == "" then
|
||||
div [ style "color" "red" ] [ text "No upper letters"]
|
||||
else if String.filter Char.isLower model.password == "" then
|
||||
div [ style "color" "red" ] [ text "No lower letters"]
|
||||
else if String.filter Char.isDigit model.password == "" then
|
||||
div [ style "color" "red" ] [ text "No digits"]
|
||||
else if String.length model.password <= 8 then
|
||||
div [ style "color" "red" ] [ text "Less than 8 chars"]
|
||||
else if model.password == model.passwordAgain then
|
||||
div [ style "color" "green" ] [ text "OK" ]
|
||||
else
|
||||
div [ style "color" "red" ] [ text "Passwords do not match!" ]
|
|
@ -0,0 +1,5 @@
|
|||
Copyright (C) YEAR by AUTHOR EMAIL
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
@ -0,0 +1,9 @@
|
|||
# Elm Tutorial Solutions
|
||||
|
||||
Because the exercises of the [official Elm tutorials](https://guide.elm-lang.org/) got hard, I tried to find solutions on the internet, but I only found [something old](https://github.com/msachi/intro-to-elm-tutorial), which doesn't compile anymore. So I decided to make it by my own.
|
||||
|
||||
The solutions are compatible with **ELM 0.19.1** (2022-08-30).
|
||||
|
||||
All solutions work with the [official browser compiler](https://elm-lang.org/try) and the files contain comments on what I've changed.
|
||||
|
||||
**Disclaimer:** I am not a professional Elm programmer. I started to learn Elm a few days ago (August 2022). Even if I know other programming languages, it doesn't mean the solutions here are the best. But if I will stay with Elm and will know better solutions, I will improve them. And if I will not update solutions it could mean I am not interested in Elm anymore and found something better.
|
Loading…
Reference in New Issue