Fl4m3Ph03n1x
Background
I have a button that may be disabled or not, depending on a set of conditions. I want to disable/enable the button without having to reload the page.
To achieve this I am using the following code:
my_app_live.ex
#provided as a sample
def disable_buttton? do
if :rand.uniform(100) > 50 do
"true"
else
"false"
end
end
my_app.html.heex
<.button disabled={disable_button?)}>Execute Command</.button>
core_components.ex
def button(assigns) do
extra = assigns_to_attributes(assigns, [:disabled])
assigns = assign(assigns, :disabled?, case Map.get(extra[:rest], :disabled) do
"true" -> true
_ -> false
end)
~H"""
<p><%= "INSIDE BUTTON: #{inspect(@disabled?)}" %></p>
<button
type={@type}
class={if @disabled? do
[
"rounded-md bg-slate-400 px-3 py-2 text-sm font-semibold text-white shadow-sm",
@class
]
else
[
"rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm",
"active:text-white/80",
@class
]
end}
{@rest}
>
<%= render_slot(@inner_block) %>
</button>
"""
end
Problem
For some reason, <p><%= "INSIDE BUTTON: #{inspect(@disabled?)}" %></p> always shows true and thus the button is always disabled.
In reality disable_buttton? may return true/false depending on which buttons are selected (if all forms have a value, then the button should be enabled), however I am unaware of any pattern to do this in Phoenix.
I am also not convinced I am using assigns properly.
Questions
- How can I enable/disable a button in Phoenix, depending on state?
- Am I using
assigns_to_attributesandassigncorrectly in this sample?
I read Phoenix.Component — Phoenix LiveView v1.2.5 but I still don’t quite understand what I am missing here.
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Documentation
While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming











Showing Posts 6 to 1- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Fl4m3Ph03n1x
So, for those who are curious, this is the code I ended up with:
core_components.exThis is my modified button function:
And here is how I use it:
my_app_live.html.heexThis depends on the state, because the state changes with time, which means my button’s appearance will also change with time!
thanks everyone for the help!
Fl4m3Ph03n1x
So I understand you advocate I should change to:
correct?
So, in Phoenix LV, if the value is
falsethe attributedisabledis removed from the node, while if it is any other thing, the node gets the attribute asdisabled="something else", which means that becausedisabledis still present, irrespective of value, it is considered as a disabled button.I didn’t know about this. So this is yet another thing I learned
LostKobrakai
@restis mean as a “catch all” for all the attributes you’re not explicitly interested in / you don’t use besides passing them onwards.Any other attributes should have an explicit
attrdefinition.You’re not passing
false, you’re passing the string"false", which is a truthy value in elixir.Fl4m3Ph03n1x
I am confused. After reading Global Attributes (Phoenix.Component — Phoenix LiveView v1.2.5) I thought I could simply do
@disabledbecause thebuttonfunction is defined with the following attributes:However, when using
@disabledthe code crashes. So I am guessing I am doing something wrong. What have I missed?If I pass the value manually, i.e.,
<.button disabled={"false"}>Execute Command</.button>, then the button has the correct colour and appearance, but when I click it nothing happens, which means it is still disabled, even though the value isfalse.This is rather confusing to me.
Very well, I have added a timer that changes
random_numberevery second and I have assigned it withassigns |> assign(assigns, :random_numer, val).Let us assume for this sample, that
@random_numberwill be between 0 - 100 and it changes periodically.As a consequence, the code is now:
my_app.html.heexWhich, in conjunction with the
core_components.ex:Now changes the colour of the button correctly, from
bg-slate-400tobg-indigo-600. However, I have more questions now:@random_number > 50to a function insidemy_app_live.exinstead of simply having it in theheexfile and still have this behaviour work?@rest?disabled?Thanks everyone for the replies and help!
josevalim
There is no visible change happening in this code. So Phoenix will render it once and never change it unless you reload the page. If instead you have a button or a timer trigger the rand value and store it in an assign, it will work.
You could say “well, there is a change, it is random”. But if Phoenix assumed that every code had a random component, then we would not be able to change tracking anything ever.
TL;DR: Use assigns for changing state.
LostKobrakai
Not really. If you’re pulling out values out of
assigns.restyou’re doing something wrong. The attribute shouldn’t be put into the catch all@restin the first place, but be an explicit attr.Are you sure this is not releated to your
:randusage / function call? Do things work if you manually passtrueorfalse?