diff --git a/lib/livebook/notebook/cell.ex b/lib/livebook/notebook/cell.ex index c2635be56..61c1f3274 100644 --- a/lib/livebook/notebook/cell.ex +++ b/lib/livebook/notebook/cell.ex @@ -57,7 +57,7 @@ defmodule Livebook.Notebook.Cell do end def find_inputs_in_output({_idx, %{type: :control, attrs: %{type: :form, fields: fields}}}) do - Keyword.values(fields) + for {_field, input} <- fields, input != nil, do: input end def find_inputs_in_output({_idx, output}) when output.type in [:frame, :tabs, :grid] do diff --git a/lib/livebook/runtime.ex b/lib/livebook/runtime.ex index f214871b3..95b99b29e 100644 --- a/lib/livebook/runtime.ex +++ b/lib/livebook/runtime.ex @@ -437,7 +437,7 @@ defprotocol Livebook.Runtime do } | %{ type: :form, - fields: list({field :: atom(), input_output()}), + fields: list({field :: atom(), input_output() | nil}), submit: String.t() | nil, # Currently we always use true, but we can support # other tracking modes in the future diff --git a/lib/livebook/session.ex b/lib/livebook/session.ex index b81896914..1a6343161 100644 --- a/lib/livebook/session.ex +++ b/lib/livebook/session.ex @@ -3311,8 +3311,9 @@ defmodule Livebook.Session do :form -> Map.update!(attrs, :fields, fn fields -> - Enum.map(fields, fn {field, attrs} -> - {field, normalize_runtime_output({:input, attrs})} + Enum.map(fields, fn + {field, nil} -> {field, nil} + {field, attrs} -> {field, normalize_runtime_output({:input, attrs})} end) end) diff --git a/lib/livebook_web/live/output/control_form_component.ex b/lib/livebook_web/live/output/control_form_component.ex index fb1eaa5db..31a56dbfd 100644 --- a/lib/livebook_web/live/output/control_form_component.ex +++ b/lib/livebook_web/live/output/control_form_component.ex @@ -13,8 +13,9 @@ defmodule LivebookWeb.Output.ControlFormComponent do socket = assign(socket, assigns) data = - Map.new(assigns.control.attrs.fields, fn {field, input} -> - {field, assigns.input_views[input.id].value} + Map.new(assigns.control.attrs.fields, fn + {field, nil} -> {field, nil} + {field, input} -> {field, assigns.input_views[input.id].value} end) if prev_data != nil and data != prev_data do @@ -38,6 +39,7 @@ defmodule LivebookWeb.Output.ControlFormComponent do
<.live_component :for={{_field, input} <- @control.attrs.fields} + :if={input} module={LivebookWeb.Output.InputComponent} id={"#{@id}-#{input.id}"} input={input} @@ -75,7 +77,7 @@ defmodule LivebookWeb.Output.ControlFormComponent do defp reset_inputs(socket) do values = for {field, input} <- socket.assigns.control.attrs.fields, - field in socket.assigns.control.attrs.reset_on_submit, + input != nil and field in socket.assigns.control.attrs.reset_on_submit, do: {input.id, input.attrs.default} send(self(), {:set_input_values, values, true}) diff --git a/test/livebook_web/live/session_live_test.exs b/test/livebook_web/live/session_live_test.exs index 41d2f43ae..c55957278 100644 --- a/test/livebook_web/live/session_live_test.exs +++ b/test/livebook_web/live/session_live_test.exs @@ -548,7 +548,8 @@ defmodule LivebookWeb.SessionLiveTest do id: "input1", destination: test, attrs: %{type: :text, default: "initial", label: "Name", debounce: :blur} - } + }, + value: nil ], submit: "Send", report_changes: %{}, @@ -575,7 +576,8 @@ defmodule LivebookWeb.SessionLiveTest do |> element(~s/[data-el-outputs-container] button/, "Send") |> render_click() - assert_receive {:event, "control_ref1", %{data: %{name: "sherlock"}, type: :submit}} + assert_receive {:event, "control_ref1", + %{data: %{name: "sherlock", value: nil}, type: :submit}} end test "file input", %{conn: conn, session: session, test: test} do