Ex_money and forms - separate currency and amount?

I’m still new to Phoenix. I’m building an app that deals with multiple currencies.

ex_money can parse a string to Money like “USD 100” so I can use a text field for the amounts.

But I would prefer to separate it and have the amount be a text field with the currency as drop down. As this will more user friendly then having to manually type the currency in a text field.

What is the best way to do this?

do you have a list of currencies you know you want to deal with?

I currently have a list of major currencies like USD, EUR, JPY, etc I use. But ideally I want all currencies if possible.

This is what I have so far

<%= text_input f, :item_cost_amount, value: input_value(f, :item_cost).amount %>
<%= select f, :item_cost_currency, ["USD", "EUR", "JPY"], prompt: "" %>

Then in the controller I will “stitch” them back together.

Issues are I have to account for nil as input_value(f, :item_cost) can be nil.

Also I have a bunch of fields like this, so I need to make some helper or something for both the front end and controller.

I’m still new to Elixir and Phoenix. This is what I have so far now after some playing around.

For Frontend

  def currency_input(form, field, opts \\ []) do
    [value, selected] = case Phoenix.HTML.Form.input_value(form, field) do
      nil -> [nil, nil]
      obj -> [obj.amount, obj.currency]
    end

    [
      Phoenix.HTML.Form.text_input(form, String.to_atom("#{field}_amount"), value: value),
      Phoenix.HTML.Form.select(form, String.to_atom("#{field}_currency"), ["USD", "EUR", "JPY"], prompt: "", selected: selected)
    ]
  end

For controller

  defp merge_currency(params, field) do
    money_value = case Money.new(Map.get(params, "#{field}_currency"), Map.get(params, "#{field}_amount")) do
      {:error, _} -> nil
      value -> value
    end

    Map.put(params, field, money_value)
  end

The only big problem is the String.to_atom. I believe I read there is a limit to number of atoms.