Hello everyone, I’m new to Elixir, Phoenix, and Liveview so I’m hoping that this question isn’t too basic.
I have a Liveview that currently should show a different set of HTML based on an assign that I update on click:
<div>
<div style="height: 70px; background-color: #00558c;">
<div style="width: 95%; margin: auto; display: flex; flex-direction: row; justify-content: space-between">
<div style="color: white; font-size: 30px; font-family: Arial; margin-top: 18px; font-weight: bold;">HL7 Visualizer</div>
<label class="switch"><input type="checkbox" id="togBtn" class="<%= if @mode == :mode2 do %>checked <% end %>"><div class="slider round" phx-click="toggle"><!--ADDED HTML --><span phx-click="message_list" class="on"><%= @mode %></span><span class="off"><%= @mode %></span><!--END--></div></label>
</div>
</div>
<%= if @mode == :mode1 do %>
<div style="margin-top: 30px">
<%= for msg <- @raw_msg do %>
<div style="margin-bottom: 10px; max-width: 95%; margin-left: auto; margin-right: auto; overflow-wrap: break-word; overflow-y: hidden;"><%= msg %></div>
<% end %>
</div>
<% else %>
<div class="font-mono bg-white rounded-lg shadow-xl w-full px-6 py-3">
<%= for {seg, idx} <- Enum.with_index(@msg_list) do %>
<div class="block border border-gray-250 rounded-sm px-4 py-2 whitespace-no-wrap"><%= Enum.at(seg, 0) %></div>
<div id="seg" phx-click="show-detail" style="margin-right: 0px !important" class="ml-5 mt-1 mr-0 flex flex-wrap"><%= for {field, idx} <- Enum.with_index(seg) do %>
<%= if field == "" do %>
<span class="block border border-gray-250 rounded-sm px-1 py-2 whitespace-no-wrap "><%= field %></span>
<%= else %>
<span class="block border border-gray-250 rounded-sm px-4 py-2 whitespace-no-wrap max-w-md overflow-hidden" style="text-overflow: ellipsis;"> <%= field %></span>
<%= end %>
<% end %></div>
<% end %>
</div>
<%= if @show_detail == :true do %>
<div class="ml-5 mt-3 flex-col flex flex-wrap" style="max-height: 300px"><%= for comp <- @msg_seg do %>
<div class="flex w-200"><%= comp %></div>
<% end %></div>
<!--<%= render("detail.html", assigns) %>-->
<% end %>
<% end %>
When I load the liveview, the first set of HTML is rendered correctly and when I press the button that updates the @mode assign, it renders the new HTML correctly as well. My issue is that when I try to press the button again to set the mode back to :mode1 and render the first set of HTML again, the liveview actually renders both sets of HTML on top of each other in a weird way. I can’t seem to figure out what the issue is here. Also, I would appreciate it if any experts could illuminate a better way to achieve this if there is one
Edit: Here’s the Liveview code as well
defmodule MyAppWeb.VisualizerView do
use Phoenix.LiveView
def render(assigns) do
MyAppWeb.PageView.render("visualizer.html", assigns)
end
def mount(_session, socket) do
raw_msg = raw_message()
msg_list = message_list()
msg_seg = message_seg(0)
{:ok, assign(socket, mode: :mode1, raw_msg: raw_msg, msg_list: msg_list, msg_seg: msg_seg, show_detail: :false)}
end
def handle_event("toggle", _, socket) do
{:noreply, update(socket, :mode, fn
:mode1 -> :mode2
:mode2 -> :mode1
end )}
end
def handle_event("show-detail", _, socket) do
{:noreply, update(socket, :show_detail, fn
:false -> :true
:true -> :false
end )}
end
end