userfrosting / UserFrosting

Modern PHP user login and management framework
https://www.userfrosting.com
Other
1.64k stars 366 forks source link

Dropdown box listing all users #206

Closed Forge-Media closed 9 years ago

Forge-Media commented 9 years ago

Hi.

I'm wondering if you could assist me, I'm looking for the easiest method to create a dropdown box which would list all the users [display_name]. Very similar to the New Action form with the Search for Action name.

Basically I need to get all user names, display them in a dropdown box and when you select a user it will get that users user_id.

alexweissman commented 9 years ago

Try something like this:

$fields = [  
  "user_dropdown" => [
    "type" => "select2",
    "label" => "Select user",
    "display" => 'show',
    "icon" => "fa fa-user",
    "choices" => loadUsers(),
    "placeholder" => "Select user",
    'validator' => [
        'selected' => true,
        'label' => 'Select user'
    ]
  ]
];

$template = "{{user_dropdown}}";

$fb = new FormBuilder($template, $fields, [], []);

echo $fb->render();

You can modify the template to include any other fields you might need. If you need buttons for submitting, canceling, etc., use the third parameter in FormBuilder. The fourth parameter is if you want to initialize the field with a particular value. See the Bootsole project for more information on the templating system.

Forge-Media commented 9 years ago

Thanks will try implementing this now :D

Forge-Media commented 9 years ago

I've created this field in my form file (form_atom.php) as well as updating the js widget file (widget-atoms.js)

However now when I click on an atom, see image > http://i.imgur.com/LXwWWq5.png It does not render the {{user_dropdown}} select field. Not sure if I'm missing something?

in my JS file I originally had the following: user_id: $('#' + dialog_id + ' input[name="user_id"]' ).val(),

No error is being generated in my php error log.

Changing the type from 'select2' to 'select' gives a php error: [21-Jan-2015 17:50:32 Europe/Paris] PHP 1. {main}() E:\Program Files (x86)\wamp\www\ForgeCP\forms\form_atom.php:0 [21-Jan-2015 17:50:32 Europe/Paris] PHP 2. FormBuilder->render() E:\Program Files (x86)\wamp\www\ForgeCP\forms\form_atom.php:226 [21-Jan-2015 17:50:32 Europe/Paris] PHP 3. FormBuilder->renderSelectField() E:\Program Files (x86)\wamp\www\ForgeCP\models\form_builder.php:46

alexweissman commented 9 years ago

Hmm, it looks like I didn't include select2 in the latest version of UF. Also, it looks like you need to build the choices list in the form required by the templating system. Try this:

https://gist.github.com/alexweissman/503f47d375000fb5e549

If you want to integrate the latest version of Bootsole into your project, that would enable you to use the select2 field type as well :-D

Forge-Media commented 9 years ago

Ok that got me so far, unfortunately the dropdown box is empty: http://i.imgur.com/DLD3p0O.jpg

 if (checkActionPermission('loadUsers', array())) {
    if (($users = loadUsers('asc')) === false) {
      apiReturnError($ajax, ACCOUNT_ROOT);  
    }

    foreach ($users as $user_id => $user){
        $user_choices[$user_id]  = ['label' => $user['display_name'] . " (" . $user['user_name']  . ")"];
    }
}

Do I need to pass $user_id as I'm not sure at the moment where form_atom.php is getting a value for the $user_id.

Sorry I'm pretty new to PHP.

alexweissman commented 9 years ago

No problem! The user_id should come from the key in the $user_choices array. It sounds like the user_choices array is probably just not getting populated. Could be a permissions issue - are you running as the root user?

If you want, you can remove the if (checkActionPermission('loadUsers', array())) { check, and change loadUsers to fetchUsers. But then, it will not do any authorization checking. If you can get it to work without authorization checking, then we can try to add that back in.

Forge-Media commented 9 years ago

I am testing this as the root user

While I'm giving that a shot thought I would just explain a little better what I'm trying to achieve overall.

The application allows admins to create Atoms which are assigned to a user. The creation of an Atom is almost identical to that of a user, except for fewer fields.

Assigned to each Atom is a Digitalocean Droplet ID. The concept is that each client will be able to see only their assigned "Atoms" (Digital Ocean Droplets). This is actually implemented and working, though at the moment assigning an Atom to a user requires an admin to enter the user's ID. (Which I'm trying to change now to a dropdown list of existing users).

Selecting a displayed user (by name) will get that user's (user_id) rather than an admin needing to know a users ID off-hand.

Eventually clients will also be able to control their Atom (Shutdown | Restart | Power On) as well as see the specifications of the Atom.

alexweissman commented 9 years ago

Cool, that makes sense and shouldn't be too hard to do. Can you try grabbing the newer version of Bootsole and see if that works? Also, can you print out the raw content of user_choices? Try error_log(print_r($user_choices, true)).

