Dynamic select with optgroup - how to group

Hi,

say i have a table like the one below.
±-------±-----------±-------±----------+
| emp_id | empname | grp_id | groupname |
±-------±-----------±-------±----------+
| 20 | Employee 2 | 13 | Group 1 |
| 19 | Employee 1 | 13 | Group 1 |
| 21 | Employee 3 | 14 | Group 2 |
±-------±-----------±-------±----------+

Now i´d like to have this:

<select name="dropdownmenu">
    <optgroup label="Group 1">
        <option name="20">Employee 2</option>
        <option name="19">Employee 1</option>
    </optgroup>
    <optgroup label="Group 2">
        <option name="21">Employee 3</option>
    </optgroup>
</select>

Repo.all(Employee) … and something with Enum.group_by. But i don´t know how to go on from here.

thanks

1 Like

Are you using Phoenix? There’s a good list of form helpers here: https://hexdocs.pm/phoenix_html/Phoenix.HTML.Form.html I guess you’ll want something like Rails’ grouped_collection_select.

Thanks, but i don´t see anything on that page that solves that.

Not sure if I understood correctly but I think you can do that with several queries.

Do a query for each group (using Ecto.Query) where each one returns an enum with the elements of the group and then you may do several select with select/3. Pass the enum that you obtained from the query to each select:

<% enum_group_1 = some_function_with_the_query_1 %>
<% enum_group_2 = some_function_with_the_query_2 %>
<%= select f, :group_1, enum_group_1 %>
<%= select f, :group_2, enum_group_2 %>

Thanks, but i need only 1 select with optgroups. I don´t see how i would get this working with your idea.

1 Like

Sorry I just reread your question. I thought you wanted multiple select but in reality you want one select with several optgroup :frowning:

This will work:

<select name="dropdownmenu">
  <%=for {grp, empls} <- @employee_grp do %>
      <optgroup label="<%=grp%>">
        <%=for emp <- empls do %>
          <option name="<%=emp.id%>"><%=emp.name%></option>
        <%end%>
      </optgroup>
  <%end%>
</select>

@emploee_grp is your result from Enum.group_by

%{"Group 1" => [%Employee{grp_id: 13, grp_name: "Group 1", id: 19, name: "Employee 1"}, 
                %Employee{grp_id: 13, grp_name: "Group 1", id: 20, name: "Employee 2"}],
  "Group 2" => [%Employee{grp_id: 14, grp_name: "Group 2", id: 21,name: "Employee 3"}]}
3 Likes

In case anyone else stumbles across this, note that optgroups are now supported by Phoenix’s HTML helpers.

options_for_select(["Europe": ["UK", "Sweden", "France"], ...], nil)
#=> <optgroup label="Europe">
      <option>UK</option>
      <option>Sweden</option>
      <option>France</option>
    </optgroup>
1 Like