#Getting the value of from multiple inputs in Lustre

1 messages · Page 1 of 1 (latest)

snow pond
#

I have the following code. I succeed at setting the address, but I fail to get the value of the 'arena_name' input. I have searched through the documentation and I fail to find a way to understand how I can retrieve the value either via the path, I also could find how to retrieve it on basis of the 'id attribute'. I'm sure there is a way, please help me out! 🙏

fn place_name_updater() -> element.Element(Msg) {
let handle_click = fn(event) {
let arena_name_path = ["target", "previousElementSibling", "previousElementSibling", "previousElementSibling", "value"]
io.debug(arena_name_path)
let arena_name_result = event
|> decipher.at(arena_name_path, dynamic.string)

case arena_name_result {
  Ok(arena_name) -> io.debug("arena name: " <> arena_name)
  Error(_) -> io.debug("error, failed to get the arena name")
} 

let arena_address_path = ["target", "previousElementSibling", "value"]
event
|> decipher.at(arena_address_path, dynamic.string)
|> result.map(UserSubmittedPlaceForm)

}

html.div([], [
html.form([],[
html.label([], [element.text("Arena name:")]),
html.input([attribute.id("arena_name")]),
html.label([], [element.text("Arena address:")]),
html.input([attribute.id("arena_address")]),]),
html.button([event.on("click", handle_click)], [html.text("Submit")]),
])
}

#

so for clarity, when i press the submit button, i always get a console log: 'error, failed to get the arena name'

wintry moss
#

in lustre it would be much more common to store the input fields in your model rather than the dom

snow pond
#

so on keydown for example?

wintry moss
#

so typically you would only listen to submit events on the form to know when to do something, rather than because you're using the browser's built-in form handlin

#

as a simplified example i would have

type Model {
  Model(name: String, address: String)
}

type Msg {
  UserUpdatedName(String)
  UserUpdatedAddress(String)
  UserSubmittedForm
}

and then in your view i would have

fn view(model) {
  html.div([], [
    html.form([],[
      html.label([], [element.text("Arena name:")]),
      html.input([attribute.value(model.name), event.on_input(UserChangedName)]),
      html.label([], [element.text("Arena address:")]),
      html.input([attribute.value(address), event.on_input(UserChangedAddress)]),
    ]),
    html.button([event.on_click(UserSubmittedForm)], [html.text("Submit")]),
  ])
}
#

it is possible to do what you were trying, and im happy to show you how, but ☝️ this would be more typical

snow pond
#

if i understand everything right, on each keystroke the model gets updated with the value from the input field, this meaning that the view gets constantly refreshed?

the thing is that i try to prevent the view refreshing constantly, because the following function is called in my view function, and that would use a lot of api keys

but maybe im doing something wrong and i should build in some logic to prevent against this?

pub fn show_map(model: Model) -> element.Element(Msg) {
// 55.725442489621116, 37.608174357865714

let google_api_key = "i should put this in a .env file soon"
let default_place = "eifel tower"

let url = case model.cleaned_place_name {
None -> "https://www.google.com/maps/embed/v1/place?key="<>google_api_key<>"&q="<>default_place<>"&center=55.7254,37.6081"
Some(cleaned_place_name) -> "https://www.google.com/maps/embed/v1/place?key="<>google_api_key<>"&q="<>cleaned_place_name<>"&center=55.7254,37.6081"
}

io.debug(url)

html.div([], [
html.h1([],[html.text("Arena")]),
html.iframe([
attribute.width(450),
attribute.height(250),
attribute.src(url),
]),
place_name_updater()
])
}

wintry moss
#

lustre only updates the parts of the dom that have changed so you don't have to worry about this (and if you notice otherwise then that's a bug that needs to be fixed not a problem you are supposed to work around!)

snow pond
#

oh super, i have something in mind now that might work, thanks for the quick answers!

wintry moss
#

happy to help ^.^

snow pond
#

so now i use those UserChangedName and UserChangedAddress to update my model

only on submit of the form (via UserSubmittedForm) is the model.cleaned_place_name changed (which is an Option(String))

i updated the show_map function to only take that optional string as a parameter (previously i passed the whole model there)

but when typing i see this show_map being triggered constantly (at first it shows the default location, after submitting the new cleaned string, typing after that still shows the same output (the new cleaned address))

i fear this is not working as expected, and possibly using api keys when i don't want it to

pub fn show_map(cleaned_place_name: Option(String)) -> element.Element(Msg) {
// 55.725442489621116, 37.608174357865714

let google_api_key = "api_key_still_not_in_env"
let default_place = "eifel tower"

let url = case cleaned_place_name {
None ->
"https://www.google.com/maps/embed/v1/place?key="
<> google_api_key
<> "&q="
<> default_place
<> "&center=55.7254,37.6081"
Some(cleaned_place_name) ->
"https://www.google.com/maps/embed/v1/place?key="
<> google_api_key
<> "&q="
<> cleaned_place_name
<> "&center=55.7254,37.6081"
}

io.debug("new url in view:" <> url)

html.div([], [
html.h1([], [html.text("Arena")]),
html.iframe([
attribute.width(450),
attribute.height(250),
attribute.src(url),
]),
])
}

#

or maybe the gleam code (and my io message) always runs, but the map doesn't get updated because it all stayed the same?