2

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 2

4

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>
5
  • 1
    Great 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?
    – MoritzLost
    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 be false, 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
    Thanks for the research – good to know!
    – MoritzLost
    Commented Mar 7, 2022 at 9:45
  • 1
    I appreciate this so much, exactly what I was looking for! Thank you! Commented Mar 7, 2022 at 19:18
3

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.

1
  • 1
    They 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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.