Arsenalist

Arsenalist

Showing form fields conditionally base on radio input value

I want to show input fields based on the value of a the radio button. Here are the two approaches I tried. This is inside a LiveComponent and I’m on LiveView 1.0.2. What is the best way to implement this simple feature (neither of the below work)?

APPROACH 1

When I click on a radio button, it is selected, but none of the following two ifs evaluate to true so the additional fields are never shown.

    <.form for={@form} phx-change="validate" phx-submit="save" phx-target={@myself}>
      <.input
        label="I am an individual"
        type="radio"
        value="INDIVIDUAL"
        field={@form[:entity_type]}
      />
      <.input
        label="I represent a company"
        type="radio"
        value="COMPANY"
        field={@form[:entity_type]}
      />
      <%= if Phoenix.HTML.Form.input_value(@form, :entity_type) == "INDIVIDUAL" do %>
        <.input label="First Name" type="text" field={@form[:first_name]} />
        <.input label="Last Name" type="text" field={@form[:last_name]} />
      <% end %>
      <%= if Phoenix.HTML.Form.input_value(@form, :entity_type) == "COMPANY" do %>
        <.input label="Company Name" type="text" field={@form[:company_name]} />
      <% end %>
    </.form>

Here is the LiveView code:

  def mount(socket) do
    form_attributes = %{
      "first_name" => "",
      "last_name" => "",
      "company_name" => "",
      "entity_type" => ""
    }

    {:ok,
     assign(
      socket,
       :form,
       to_form(form_attributes)
     )
    }
  end

  def handle_event("validate", _params, socket) do
    {:noreply, socket}
  end

APPROACH 2

After not getting this to work I also tried this approach where I set a new variable to track which entity_type is selected. This resulted in the if condition being executed, but the radio button not being selected and I have to click it again for it to be selected. Here’s a video: Area - Dubz

    <.form for={@form} phx-change="validate" phx-submit="save" phx-target={@myself}>
      <.input
        label="I am an individual"
        type="radio"
        value="INDIVIDUAL"
        field={@form[:entity_type]}
        phx-change="entity_type_changed"
        phx-target={@myself}
      />
      <.input
        label="I represent a company"
        type="radio"
        value="COMPANY"
        field={@form[:entity_type]}
        phx-change="entity_type_changed"
        phx-target={@myself}
      />
      <%= if @entity_type_selected == "INDIVIDUAL" do %>
        <.input label="First Name" type="text" field={@form[:first_name]} />
        <.input label="Last Name" type="text" field={@form[:last_name]} />
      <% end %>
      <%= if @entity_type_selected == "COMPANY" do %>
        <.input label="Company Name" type="text" field={@form[:company_name]} />
      <% end %>
    </.form>
  def mount(socket) do
    form_attributes = %{
      "first_name" => "",
      "last_name" => "",
      "company_name" => "",
      "entity_type" => ""
    }

    {:ok,
     assign(
      socket,
       :form,
       to_form(form_attributes)
     )
     |> assign(:entity_type_selected, "")
    }
  end

  def handle_event("entity_type_changed", %{"entity_type" => entity_type} = params, socket) do
    {:noreply, assign(socket, :entity_type_selected, entity_type)}
  end

First Post!

garrison

garrison

When your "validate" event is called, the form sends back the params in the params variable (the second argument to handle_event/3). You have to actually assign the new values back to the socket - currently you are just throwing them away.

{:noreply, assign(socket, :form, to_form(params))}

This is why your first approach doesn’t work. It’s also why your second approach doesn’t work - you are updating the variable, but you’re also throwing away the new params, so when the update comes back from the server it clobbers the radio button (since the server state was never changed).

Most Liked

LostKobrakai

LostKobrakai

The form abstraction needs to deal with invalid and partial values and various types of values. Hence it’s not the best place to check if an input is of a certain value. I’d suggest checking Ecto.Changeset.get_field(@form.source, field) instead if the form is based on a changeset.

Last Post!

sreyansjain

sreyansjain

You can try this. I am on mobile so I am a bit limited now.

<.input
  label="I am an individual"
  type="radio"
  value="INDIVIDUAL"
  field={@form[:entity_type]}
  checked={@form[:entity_type].value && @form[:entity_type].value == "INDIVIDUAL"}
/>

For conditional field visibility this would work too

<.input :if={@form[:entity_type].value && @form[:entity_type].value == "INDIVIDUAL"} label="First Name" type="text" field={@form[:first_name]} />

Need to update the form in the validate event

def handle_event("validate", params, socket) do
  {:noreply, assign(socket, :form, to_form(params))}
end

Where Next?

Trending in Questions Top

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
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" =&gt; #BSON.ObjectId&lt;58eb1a7a9ad169198c3dXXXX&gt;, "email" =&gt; ...
New
tj0
I’ve been following the steps here for the upgrade from 1.6 to 1.7 and it has gone relatively smoothly all the way till the phoenix_view ...
New
cgraham
Hi! What is currently the best library/method for parsing text and tabular data out of PDF files in Elixir or Erlang?
New
stefanchrobot
Hi, I need a way to handle data migrations in my application. I found an article by @wojtekmach about manual migrations: Automatic and ma...
New
stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
kip
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New
webofbits
Squid Mesh is an open source workflow automation runtime for Elixir applications. It is aimed at Phoenix and OTP apps that want to defin...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
kip
In 2021 I started a new library called Tempo with the objective of modelling time as a set of intervals - not as instants. In 2022 I gave...
New

We're in Beta

About us Mission Statement