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

mfiazahmad's avatar

Sorting issue in jQuery dataTable which involves Laravel relationship

I have a main table called users which is connected to leads through one-to-one relationship.

I am fetching first_name, last_name, email from users table and response from leads table to display this data in a jQuery dataTable.

Now the issue is when I click on the first_name, last_name, email columns which exist in the main table, they sort but when I click on response, sorting fails by saying "status" column does not exist.

I know it does not exist on the main table but is in the leads table.

How can I make it work. Here is my code for jQuery dataTables:

	$data = [];
    $tableData = [];
    $offset = request()->get('start');
    $limit = request()->get('length');
    $draw = request()->get('draw');

    $search = request()->get('search');
    $searchValue = $search['value'];

    $order = request()->get('order');
    $columnOrderIndex = $order[0]['column'];
    $columnOrderDirection = $order[0]['dir'];

    $columns = request()->get('columns');
    $columnData = $columns[$columnOrderIndex]['data'];

    $users = User::query();
    $totalRecords = $users->count();

    if (!empty($searchValue)) {
        $users = $users->where('order_id', 'LIKE', '%' . $searchValue . '%')->orWhere('first_name', 'LIKE', '%' . $searchValue . '%')->orWhere('last_name', 'LIKE', '%' . $searchValue . '%')->orWhere('email', 'LIKE', '%' . $searchValue . '%');
    }

    if (request()->filled('order_status')) {
        $users = $users->whereHas('lead', function ($query) {
            $query->where('response', '=', request()->order_status);
        });
    }

    $totalFilteredRecords = $users->count();
    $usersData = $users->with('lead')->orderBy($columnData, $columnOrderDirection)->offset($offset)->limit($limit)->get();

    foreach ($usersData as $userData) {
        $tableData['order_id'] = $userData['order_id'];
        $tableData['first_name'] = $userData['first_name'];
        $tableData['last_name'] = $userData['last_name'];
        $tableData['email'] = $userData['email'];
        $tableData['response'] = $userData->lead->response ?? 'N/A';

        $data[] = $tableData;
    }

    return response()->json([
        'draw' => $draw,
        'recordsTotal' => $totalRecords,
        'recordsFiltered' => $totalFilteredRecords,
        'data' => $data,
    ]);
0 likes
3 replies
LaryAI's avatar
Level 58

To resolve the sorting issue with the status column that exists in the leads table, you need to ensure that the column is properly referenced in your query. Since the status column is part of the leads table, you need to join the leads table with the users table and then sort based on the status column.

Here's how you can modify your code to achieve this:

  1. Join the leads table with the users table.
  2. Update the sorting logic to handle the status column correctly.

Here's the updated code:

$data = [];
$tableData = [];
$offset = request()->get('start');
$limit = request()->get('length');
$draw = request()->get('draw');

$search = request()->get('search');
$searchValue = $search['value'];

$order = request()->get('order');
$columnOrderIndex = $order[0]['column'];
$columnOrderDirection = $order[0]['dir'];

$columns = request()->get('columns');
$columnData = $columns[$columnOrderIndex]['data'];

// Map the column data to the correct table columns
$columnData = $columnData == 'response' ? 'leads.response' : 'users.' . $columnData;

$users = User::query()
    ->leftJoin('leads', 'users.id', '=', 'leads.user_id')
    ->select('users.*', 'leads.response as response');

$totalRecords = $users->count();

if (!empty($searchValue)) {
    $users = $users->where(function($query) use ($searchValue) {
        $query->where('users.order_id', 'LIKE', '%' . $searchValue . '%')
              ->orWhere('users.first_name', 'LIKE', '%' . $searchValue . '%')
              ->orWhere('users.last_name', 'LIKE', '%' . $searchValue . '%')
              ->orWhere('users.email', 'LIKE', '%' . $searchValue . '%')
              ->orWhere('leads.response', 'LIKE', '%' . $searchValue . '%');
    });
}

if (request()->filled('order_status')) {
    $users = $users->where('leads.response', '=', request()->order_status);
}

$totalFilteredRecords = $users->count();
$usersData = $users->orderBy($columnData, $columnOrderDirection)
                   ->offset($offset)
                   ->limit($limit)
                   ->get();

foreach ($usersData as $userData) {
    $tableData['order_id'] = $userData['order_id'];
    $tableData['first_name'] = $userData['first_name'];
    $tableData['last_name'] = $userData['last_name'];
    $tableData['email'] = $userData['email'];
    $tableData['response'] = $userData->response ?? 'N/A';

    $data[] = $tableData;
}

return response()->json([
    'draw' => $draw,
    'recordsTotal' => $totalRecords,
    'recordsFiltered' => $totalFilteredRecords,
    'data' => $data,
]);

Explanation:

  1. Join the leads table: The leftJoin method is used to join the leads table with the users table on the user_id field.
  2. Select the necessary columns: The select method is used to select columns from both tables.
  3. Update the column mapping: The $columnData variable is updated to reference the correct table columns.
  4. Update the search logic: The search logic is updated to include the response column from the leads table.
  5. Update the sorting logic: The orderBy method is updated to sort based on the correct table columns.

This should resolve the sorting issue with the status column in your jQuery DataTable.

Please or to participate in this conversation.