Assuming you're using the core users/save-user
action to edit users (as per the official User Profile form example) you can add a form input named groups
to save group assignments from the frontend form.
Note that this only works when editing an existing user's profile, i.e. not when registering new users.
Before saving the user, Craft will handle permission checking for you (again, assuming you're posting the form to the core users/save-user
action). Still, it's probably a good idea to make sure that only groups that the current user is able to save assignments for, are exposed as options in the form. Here's one way to achieve that – first pulling all user groups via the craft.app.userGroups
service, and then filtering those groups, using the currentUser.can()
method to check that the current user has the necessary assignUserGroup:[UserGroupUID]
permission for each group:
{% set userGroups = craft.app.userGroups.allGroups()|filter(group => currentUser.can("assignUserGroup:#{group.uid}")) %}
Once you have your userGroups
array, you can build a dropdown:
<form method="post" accept-charset="UTF-8" enctype="multipart/form-data">
...
<label for="group">User group</label>
<select id="group" name="groups[]">
{% for userGroup in userGroups %}
<option value="{{ userGroup.id }}"{% if user.isInGroup(userGroup) %} selected{% endif %}>{{ userGroup.name }}</option>
{% endfor %}
</select>
...
</form>
Or if you prefer, checkboxes. Notice the hidden input name="groups"
above the actual checkbox inputs – that's there to make it possible to submit the form without any groups checked:
<input type="hidden" name="groups" value/>
<fieldset>
<legend>User groups</legend>
{% for userGroup in userGroups %}
<label>
<input type="checkbox" name="groups[]" value="{{ userGroup.id }}"{% if user.isInGroup(userGroup) %} checked{% endif %} />
<span>{{ userGroup.name }}</span>
</label>
{% endfor %}
</fieldset>
Or radio buttons:
<fieldset>
<legend>User group</legend>
{% for userGroup in userGroups %}
<label>
<input type="radio" name="groups[]" value="{{ userGroup.id }}"{% if user.isInGroup(userGroup) %} checked{% endif %} />
<span>{{ userGroup.name }}</span>
</label>
{% endfor %}
</fieldset>