Parent form state reset when child live component is rendered on button click

Hello,

I have a very simple code setup with a Parent Live View and a child Live Component. They both have a form with some data.

The parent contains 2 fields which is a date and a text field in the form. Outside the form is a button which loads a child live component below the button on a button click.

The child live component has a form with with mainly text fields and a time-input field.

When submitted the data goes to the correct handle events of the parent as well as the child.

I have 2 questions:

  1. when i click on the button to render the child live component the data entered in the parent live view form gets reset and turns blank, how can i avoid this?
  2. Is there any way i can close (not show) the child live component when the form is submitted for the child component?

I am adding the code below.

P.S. I am a beginner and very recently started coding in elixir.


The Live View and its template

defmodule FormsTutorialWeb.PageLive do
  use FormsTutorialWeb, :live_view

  def mount(_params, _session, socket) do
    {:ok, assign(socket, event_type: "")}
  end

  @spec handle_event(<<_::56>>, any, any) :: {:noreply, any}
  def handle_event("clicked", params, socket) do
    IO.puts "handle event of parent"
    IO.inspect(params, label: "params ---> ")
    {:noreply, socket}
  end

  def handle_params(_params, _uri, socket) do
    {:noreply, socket}
  end

  def handle_event("show_interstitial", params, socket) do
    IO.puts "inside handle event show interstitial"
    IO.inspect(params, label: "params ---> ")
    {:noreply, assign(socket, event_type: "Show")}
  end
end


<%= f = form_for :new_day, "#", [phx_submit: :clicked] %>
  <label>Create new day</label>
  <%= date_input f, :date%>

  <label class="form-control-label" for="url">Media URL</label>
  <%= text_input f, :url%>

  <div>
    <%= submit "Done", phx_disable_with: "Setting..." %>
  </div>
</form>

<div phx-click="show_interstitial">
    <a>Show interstitial</a>
</div>



<%= if @event_type == "Show" do %>
  <%= live_component(
            @socket,
            FormsTutorialWeb.PageComponent,
            id: "1",
            number: 1
          )
  %>
<% end %>

The child live component and its template

defmodule FormsTutorialWeb.PageComponent do
  use Phoenix.LiveComponent
  use Phoenix.HTML
  alias FormsTutorial.User
  alias FormsTutorial.Pictures.Picture
  alias FormsTutorial.Pictures

  def mount(socket) do
    changeset = Picture.changeset(%Picture{})
    {:ok, assign(socket, changeset: changeset)}
  end

  # def update(%{id: id, number: number}, socket) do
  #   {:ok,
  #    assign(socket,
  #      id: id,
  #      number: number
  #    )}
  # end

  def handle_event("clicked", params, socket) do
    IO.puts "handle event of child component"
    IO.inspect(params, label: "params ---> ")
    {:noreply, socket}
  end
end

<%= f = form_for :heading, "#", [phx_submit: :clicked, phx_target: @myself] %>
    <p class="pl-2">New Show Interstitial</p>

    <label>Name</label><br>
    <%= text_input f, :name %>

    <label>Age</label><br>
    <%= number_input f, :age %>

    <div>
        <%= submit "DONE"%>
    </div>
</form>
1 Like