roganjoshua

roganjoshua

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.

Showing Posts 1 to 4

LionelHutz

LionelHutz

Looks interesting! Thanks for sharing. Just to confirm - are you looking for advice/insight on how to get to the functionality describe starting from the above, or saying that there’s a more particular problem with how it should already be working?

Thanks.

roganjoshua

roganjoshua OP

I am trying to get any of it working… it is really understanding exactly how it all hangs together.

mount : this is like a init for the live view and you can add models? to the socket for transfer across the websocket

I have added an array of key/value pairs (which I get t from the db) to the versions variable for use by the template. and then send it to a form was a schemaless changeset.

I expect the handle_event for select-version to do something which it really doesn’t at the moment but would do something like

for version <- Builder.get_customer_by_version_id(id), do: {customer.name, customer.id}

and assign that to the socket for the customer <.select

It is the form bit I am unsure of

field={@form[:version_id]}

not sure how to set this or retrieve it for example

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

roganjoshua

roganjoshua OP

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.

— All posts loaded —

Where Next? Top

Trending in Questions Top

katta
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
achenet
Hello, I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind. However, when I launch mix phx.server, I get an error...
New
kpanic
Hi everyone, I am toying with the idea of building a “match maker” for giving personal help to people that wants to start coding. I sta...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New
Cxx-mlr
I’m working on a small exercise involving update_in/3, and I came up with this solution: data = %{ name: "Periodic Table", category:...
New
ChrisAmelia
I’ve got trouble wrapping my head around the order in which functions are called in this snippet (from Phoenix’s authentication): toke...
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
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
budgie
A little off-topic, but I feel like people here have a good head on their shoulders. I used to be quite good at making software. Was luc...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews