aboutsummaryrefslogtreecommitdiff
path: root/examples/03-controlled-inputs/README.md
blob: fcbbb1f300097af86526a06c1fb71d7e957c0fcb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
![](./header.png)

# 03 Controlled Inputs

> **Note**: this guide is written for Lustre v4. The latest stable release of
> Lustre is v3. To follow along with this guide, you need to _manually_ edit your
> `gleam.toml` and change the required version of lustre to `"4.0.0-rc.2"`.

The most common way to handle inputs and other state-holding elements is in a
_controlled_ way. This means your app's model is the source of truth for that
element's state, and you update that state based on user input or other events.

This example shows what that means in practice. For any controlled input we need
two things:

- A field in our model (or a function to derive a value from the model) to use
  as the input's `value` attribute.

- A message variant to handle input events and update the model.

```gleam
ui.input([
  // Input's value is fixed to the model's `value` field
  attribute.value(model.value),
  // Whenever the input changes, we send a `GotInput` message with the new value
  event.on_input(GotInput)
])
```

## Why is this beneficial?

Central to Lustre's architecture is the idea that your model is the single source
of truth for your application's UI. This opens up the door to things like serialising
program state to load in the future, time-travel debugging, and rehydrating your
app's state from a server.

It also gives you tighter control of when and how to update your UI in response
to user input. In this example, we only update the model when the new input
value is less than 10 characters long.

```gleam
case msg {
  GotInput(value) -> {
    let length = string.length(value)

    case length <= model.max {
      True -> Model(..model, value: value, length: length)
      False -> model
    }
  }

  ...
```

## Getting help

If you're having trouble with Lustre or not sure what the right way to do
something is, the best place to get help is the [Gleam Discord server](https://discord.gg/Fm8Pwmy).
You could also open an issue on the [Lustre GitHub repository](https://github.com/lustre-labs/lustre/issues).

While our docs are still a work in progress, the official [Elm guide](https://guide.elm-lang.org)
is also a great resource for learning about the Model-View-Update architecture
and the kinds of patterns that Lustre is built around.