How to set conditional class names in a template. Looking at the code below I’m wanting to toggle between bg-gray-900
and bg-gray-300
depending if the page is the active page. ie. `@page = “settings”?
<%= link "Account Settings", to: Routes.user_settings_path(@conn, :edit), class: "px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-md" %>
1 Like
Those could help
You just need to change the “active” class name to be the color you want and the nil
or default value to be the other shade.
3 Likes
I ended up using this inline conditional for applying the class, works for my use case and I feel it keeps it simple. Just set a ‘page’ variable on the render/3 in the controller.
<%= link "Account Settings", to: Routes.user_settings_path(@conn, :edit), class: "#{if @page === "account_settings", do: "bg-gray-900 "}px-3 py-2 text-sm font-medium text-white bg-gray-900 rounded-md" %>
2 Likes
Dabsy
August 17, 2021, 3:10pm
4
I pinched this snippet from a previous dev working on my current project.
def classes(classes) do
classes
|> Enum.filter(&elem(&1, 1))
|> Enum.map(&elem(&1, 0))
|> Enum.join(" ")
end
Using it as
<%= some_tag "example", class: classes("is-selected": is_selected_or_something()) %>
<div class="<%= classes("is-selected": true) %>">
3 Likes
matt1
April 28, 2023, 4:22pm
5
if it works for someone
<div class="w-full">
<ol class="flex flex-col text-sm font-medium text-center text-gray-500 md:items-center md:flex-row flex-nowrap ">
<li
:for={step <- @steps}
class={
(if step.slug == @current_step,
do: "text-blue-600 ",
else: "") <>
(if step.status != :last,
do: "sm:after:content-[''] sm:after:w-full sm:after:h-1 sm:after:border-b sm:after:border-gray-400 sm:after:border-1 sm:after:mx-6 ",
else: "") <>
"flex items-center"
}
>
<.icon name={step.icon} class="mr-2" />
<%= step.title %>
</li>
</ol>
</div>
zimt28
April 28, 2023, 6:30pm
6
You should be able to write this as
<div class="w-full">
<ol class="flex flex-col flex-nowrap text-center text-sm font-medium text-gray-500 md:flex-row md:items-center">
<li
:for={step <- @steps}
class={[
"flex items-center",
step.slug == @current_step && "text-blue-600",
step.status != :last &&
"sm:after:content-[''] sm:after:w-full sm:after:h-1 sm:after:border-b sm:after:border-gray-400 sm:after:border-1 sm:after:mx-6 "
]}
>
<.icon name={step.icon} class="mr-2" />
<%= step.title %>
</li>
</ol>
</div>
1 Like
Dabsy
May 17, 2023, 1:18pm
7
I also moved away from using the classes/1
function I mentioned above to the condition && "classes"
approach after someone noted the atom creation aspect of the keyword list being an additional unnecessary concern.
Hi
when I try your suggestion with something like:
<.icon
name="hero-check-circle"
class={[
"w-7 h-7",
if(item.status == :completed, do: "bg-green-600", else: "bg-gray-300")
]}
/>
I get a warning:
warning: attribute "class" in component DragWeb.CoreComponents.icon/1 must be a :string, got: [
I’m on phoenix 1.7.1 with live_view 0.18.16.
Does anyone have any idea why this isn’t working?
cheers
Dave
<.icon />
is defined in CoreComponents
. Search for def icon(
and change attr :class, :string, default: nil
to attr :class, :any, default: nil
.
1 Like
That worked :-). Many thanks @sodapopcan .