cd-slash

cd-slash

Cascading selects in Livebook with Kino?

I have a livebook cell that starts with a single input, then appends additional select inputs recursively based on the input of the previous select box. It’s a self-referencing table, so it’s using parent / child relations to populate the next box. I’m pretty surprised that this works as I thought the recursive Kino.listen/2 calls would break something, but pleasingly it works pretty well.

The obvious problem is that inputs are only appended, not removed. If an earlier selection in the list is changed, another box is simply appended on the end. I can’t find any obvious way to track inputs appended to a frame so I can remove them without clearing the whole form - is there any way to track these? I have also tried using a Kino form or just adding raw inputs but neither seems to allow an append like the frame does.

defmodule AreaInputs do
  import Ecto.Query

  defp parent_id_filter(queryable, parent_id) do
    case parent_id do
      nil -> queryable |> where([a], is_nil(a.parent_id))
      _ -> queryable |> where([a], a.parent_id == ^parent_id)
    end
  end

  def get_areas(parent_id) do
    Area
    |> parent_id_filter(parent_id)
    |> order_by([a], a.name)
    |> AreaRepo.all()
    |> Enum.map(fn area -> {area.id, area.name} end)
  end

  def append_select_and_listen(frame, event) do
    new_input = Kino.Input.select("", AreaInputs.get_areas(event.value))
    Kino.Frame.append(frame, new_input)

    Kino.listen(new_input, fn event_2 ->
      append_select_and_listen(frame, event_2)
    end)
  end
end

frame = Kino.Frame.new() |> Kino.render()
initial_input = Kino.Input.select("", AreaInputs.get_areas(nil))
Kino.Frame.render(frame, initial_input)

Kino.listen(initial_input, fn event ->
  AreaInputs.append_select_and_listen(frame, event)
end)

Most Liked

jonatanklosko

jonatanklosko

Creator of Livebook

Hey @cd-slash : ) For this case I think you need a process to manage the frame and inputs, so you can re-render all the content. So more specifically, you could have a GenServer that has the frame and you would subscribe it to input events. Then, when an even is received, you re-render into the frame new set of inputs accordingly.

In the future we may have an abstraction to streamline this. Currently there is a proof of concept of a wizard in Kino Add Kino.Wizard POC by josevalim · Pull Request #426 · livebook-dev/kino · GitHub.

hugobarauna

hugobarauna

Livebook Core Team

Where Next?

Popular in Questions Top

sergio
In Ruby, I can go: User.find_by(email: "foobar@email.com").update(email: "hello@email.com") How can I do something similar in Elixir? ...
New
WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
jay1
Why is it that the mnesia database isn’t the most preferred database for use in Elixir/Phoenix?
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> somethi...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
yawaramin
In the Dialyzer docs ( dialyzer — OTP 29.0.2 (dialyzer 6.0.1) ), there is a way to turn off a specific warning for a function: -dialyzer...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

Other popular topics Top

WestKeys
Currently suffering from paralysis by [HTTP client] analysis. This is rather unusual in Elixirland as there tends to be consensus on the ...
New
JeremM34
Hello, how can I check the Phoenix version ? Thanks !
New
shahryarjb
Hello, I have map which I want to convert it to string like this: the map: %{last_name: "tavakkoli", name: "shahryar"} the string I ne...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
dogweather
I wrote this comment on r/haskell, and it’s not popular there. :wink: But I think I’m on to something… Haskell reminds me of Java, and e...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement