So, I'm trying to build a dashboard where the partner of the company I work for can edit users. And I want him to be able to have like a drop down to assign the user's group on the frontend. Is there a way to do this with just a form and input fields? Or does this have to be done with a custom plugin?
2 Answers
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>
-
1Great answer! Are you sure that
users/save-user
supports setting user groups though? It's not listed as a supported parameter in the documentation – but maybe it's just missing? Commented Mar 7, 2022 at 8:41 -
1@MoritzLost I did test it and it works. Maybe the reason why it's not mentioned in the docs is that assigning groups via
users/save-user
only works conditonally, specifically if the request is not a "public registration" – see github.com/craftcms/cms/blob/develop/src/controllers/…. In the case where the form is used to edit existing users' profiles (which is how I interpreted the OP)$isPublicRegistration
should always befalse
, and hence assigning user groups should work. Commented Mar 7, 2022 at 9:39 -
I'll make a note that the above only works when editing existing users and not when registering new ones, though – an important caveat :) Commented Mar 7, 2022 at 9:39
-
1
-
1I appreciate this so much, exactly what I was looking for! Thank you! Commented Mar 7, 2022 at 19:18
Why not just provide them with access to the backend, with only the permissions they need?
Anyway, if you need to provide a custom form in the frontend, you can write a form similar to the example in the knowledge base article on front-end user accounts. In particular the part about user profile forms.
As far as I know, the users/save-user
controller action doesn't allow you to edit user groups for a given user. Maybe check if there's another controller action that does that you can use. If there isn't, you're gonna have to write your own, making sure to include safeguards to prevent privilege escalation vulnerabilities. Then you can just point your custom form to the custom controller endpoint. See the documentation on controllers for details.
Edit: The users/save-user
controller does support editing groups for existing users, it's just not documented. See the answer by Mats Mikkel Rummelhoff for details.
-
1They will still have access to the backend, but I wanted them to have a nice user interface to easily change things to what they need to. But thanks for the response! Commented Mar 7, 2022 at 19:25