2

I'm trying to create a dataTable of users where each row has a drop-down child row that contains checkboxes of the user privileges. So quite dynamically a 'super' admin can click on users and assign their privileges within the table.

Firstly, not sure if this is a good idea, so feel free to suggest a better way of doing it. Maybe a simple popup modal per row would be easier but for now I've decided this would be a cool way of doing it, so I push on.

Trying to initialise the dataTable with AJAX has me stumped currently however.

PermissionsController.php

public function grid()
{
    //retrieve data from models
    $data['data'] = collect([ 'admins' => $admins, 'roles' => $roles ]);

        return $data;
}

routes.php

Route::get('user-permissions', 'PermissionsController@grid');

permissions.blade

<table class="table table-striped" id="admins_table" >
    <thead>
    <tr>
        <th>Last Name</th>
        <th>First Name</th>
        <th>Email</th>
        <th>Phone</th>
    </tr>
    </thead>
</table>

js

var oTable = $('#admins_table').dataTable( {
    "sDom": "<'row'<'col-md-6'l><'col-md-6'f>r>t<'row'<'col-md-12'p i>>",
    "aaSorting": [],
    "oLanguage": {
        "sLengthMenu": "_MENU_ ",
        "sInfo": "Showing <b>_START_ to _END_</b> of _TOTAL_ entries"
    },
    "ajax": {
       //here's where I'm trying to grab the data
       "url": "http://example.app/user-permissions", 
       "dataSrc": "data"
    },
    "columns": [
        { "data": "last_name" },
        { "data": "first_name" },
        { "data": "email" },
        { "data": "phone" }
    ]
});

Ajax

{
"data":
    {
    "admins":
    [{
        "id":31,
        "email":"[email protected]",
        "last_login":"2015-07-27 09:50:50",
        "first_name":"Gary",
        "last_name":"Barlow",
        "roles":[{
            "id":1,"slug":"admin"
        }]
    }],

    "roles":
    [
        {"id":3,"slug":"admin","name":"Admin"},
        {"id":7,"slug":"accounts","name":"Accounts"}, 
        {"id":8,"slug":"sales","name":"Sales"},
        {"id":9,"slug":"superAdmin","name":"SuperAdmin"}
    ]
    }
}

The "admin" object encompasses all the admins that are passed through and their already assigned roles. These should appear as already ticked within the child-row. The "roles" object will contain all the current roles available to allow for assignment of additional roles. Basically, this identifies the number of checkboxes that need to appear.

I've abstracted out the rest as what's above pertains to the initialisation. Greatly appreciate any help.


Trying to use AJAX I'm getting nothing but "No data available in table" when if I type in the browser the route path I get the JSON object output.

I'm not sure how I should call the route.

url: '/user-permissions',
dataSrc: 'data.admins',
success: function (data) {
    console.log(data);
}

Will the above suffice? I don't really want to be calling the whole url. I even added a success function to try and get a console output of the data but still nothing.

2 Answers 2

3
  1. the correct dataSrc reference would be data.admins
  2. you miss a admins[].phone in the sample data?

As I understand you want to show a <select> populated with data.roles, showing the current data.admins[].roles[0].id?

You can do this by collecting data.roles in the dataSrc callback (or in a xhr.dt event) and use a render method for the role column :

<table class="table table-striped" id="admins_table" >
    <thead>
    <tr>
        <th>Last Name</th>
        <th>First Name</th>
        <th>Email</th>
        <th>Phone</th>
        <th>role</th>
    </tr>
    </thead>
</table>

js, only the important

var roles,
var oTable = $('#admins_table').dataTable( {
    "ajax": {
        "url": "http://example.app/user-permissions",  
        "dataSrc" : function(json) {
            roles = json.data.roles;
            return json.data.admins;
        }
    },
    "columns": [
        { "data": "last_name" },
        { "data": "first_name" },
        { "data": "email" },
        { "data": "phone" },
        { "data": "roles",
          "render": function(data, type, row) {
            var select = '<select>',
                role = data[0].id;
            for (var i=0;i<roles.length;i++) {
                select+='<option value="'+roles[i].id+'"';
                if (role == roles[i].id) select+=' selected';
                select+='>'+roles[i].name+'</option>';
            }
            select+='</select>';
            return select;
          }
       }
    ]
});

produces this table : enter image description here

with this data :

{ "data": {
    "admins": [{
        "id":31,
        "email":"[email protected]",
        "last_login":"2015-07-27 09:50:50",
        "first_name":"Gary",
        "last_name":"Barlow",
        "phone" : "123",
        "roles":[{
            "id":8,"slug":"sales"
        }]
    },{
        "id":32,
        "email":"[email protected]",
        "last_login":"2015-07-27 09:50:50",
        "first_name":"Bary",
        "last_name":"Garlow",
        "phone" : "321",
        "roles":[{
            "id":7,"slug":"accounts"
        }]
    }],
    "roles": [
        {"id":3,"slug":"admin","name":"Admin"},
        {"id":7,"slug":"accounts","name":"Accounts"}, 
        {"id":8,"slug":"sales","name":"Sales"},
        {"id":9,"slug":"superAdmin","name":"SuperAdmin"}
    ]
  }
}
Sign up to request clarification or add additional context in comments.

5 Comments

Hi @davidkonrad. Firstly, thanks for the reply! Yes I did miss the phone attribute in the sample data. My aim isn't actually to have a select box because that limits a user to one role, but instead have a child row which contains multiple checkboxes. The child row would be toggled via an icon to the far left of each row. Much like demo'd here. I'll have a go with your suggestion and see if it solves the table initialising.
I've added a paragraph after the Ajax section to better explain what the information is for.
@LukeVincent, should I try to make a small example? I can do that with child rows, but it is far better if you figure it out yourself. Happy to help.
I've figured out how to do the child rows bit I was just clarifying where you assumed I wanted select boxes. I've got everything displaying fine by passing the data through as a php object but as soon as I move to Ajax I just can't get it to initialise. If I type in the address /user-permissions I get the json object displayed in the browser but when I use it as the data source for the table I get the "No data available in table" - has me stumped.
When I say I can't get it to initialise, it is initialising because the "No data available in table" appears. So something is wrong with the Json being passed through or I'm not grabbing it correctly. Most examples I've seen use '/something.txt', I can't find anything that demonstrates with a Laravel route call.
1

It's been awhile now since I asked this question and I thought I'd clarify what I did to solve the problem. First I ensured all the data tables scripts were the latest versions, not sure if this was a problem but I was using some outdated stuff.

Within the tables initialisation the ajax call became simply:

ajax: "/user-permissions"

Most the hard work went into the controller function that was called by the above route:

public function grid()
{
    $admins = // get users with relevant roles e.g. ($user->load('roles'))

    return Datatables::of($admins)->make(true)
}

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.