Havardpede

Havardpede

I am working on creating a multi-page application form.
I have decided to hide the next-button until there is an answer for each question on the page.
To detect when an answer is updated, I have tried the following:

  • Attaching a phx-blur to the inputs. This worked, but forced the user to exit the input, which wasnt intuitive enough in certain cases.

  • Attaching a phx-keyup to inputs. I could not find a way to attach a reference to indicate which input was being edited, so I could update the relevant answer.

  • Wrapping the inputs in a <form> with phx-change. This triggered the event correctly, but did not reload the DOM. I even converted the navbar into a live_component, and tried triggering a forced re-render with send_update/2.

Do you have any ideas on how to handle this case?

Thanks in advance :slight_smile:

Showing Posts 1 to 10

chrismccord

chrismccord

Creator of Phoenix

This is the way to go. Can you share your live view / template (or a distilled version) so we can say what could be wrong? Thanks!

Havardpede

Havardpede OP

Hey @chrismccord appreciate your input :slight_smile:

I created the following to replicate the issue:

defmodule GladosWeb.LiveView.Test do
  use Phoenix.LiveView

  def render(assigns) do
    Phoenix.View.render(GladosWeb.MemberView, "test_application_page.html", assigns)
  end

  def mount(%{}, socket) do
    socket =
      socket
      |> assign(:show_button, false)
      |> assign(:answer, "")

    {:ok, socket}
  end

  def handle_event(
        "set_answer",
        %{"_target" => [target]} = values,
        socket
      ) do
    answer = values[target]

    socket
    |> assign(:show_button, answer != "")
    |> assign(:answer, answer)

    {:noreply, socket}
  end
end

<form phx-change="set_answer">
  <input type="string" name="input" value="<%= @answer %>" class="border" %>
  <br/>
  Show button?  <%= @show_button %>
</form>

image

image

When editing the answer, the socket is updated with the correct value for :show_button. However, this is not updated in the DOM.

outlog

outlog

socket
|> assign(:show_button, answer != "")
|> assign(:answer, answer)

{:noreply, socket}

seems like those assigns doesn’t go on the socket/reply eg you need

socket = socket
|> assign(:show_button, answer != "")
|> assign(:answer, answer)

{:noreply, socket}

this is a bit of OOP vs FP..

socket
|> assign(:show_button, answer != "")
|> assign(:answer, answer)

is basically a noop in FP - while in OOP it would most likely have mutated “socket”

Havardpede

Havardpede OP

Oh wow yeah that was obvious. Thank you :blush:

Havardpede

Havardpede OP

@outlog I stored the updated socket. That did not solve it unfortunately.

chrismccord

chrismccord

Creator of Phoenix

can you share your new code?

Havardpede

Havardpede OP

String input
The following code is when using phx-change in conjunction with a input of type string.
ezgif.com-video-to-gif (1)

<form phx-change="set_answer">
  <input type="string" name="input" value="<%= @answer %>" class="border" %>
  <br/>
  Show button?  <%= @show_button %>
</form>

defmodule GladosWeb.LiveView.Test do
  use Phoenix.LiveView

  def render(assigns) do
    Phoenix.View.render(GladosWeb.MemberView, "test_application_page.html", assigns)
  end

  def mount(%{}, socket) do
    socket =
      socket
      |> assign(:show_button, false)
      |> assign(:answer, "")

    {:ok, socket}
  end

  def handle_event(
        "set_answer",
        %{"_target" => [target]} = values,
        socket
      ) do
    answer = values[target]

    socket =
      socket
      |> assign(:show_button, answer != "")
      |> assign(:answer, answer)

    {:noreply, socket}
  end
end

select input
ezgif.com-video-to-gif (4)

defmodule GladosWeb.LiveView.Test do
  use Phoenix.LiveView

  def render(assigns) do
    Phoenix.View.render(GladosWeb.MemberView, "test_application_page.html", assigns)
  end

  def mount(%{}, socket) do
    socket =
      socket
      |> assign(:show_button, false)
      |> assign(:answer, "hide")

    {:ok, socket}
  end

  def handle_event(
        "set_answer",
        %{"_target" => [target]} = values,
        socket
      ) do
    answer = values[target]

    socket =
      socket
      |> assign(:show_button, answer == "show")
      |> assign(:answer, answer)

    {:noreply, socket}
  end
end
<form phx-change="set_answer">
  <select name="select" class="mb-4">
    <option <%= if @answer == "hide", do: "selected" %> value="hide">hide button</option>
    <option <%= if @answer == "show", do: "selected" %>  value="show">show button</option>
  </select>
  <br/>
  Show button?  <%= @show_button %>
</form>

sfusato

sfusato

I don’t think you are properly pattern matching in your handle_event. If you do a print to the console inside the function, does it gets printed to the console?

If my suspicion is right, start with a bare values in the function head, print that to the console, see the format and then refine your pattern matching.

Havardpede

Havardpede OP

Yes it does in fact call the function, @sfusato :frowning:

outlog

outlog

check your browser console - believe there is a bug in phoenix_live_view.js
InvalidCharacterError: The string contains invalid characters.

Where Next? Top

Trending in Questions Top

stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New
Blokh
Hey guys, I’ve got a huge CSV ( around 10 GB ) that needs to be processed hourly Do you guys have any suggestions what is the best prac...
New
roeland
Kia ora, We have been using elixir-google-api to connect to Google Drive. However, with the updates to Tesla due to CVEs this is now bro...
New
kszambelanczyk
Hello! Could someone please give me a help/sample code, how to delete a file from s3 using waffle/waffle_ecto from Phoenix app. I creat...
New
Onor.io
I have what I’ve heard referred to as a “lookup table” in my database. This is a way of assigning codes to common values. One common lo...
New
jaybe78
Hello, I’m developing a online persistent chat system (what’s app) like using elixir/dynamodb/aws for a mobile app(flutter). The diffic...
New
Trolleger
What approach to take when sending live updates to “random” users Hi! I have a question, I have a little chat app, and when I create a DM...
New

Other Trending Topics Top

garrison
Hobbes is a low-level distributed database for the Elixir programming language. Hobbes provides a simple, safe, and scalable storage lay...
New
mcass19
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Damirados
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge &amp; Solve. They are GUI (Emerge) and State management (S...
New
netoum
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
wintermeyer
There are three potential reasons for members of this forum to have a look at https://vutuv.de You are tired or annoyed of LinkedIn. Yo...
New
aseigo
ICal is a library for interacting with iCalendar data. It parses iCalendars into typed Elixir structs via ICal.from_ics, and can prepare ...
New

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews