This tutorial will explain how to make an Elm program that shows a number, a minus button to decrease it, and a plus button to increase it.
Initial State
The first part of the program is setting the default number when the program starts. In Scratch, that would look like this:
when flag clicked set [number v] to (0)
In Elm, a variable is used for the initial value. In Elm, variables cannot be changed, so this variable will always equal 0.
init =
0
View
It is also necessary to make a view, which shows things on the screen and specifies the messages to broadcast when buttons are pressed.
Buttons
In Scratch, each button would get its own sprite. The minus button would have these scripts:
when flag clicked go to x: (-80) y: (0) when this sprite clicked broadcast (decrease v)
The plus button is similar, but with a different position, and a different message to broadcast when clicked.
In Scratch, the decrease
and increase
messages would be added by clicking on the dropdown menu on broadcast ( v)
and selecting "New message".
In Elm, all messages go in one place in the code. A custom type can be created to represent a message. The pipe character |
goes between each possible message. This will create the Decrease
and Increase
variables, which are like dropdown menu options in Scratch.
type Msg = Decrease | Increase
The easiest way to make an HTML element for a button is to use the Html.button
function. It takes two parameters: a list of attributes (similar to Looks and Events in Scratch), and a list of elements to show inside of the button. Lists go in square brackets []
and each item is separated with commas.
The Html.Events.onClick
function produces an HTML attribute. It takes a Msg
value as a parameter.
minusButton =
Html.button
[ Html.Events.onClick Decrease ]
[ Html.text "-" ]
plusButton =
Html.button
[ Html.Events.onClick Increase ]
[ Html.text "+" ]
Number
In addition to these buttons, the number's current value must also be displayed. In Scratch, this script does that:
when flag clicked show variable [number v]
In Elm, a function that produces an HTML element from an integer (a number without decimals) can be created. The String.fromInt
function is needed, which creates text from an integer.
numberDisplay num =
Html.text (String.fromInt num)
Another way to make this function is to use >>
to combine Html.text
and String.fromInt
.
numberDisplay =
String.fromInt >> Html.text
The Entire View
In Elm, a function that generates the entire HTML needs to be created:
view num =
Html.div []
[ minusButton
, numberDisplay num
, plusButton
]
Updating the number
The program needs to know how to change the number when the buttons are clicked. In Scratch, this is done with a script for each possible message:
when i receive [decrease v] change [number v] by (-1) when i receive [increase v] change [number v] by (1)
In Elm, this requiress update
function that uses the message and previous number to calculate the new number. The case
expression causes a different result to be selected, depending on the value of msg
.
update msg num =
case msg of
Decrease ->
num - 1
Increase ->
num + 1
Assembling the Program
The init, view, and update functions can be turned into a program with Browser.sandbox, which takes a record as a parameter.
main =
Browser.sandbox
{ init = init
, view = view
, update = update
}
All of the Elm code
import Browser
import Html
import Html.Events
type Msg = Decrease | Increase
main =
Browser.sandbox
{ init = init
, view = view
, update = update
}
init =
0
minusButton =
Html.button
[ Html.Events.onClick Decrease ]
[ Html.text "-" ]
plusButton =
Html.button
[ Html.Events.onClick Increase ]
[ Html.text "+" ]
numberDisplay =
String.fromInt >> Html.text
view num =
Html.div []
[ minusButton
, numberDisplay num
, plusButton
]
update msg num =
case msg of
Decrease ->
num - 1
Increase ->
num + 1