I have some tasks that launch on a button click. The tasks take between 1-10 seconds on the server to be done. As soon as the task is launched, I reply with a waiting
status and later send a success
or failure
when the task is done.
A couple of things need to happen when I click the button:
- Disable the button
- I’d like to change the text of the button to
evaluating....
- Change the loading indicator (both text and color)
This is some of the code I have so far:
<div class="relative">
<button
type="button"
class="inline-flex items-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-75"
disabled={@status == "waiting"}
phx-disable-with
phx-click={
JS.push("evaluate")
|> JS.remove_class(evaluation_style_span(@status), to: "##{@id}-span")
|> JS.add_class(evaluation_style_span("waiting"), to: "##{@id}-span")
|> JS.remove_class(evaluation_style_span(@status), to: "##{@id}-svg")
|> JS.add_class(evaluation_style_span("waiting"), to: "##{@id}-svg")
}
phx-target={@myself}
>
<Heroicons.play_circle solid class="-ml-1 mr-2 h-5 w-5" /> Evaluate
</button>
<div id="evaluation-status" class="absolute top-0 right-0">
<span
id={"#{@id}-span"}
class={[
"inline-flex items-center rounded-md px-2.5 py-0.5 text-sm font-medium",
evaluation_style_span(@status)
]}
>
<%= case @status do %>
<% "initial" -> %>
not evaluated
<% "waiting" -> %>
in progress
<% "success" -> %>
last execution was succesful
<% "failure" -> %>
last execution failed
<% end %>
<svg
id={"#{@id}-svg"}
class={["ml-1.5 -mr-0.5 h-4 w-4", evaluation_style_svg(@status)]}
fill="currentColor"
viewBox="0 0 8 8"
>
<circle cx="4" cy="4" r="4" />
</svg>
</span>
</div>
</div>
...
defp evaluation_style_span("initial"), do: "text-indigo-800"
defp evaluation_style_span("waiting"), do: "text-orange-800"
defp evaluation_style_span("success"), do: "text-green-800"
defp evaluation_style_span("failure"), do: "text-red-800"
defp evaluation_style_svg("initial"), do: "text-indigo-400"
defp evaluation_style_svg("waiting"), do: "text-orange-400"
defp evaluation_style_svg("success"), do: "text-green-400"
defp evaluation_style_svg("failure"), do: "text-red-400"
Some questions:
- I cannot change the text of button to
Evaluating...
withphx-disable-with
because then I loose theHeroicon
. Can I solve this in an other way? - The
JS.add_class
are persisted across renders (by design) but as soon as the server answers with thewaiting
status and latersuccess
the classes will 2 text colors. - I have no idea how I can change the text inside the
evaluation-status
div when the button is clicked.
So far these are the possible options for a solution I can think of:
- Don’t bother and only show update the loading when the server first can respond.
- Find a solution with
Phoenix.JS
somehow (don’t know how) - Do all of this directly in javascript
I don’t like solution 1 really, I don’t know how to do 2, and if possible I’d like to avoid 3.
Does anyone have suggestions on how to solve this in a nice way?