Replies: 6 comments 4 replies
-
In my case, I solved it by having 2 virtual fields, one for the amount and one for the currency. |
Beta Was this translation helpful? Give feedback.
-
I started with the virtual fields then I figured - The built in date time selector does a similar thing so I had a look at how that works and I came up with:
And then you can use it with like:
And then similar to the date/datetime selector in phoenix you can supply your own builder function to control the output. I haven't fully tested this yet but I feel like this is the way to go vs having to clutter up your model with virtual fields |
Beta Was this translation helpful? Give feedback.
-
This looks promising indeed; do you have a proof-of-concept URL that demonstrates this by any chance? For a generalised solution, the |
Beta Was this translation helpful? Give feedback.
-
I could probably whip something up The step thing per currency would probably require adding some JavaScript |
Beta Was this translation helpful? Give feedback.
-
For those in the future who may arrive at this issue like me looking for a way to have a "single" input that can handle a def input(%{type: "money"} = assigns) do
assigns =
assigns
|> update(:value, &money_value/1)
|> assign_new(:default_currency, fn ->
backend = Money.default_backend()
Cldr.Currency.current_currency_from_locale(backend.get_locale())
end)
~H"""
<div phx-feedback-for={"#{@name}[amount]"}>
<.label for={@id}><%= @label %></.label>
<div class="relative mt-2 rounded-lg">
<input
type="text"
inputmode="numeric"
id={"#{@id}_amount"}
name={"#{@name}[amount]"}
value={@value.amount}
placeholder="0.00"
class={[
"block w-full rounded-lg border-0 pr-20 text-zinc-900 ring-1 ring-inset ring-zinc-300 placeholder:text-zinc-400 focus:ring-1 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6",
"phx-no-feedback:ring-zinc-300 phx-no-feedback:focus:ring-zinc-400",
@errors == [] && "ring-zinc-300 focus:ring-zinc-400",
@errors != [] && "ring-rose-400 focus:ring-rose-400"
]}
/>
<div class="absolute inset-y-0 right-0 flex items-center">
<label for={"#{@id}_currency"} class="sr-only">Currency</label>
<select
id={"#{@id}_currency"}
name={"#{@name}[currency]"}
class="h-full rounded-lg border-0 bg-transparent py-0 pl-2 pr-7 text-zinc-500 focus:ring-1 focus:ring-inset focus:ring-zinc-600 sm:text-sm"
>
<%= Phoenix.HTML.Form.options_for_select(
Money.known_currencies(),
@value.currency || @default_currency
) %>
</select>
</div>
</div>
<.error :for={msg <- @errors}><%= msg %></.error>
</div>
"""
end
defp money_value(%Money{} = money) do
money
end
defp money_value(nil) do
%Money{amount: nil, currency: nil}
end
defp money_value(%{"amount" => amount, "currency" => currency}) do
%Money{amount: amount, currency: currency}
end Then on your form, you can just use it like:
|
Beta Was this translation helpful? Give feedback.
-
@Wigny, thanks for the contribution, much appreciated. Perhaps you'd consider a blog post that you could then point elixirforum at? Just a couple of obversations too if I may:
|
Beta Was this translation helpful? Give feedback.
-
@cdvv7788, @LostKobrakai, one of the open issues is how to create a good experience inputting a money through an HTML form:
Your thoughts and suggestions would be most welcome.
Beta Was this translation helpful? Give feedback.
All reactions