Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

lat4732's avatar
Level 12

Make datatable sortBy work

Hello everyone!

viz1

I'm using datatables in my administration panel but I realized that the sort functionality is not working properly. The specific table that we're talking about is with server-side rendering. The specific column "Status" that we're talking about has the following contents

if($record->claimed == 1) {
     $claimed = '<span class="badge badge-primary">CLAIMED</span>';
 } else {
     $claimed = '<span class="badge badge-secondary">NOT CLAIMED</span>';
 }

How can I make this sort work properly? I tried this

if($record->claimed == 1) {
     $claimed = '<span class="d-none">1</span><span class="badge badge-primary">CLAIMED</span>';
 } else {
     $claimed = '<span class="d-none">0</span><span class="badge badge-secondary">NOT CLAIMED</span>';
 }

but it doesn't work as expected. Maybe some kind of a data-sort attribute or....? Any ideas?

0 likes
9 replies
lat4732's avatar
Level 12

@cschoenmakers That's not the way. It's a server-side processing and I'm pretty sure I need to do that inside the controller. Here's my method for this specific datatable

public function datatableWebsites(Request $request) {
    $draw = $request->get('draw');
    $start = $request->get("start");
    $rowperpage = $request->get("length");
    $columnIndex_arr = $request->get('order');
    $columnName_arr = $request->get('columns');
    $order_arr = $request->get('order');
    $search_arr = $request->get('search');
    $columnIndex = $columnIndex_arr[0]['column'];
    $columnName = $columnName_arr[$columnIndex]['data'];
    $columnSortOrder = $order_arr[0]['dir'];
    $searchValue = $search_arr['value'];

    $totalRecords = DB::table('websites')->select('count(*) as allcount')->count();
    $totalRecordswithFilter = DB::table('websites')->select('count(*) as allcount')->where('websites.*', 'like', '%' .$searchValue . '%')->count();  
    
    
    $sorts = ['id', 'claimed', 'web_category'];

    $records = DB::table('websites')
        ->orderBy($sorts[$order_arr[0]['column']] ?? 'created_at', $order_arr[0]['dir'] ?? 'desc')
        ->leftJoin('categories', 'categories.id', '=', 'websites.web_category')
        ->where('websites.*', 'like', '%' .$searchValue . '%')
        ->selectRaw('websites.*, categories.name as category_name')
        ->groupBy('websites.id', 'categories.name')
        ->skip($start)
        ->take($rowperpage)
        ->get();

    $data_arr = array();

    $sno = $start+1;
    
    foreach($records as $record){

        $id = $record->id;
        $img = '<a href="' . cdnplus_url($record->logo_path) . '?time=' . time() . '"><img src="' . cdnplus_url($record->logo_path) . '?time=' . time() . '" width="50" height="50" class="border" onerror="this.onerror=null; this.src=\'' . cdnplus_url('business_assets/img/no-image.webp') . '\'" /></a>';
        $web_name = $record->web_name;
        if($record->claimed == 1) {
            $claimed = '<span data-sort="' . $record->claimed . '" class="badge badge-primary">CLAIMED</span>';
        } else {
            $claimed = '<span data-sort="' . $record->claimed . '" class="badge badge-secondary">NOT CLAIMED</span>';
        }
        $web_link = $record->web_link;
        $created_at = \Carbon\Carbon::parse($record->created_at)->diffForHumans();
        $category = $record->category_name . " (" . $record->web_category . ")";
        $btn = '<td class="align-middle text-center">
                    <a href="' . url('administrator/inspect/website/' . $record->id) . '">
                        <button type="button" class="btn btn-secondary btn-flat"><i class="fa fa-search"></i></button>
                    </a>
                </td>';

        $data_arr[] = array(

            $id,
            $img,
            $web_name,
            $claimed,
            $web_link,
            $created_at,
            $category,
            $btn

        );

    }

    return response()->json([
        "draw" => intval($draw),
        "recordsTotal" => $totalRecords,
        "recordsFiltered" => $totalRecordswithFilter,
        "data" => $data_arr
    ]);


}
Tray2's avatar

Or do it inside the database, which is the best option.

dysentry30's avatar

You can try this, if you want to sortBy in your controller

$records = DB::table('websites')
        ->orderBy($sorts[$order_arr[0]['column']] ?? 'created_at', $order_arr[0]['dir'] ?? 'desc')
        ->leftJoin('categories', 'categories.id', '=', 'websites.web_category')
        ->where('websites.*', 'like', '%' .$searchValue . '%')
        ->selectRaw('websites.*, categories.name as category_name')
        ->groupBy('websites.id', 'categories.name')
        ->skip($start)
        ->take($rowperpage)
        ->get()->soryBy("claimed")->values();
lat4732's avatar
Level 12

@dysentry30

DataTables warning: table id=websitesTable - Ajax error. For more information about this error, please see http://datatables.net/tn/7
dysentry30's avatar

Can you share your network inspect? So others can see it

lat4732's avatar
Level 12

@dysentry30 But adding ->sortBy("claimed") is not what I actually need. It will sort by claimed always and that's not what I want. I want it to be dynamically based on which column the administrator has clicked. As you can see the results can be sorted by id (asc/desc), status (asc/desc) and category id (asc/desc)

viz1

Please or to participate in this conversation.