Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Doesn't work if field has a value set #65

Open
hunterboerner opened this issue May 8, 2024 · 7 comments
Open

Doesn't work if field has a value set #65

hunterboerner opened this issue May 8, 2024 · 7 comments

Comments

@hunterboerner
Copy link

Hi,

When creating a new record everything works fine. However, when I try editing a record with live_select it will override me on every keypress and lose focus. Any idea what's going on?

@hunterboerner
Copy link
Author

I figured out that this is the result of what I'm doing with the options:

  @impl true
  def handle_event(
        "live_select_change",
        %{"text" => text, "id" => live_select_id = "garden_region_id_live_select_component"},
        socket
      ) do
    matches =
      Seqfuzz.matches(socket.assigns.region_opts_stored, text, &elem(&1, 0),
        filter: true,
        sort: true
      )
    opts = Enum.map(matches, fn {m, _} -> m end) |> Enum.take(10)
    highlights =
      Enum.map(matches, fn {{a, _}, c} -> {a, c.matches} end) |> Enum.take(10) |> Enum.into(%{})
    send_update(LiveSelect.Component, id: live_select_id, options: opts)
    {:noreply, assign(socket, :highlights_regions, highlights)}
  end

and

        <.live_select
          field={@form[:region_id]}
          label="Region"
          phx-target={@myself}
          options={@region_opts}
          value_mapper={&to_string(&1)}
        >
          <:option :let={opt}>
            <.highlight matches={@highlights_regions[opt.label]} string={opt.label} />
          </:option>
        </.live_select>

If I change the event handler to not change the socket then it works as expected but of course I don't get my highlighting that I want.

@hunterboerner
Copy link
Author

hunterboerner commented May 9, 2024

This is occurring even with the following .highlight, though not reliably. It appears to only have issues when I type a letter that is included in the currently selected value's label.

  def highlight(assigns) do
    ~H"wat"
  end

@hunterboerner
Copy link
Author

I have tracked down the issue to this line in a reproduction repo: https://github.com/hunterboerner/live_select_test/blob/main/lib/live_select_test_web/live/foobar_live/form_component.ex#L70

If you change a variable that's used in the options then it causes this weird bug.

hunterboerner added a commit to hunterboerner/live_select that referenced this issue May 9, 2024
@maxmarcon
Copy link
Owner

maxmarcon commented May 12, 2024

Hi @hunterboerner . I think this issue is caused by a race condition in rendering. You're updating the options using send_update, at the same time you're changing the quox assign, which is used for rendering them.

Why not keeping all the information used to render the option within the option itself?

I tried the following on your repo and it works:

          <:option :let={opt}>
            <.baz label={opt.label} quo={opt.quo} />
          </:option>
def other_opts() do
    [%{label: "abc", value: "1"}, %{label: "def", value: "2"}]
end

@impl true
def update(%{foobar: foobar} = assigns, socket) do
    changeset = Foo.change_foobar(foobar)

    {:ok,
     socket
     |> assign(assigns)
     # set quo to 3 or whatever the value should be for the option
     |> assign(:other_opts, other_opts() |> Enum.map(&Map.put(&1, :quo, 3)))
     |> assign(:quox, %{})
     |> assign_form(changeset)}
end

@impl true
def handle_event(
        "live_select_change",
        %{"text" => text, "id" => live_select_id},
        socket
      ) do
    opts =
      other_opts()
     # set quo to 3 or whatever the value should be for the option
      |> Enum.map(&Map.put(&1, :quo, 3))

    send_update(LiveSelect.Component, id: live_select_id, options: opts)
    {:noreply, socket}
end

Let me know what you think

@hunterboerner
Copy link
Author

Hi @maxmarcon, I will try that when I get back to my computer. I can't remember for certain though but when I edited a field that wasn't using highlights map just plain label i still had the form input overriding my input. That's what the PR I created deals with. I'll check if this is still an issue back at my computer.

@hunterboerner
Copy link
Author

Hi so I think this will still be a a problem if you're triggering an update to the live_select by changing any assigns. Your solution should work bc it doesn't cause live view to retrigger the update hook for the live_select. This might be a big enough caveat to add to the docs

@maxmarcon
Copy link
Owner

ok can you please formalize/verify this statement? It's not clear to me what you mean exactly. Once you identified the problem, and can reproduce it, I'm ok with a PR that amends the docs. I will close the other PR in the meantime. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants