material-transfer

Dual listbox — Django filter_horizontal analog for M2M fields. Two panels with per-side search, move buttons, double-click to move. Posts one name=<value> entry per chosen item.

Form posting — slotted options, preselected

A Django widget renders one <material-option> per queryset row; selected marks the chosen side (the exact markup a <select multiple> gets). Click marks, double-click moves, Space marks / Enter moves from the keyboard. Filter applies to "Choose all".

Anna Petersen Robert Chen Carol Diaz Dmitri Volkov Elena Marquez Frank Lin Grace Patel (inactive) Henry Okafor Ivy Zhang Jack Reyes Katya Sokolova Liam Byrne
Submit Reset
(submit to see FormData)

JS options, compact (size="5"), no filter

RTL (hard-coded)

Panels mirror; move chevrons point toward the logical "chosen" side.

البريد الإلكتروني التقارير الفواتير المستودع
Sample usage (Django)
<form method="post">
  <material-transfer name="members" required
                     available-label="{% trans 'All users' %}"
                     chosen-label="{% trans 'Members' %}">
    {% for user in users %}
      <material-option value="{{ user.pk }}"
                       {% if user.pk in member_ids %}selected{% endif %}>
        {{ user.get_full_name }}
      </material-option>
    {% endfor %}
  </material-transfer>
</form>

# views.py
ids = request.POST.getlist('members')   # ModelMultipleChoiceField works too