I'm basically doing the same thing in my company's CRM, we have a dropdown to select which tutor is being assigned to a particular student and it fetches the user_id. But, I am using the more recent version of Bootsole.

Forge-Media commented 9 years ago

Ok progress (sort of)

Firstly what is the best way to upgrade to the latest version of Bootsole?

I noticed that there is another similar line of code to this in the table_users.php:

if (($users = loadUsers($get['limit'])) === false) {
  apiReturnError($ajax, ACCOUNT_ROOT);  
}

I've tried the following:

if (checkActionPermission('loadUsers', array())) {
    if (($users = loadUsers('')) === true) {
      apiReturnError($ajax, ACCOUNT_ROOT);  
    }

    foreach ($users as $user_id => $user){
        $user_choices[$user_id]  = ['label' => $user['display_name'] . " (" . $user['user_name']  . ")"];
    }
}

The $user_choices array is populated as such:

(
    [1] => Array
        (
            [label] => Jeremy (jeremy)
        )

    [2] => Array
        (
            [label] => Marc (marc)
        )

)

However, I then get the following error: [21-Jan-2015 20:43:02 Europe/Paris] PHP 1. {main}() E:\Program Files (x86)\wamp\www\ForgeCP\forms\form_atom.php:0

[21-Jan-2015 20:43:02 Europe/Paris] PHP 2. FormBuilder->render() E:\Program Files (x86)\wamp\www\ForgeCP\forms\form_atom.php:241

[21-Jan-2015 20:43:02 Europe/Paris] PHP 3. FormBuilder->renderSelectField() E:\Program Files (x86)\wamp\www\ForgeCP\models\form_builder.php:46

Wondering now as in your example you used: 'asc' not sure as the parameter in loadUsers is $limit

alexweissman commented 9 years ago

Try if (($users = loadUsers('')) === false) {. The way you have it right now, with true, means that it will return an error if it succeeds in loading the users (which is not what you want). I just updated the Gist.

Yes you are correct, the same type of construct is used in table_users. Basically, we're loading checking permissions, and then loading the list of all users.

The best way to integrate the new version of Bootsole is just to replace the corresponding files in UF with the files in the current version of Bootsole (0.1.4). I am actually working on a new version of Bootsole as we speak, that will use Composer to make it easier to upgrade. But for now, unfortunately we have to do it manually :-(

Forge-Media commented 9 years ago

I tried replacing the files with their corresponding files, unfortunately this resulted in UserFrosting breaking. Functions such as :

As to the main issue I have altered the statement from true to false. But get the following PHP error:

[21-Jan-2015 22:03:44 Europe/Paris] PHP   1. {main}() E:\Program Files (x86)\wamp\www\ForgeCP\forms\form_atom.php:0
[21-Jan-2015 22:03:44 Europe/Paris] PHP   2. FormBuilder->render() E:\Program Files (x86)\wamp\www\ForgeCP\forms\form_atom.php:242
[21-Jan-2015 22:03:44 Europe/Paris] PHP   3. FormBuilder->renderSelectField() E:\Program Files (x86)\wamp\www\ForgeCP\models\form_builder.php:46

As the array is being populated, is it the older version of Bootsole which is the problem?

alexweissman commented 9 years ago

Try merging the contents of model/template_functions.php from UF with the contents of template_functions.php in bootsole.

I'm not sure what to make of that error message - it is just saying that it's calling the renderSelectField function, but nothing about what is actually going wrong.

Let me play with it a bit. Also, how urgent is this project? I'm working on a new version of bootsole, I can integrate it into UF once it's done but it may be a few more weeks.

alexweissman commented 9 years ago

Hmm ok, are you getting an Array => string conversion error? I just played with it in my local installation, and it looks like the old version of Bootsole expects each value in the choices array to be a string, rather than another array.

I just updated the Gist, it should work now. But be advised that if you upgrade Bootsole, the new version will want an array of attributes.

Forge-Media commented 9 years ago

Yes I was about to post this: Thanks the change works! :D

An array as such seems to work E.g: $choices = array('1' =>'choice1','2'=>'choice2');

I will try working on the bootsole update again.

alexweissman commented 9 years ago

Yeah, sorry about that. I have a whole new templating system coming out, which should make it a lot easier to build forms, pages, etc. So, I am waiting to synchronize Bootsole with UF for when the new version is ready.

If only I had used a dependency manager...sigh.

Forge-Media commented 9 years ago

Unfortunately I started my project ForgeCP back in August 2014 and left it till now. Trying to update my fork with the new changes to UserFrosting has been something I'm avoiding at the moment.

Thanks for the help Can't guarantee I wont be back :)

alexweissman commented 9 years ago

Lol no problem, I'll be around. Glad I could help.