Search code examples
elixirphoenix-framework

toggle between true and false in Elixir


I'm new to Elixir and am trying to toggle between true and false value like JS but i think that is not possible. is there an easy way to do that?

in the component

def update(assigns, socket) do
socket
|> assign(:show_password, false)
|> reply(:ok)
end


def handle_event("show_password", _params, socket) do
socket
|> assign(:show_password, !:show_password)
|> reply(:noreply)
end

in the HTML

 <i class="icon-closed_eye" phx-click="show_password" phx-target="<%= @myself %>"></i>

thank you all


Solution

  • It sure is, but, as mentioned in the comments, :show_password is an atom, not a boolean, so !:show_password doesn't make a lot of sense. However, you already have the value of :show_password in the socket's :assigns. So you can update it:

    def handle_event("show_password", _params, socket) do
      socket
      |> assign(:show_password, !socket.assigns[:show_password])
      |> reply(:noreply)
    end
    

    Or even:

    def handle_event("show_password", _params, socket) do
      socket
      |> update(:show_password, &(!&1))
      |> reply(:noreply)
    end
    

    And for the template, however, you still need to use something like a conditional:

    <%= if @show_password do %>
      <i class="icon-closed_eye" phx-click="show_password" phx-target="<%= @myself %>"></i>
    <% else %>
      <i class="icon-opened_eye" phx-click="show_password" phx-target="<%= @myself %>"></i>
    <% end %>
    

    Assuming you also have an icon-opened_eye icon.

    From there you can find other improvements. For instance you could avoid the conditional and use instead a helper function to define the class depending on the value of @show_password