roganjoshua

roganjoshua

Basic Understanding of Live Form

I am trying to get a basic for to do my bidding.
I am very much a beginnner so many things are a bit cloudy.
I have a heex template below:

<main class="px-4 py-20 sm:px-6 lg:px-8">
  <.form for={@form} phx-change="validate" phx-submit="Go">
    <div class="p-2">
      <div>
        <.input
          name="version"
          field={@form[:version_id]}
          options={@versions}
          type="select"
          phx-change="select-version"
          value=""
          label="Select a Version"
        />
      </div>

      <div>
        <.input
          name="customer"
          field={@form[:customer_id]}
          options={[]}
          type="select"
          phx-change="select-customer"
          value=""
          label="Select a Customer:"
        />
      </div>
      <div>
        <.button>
          Go
        </.button>
      </div>
    </div>
  </.form>
  <pre><%= inspect assigns, pretty: true %></pre>
</main>

There are two <selects one is dependent on the other.
So the value selected from versions will populate the other selector with a list of customers that belong to that version.

The related code looks like this at the moment.

defmodule CustomerbuilderWeb.MainLive.Index do
  use CustomerbuilderWeb, :live_view

  alias Customerbuilder.Builder

  @impl true
  def mount(_params, _session, socket) do

    {:ok,
     socket
     |> assign(:versions, get_versions())
     |> clear_form()}
  end

  @impl true
  def handle_event("select-version", %{"id" => id}, socket) do
    {:noreply, stream(socket, :version_collection, id)}
  end

  @impl true
  def handle_event("select-customer", %{"id" => id}, socket) do
    {:noreply, stream(socket, :version_collection, id)}
  end

  def assign_form(socket, changeset) do
    assign(socket, :form, to_form(changeset))
  end

  def clear_form(socket) do
    form =
      socket.assigns
      |> to_form()

    assign(socket, :form, form)
  end

  defp get_versions() do
    for version <- Builder.list_version(), do: {version.name, version.id}
  end
end

Once the version and customer is set the Go button will take those values and send a POST request to an api (using HTTPPoison?) to kick off a build.

Then a kind of polling to api monitor the progress of the build to update the UI, which I haven’t even started.

a map with atom keys was given to a form. Maps are always considered parameters                                                      and therefore must have string keys, got: %{versions: [{"Version-8.6.2",1}, {"Version-8.6.1", 2}, {"Version-8.5.3", 3},

I am very grateful for any interest here.

Marked As Solved

codeanpeace

codeanpeace

The data set as assigns and/or streams in the server side socket isn’t transfered across the websocket. It’s the rendered HTML template and subsequent changes/diffs that get sent to the client side via the websocket.

defmodule LiveCalWeb.OrganizationUserSearchLive do
  use LiveCalWeb, :live_view

  # note: options are structured as a list of tuples representing `option` text and value
  # e.g. `["Admin": "admin", "User": "user"]` as described in the `Phoenix.HTML.Form.options_for_select/2` docs

  def mount(_params, _session, socket) do
    organization_options = for org <- get_organizations(), do: {org.name, org.id}

    {:ok,
     socket
     |> assign(:form, to_form(%{"organization_id" => nil, "user_id" => nil}))
     |> assign(:organization_options, organization_options)
     |> assign(:user_options, [])}
  end

  def handle_event("select-organization", %{"organization_id" => org_id} = form_params, socket) do
    user_options = for user <- get_organization_users(org_id), do: {user.name, user.id}

    {:noreply,
      socket
      |> assign(:form, to_form(form_params))
      |> assign(:user_options, user_options)}
  end

  def handle_event("submit", %{"organization_id" => organization_id, "user_id" => user_id}, socket) do
    IO.puts("~~ form submitted for organzation id: #{organization_id} and user id: #{user_id}~~")
    {:noreply, socket}
  end

  def render(assigns) do
    ~H"""
    <.form for={@form} phx-submit="submit">
      <.input field={@form[:organization_id]} phx-change="select-organization"
        type="select"
        label="First select an organization to load its users:"
        placeholder="organization"
        options={@organization_options}
        prompt="-- select organization --"
      />
      <.input field={@form[:user_id]}
        type="select"
        label="Now select an organization user:"
        placeholder="user"
        options={@user_options}
        prompt="-- select user --"
      />
      <button>Submit</button>
    </.form>
    """
  end

  # stubbed users and organizations
  defp get_organizations(), do: [%{id: 1, name: "OrgA"}, %{id: 2, name: "OrgB"}]
  defp get_organization_users(organization_id) do
    case organization_id do
      "1" -> [%{id: 1, name: "John from OrgA"}, %{id: 2, name: "Jules from OrgA"}]
      "2" -> [%{id: 3, name: "Jack from OrgB"}, %{id: 4, name: "Jill from OrgB"}]
    end
  end
end

# bonus: if you add `:let={f}` inside the `<.form ...>` component and `:if={f.params["organization_id"]}` inside the user `<.input ...>`, you can hide the user dropdown until an organization is selected

https://github.com/codeanpeace/live_cal/commit/300d7843a31f28a31678db0cf3dd81722656bec8

Also Liked

roganjoshua

roganjoshua

Appreciate the time and effort you have put in here @codeanpeace .

It really helps to see examples like this as I can piece together how it works by connecting the names of things.

Where Next?

Popular in Questions Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
fireproofsocks
I’m working on defining a simple Ecto schema for a table (in PostGres), but I don’t see where I can define a column as NOT NULL. Conside...
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
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
nobody
How to bind a phoenix app to a specific ip address? could not find anything about that, nowhere, unfortunately, but for me this is quite...
New
jerry
Good day to you all. I have been struggling to get a query involving like and ilike to work. Can anyone assist me on this, please? pro...
New
JulienCorb
I am trying to implement my new.html.eex file to create new posts on my website. new.html.eex: &lt;h1&gt;Create Post&lt;/h1&gt; &lt;%= ...
New
vrod
I am using the Starship cross-shell prompt – it seems pretty nice, but I get some errors: [WARN] - (starship::utils): Executing command ...
New
Qqwy
Original source of discussion: This topic on the Pragmatic Programmers’ Functional Web Development with Elixir, OTP, and Phoenix forum. ...
New
PeterCarter
There are pre-rolled solutions for other frameworks that do work. However, Phoenix does not seem to have these. Have people had good expe...
New

Other popular topics Top

sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 42920 311
New
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
aalberti333
As the title describes, I’m trying to run Enum.map() over a list of key/value pairs, where the value is a map. My data looks like this: ...
New
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36128 110
New
rms.mrcs
Hi, I need to transform a list of numbers into a map where the keys are the indexes and the values are the original values of the list. ...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

We're in Beta

About us Mission Statement