Skip to content

Ajax

Ajax

The ajax option enables DataTables to load data from an HTTP endpoint, ideal for large datasets or server-side filtering.

Basic Usage

use Pentiminax\UX\DataTables\Model\DataTable;
$dataTable = new DataTable('products');
$dataTable->ajax(
url: '/api/users',
type: 'GET'
);

Ajax Parameters

ParameterTypeDescription
urlstringAPI endpoint URL
dataSrcstringJSON key containing row data (default: data)
typestringHTTP method: GET or POST

Expected JSON Response

Your endpoint should return JSON in this format:

Client-Side Processing

For client-side tables (all data loaded at once):

{
"data": [
{ "id": 1, "name": "Product A", "price": 10.50 },
{ "id": 2, "name": "Product B", "price": 20.00 }
]
}

Server-Side Processing

For server-side tables (paginated/filtered on server):

{
"draw": 1,
"recordsTotal": 1000,
"recordsFiltered": 150,
"data": [
{ "id": 1, "name": "Product A", "price": 10.50 },
{ "id": 2, "name": "Product B", "price": 20.00 }
]
}
FieldDescription
drawRequest sequence number (prevents out-of-order responses)
recordsTotalTotal records in the dataset
recordsFilteredRecords after filtering
dataArray of row objects

Mapping Columns to JSON Keys

TextColumn::new() automatically uses the column name as the data key:

// Automatically maps to JSON key "name"
TextColumn::new('name', 'Name');
// For nested data, use setData()
TextColumn::new('price', 'Price')
->setData('pricing.amount');

Symfony Controller Example

src/Controller/Api/ProductController.php
namespace App\Controller\Api;
use App\Repository\ProductRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Annotation\Route;
class ProductController extends AbstractController
{
#[Route('/api/products', name: 'api_products', methods: ['GET'])]
public function list(ProductRepository $repository): JsonResponse
{
$products = $repository->findAll();
$data = array_map(fn($p) => [
'id' => $p->getId(),
'name' => $p->getName(),
'price' => $p->getPrice(),
], $products);
return $this->json(['data' => $data]);
}
}

Server-Side Processing

For large datasets, enable server-side processing:

$dataTable = new DataTable('products');
$dataTable
->ajax('/api/products')
->serverSide(true)
->processing(true);

Your endpoint receives these query parameters:

ParameterDescription
drawRequest counter
startStarting row index
lengthNumber of rows to return
search[value]Global search term
order[0][column]Column index to sort by
order[0][dir]Sort direction (asc/desc)
columns[n][data]Column data source
columns[n][searchable]Whether column is searchable
columns[n][orderable]Whether column is orderable

Handling Server-Side Requests

use Symfony\Component\HttpFoundation\Request;
#[Route('/api/products', name: 'api_products', methods: ['GET', 'POST'])]
public function list(Request $request, ProductRepository $repository): JsonResponse
{
$draw = $request->query->getInt('draw', 1);
$start = $request->query->getInt('start', 0);
$length = $request->query->getInt('length', 10);
$searchValue = $request->query->all('search')['value'] ?? '';
// Get ordering
$orderColumn = $request->query->all('order')[0]['column'] ?? 0;
$orderDir = $request->query->all('order')[0]['dir'] ?? 'asc';
$columns = $request->query->all('columns');
$orderField = $columns[$orderColumn]['data'] ?? 'id';
// Query with pagination, search, and ordering
$qb = $repository->createQueryBuilder('p');
if ($searchValue) {
$qb->andWhere('p.name LIKE :search')
->setParameter('search', '%' . $searchValue . '%');
}
$qb->orderBy('p.' . $orderField, $orderDir);
// Get total and filtered counts
$totalCount = $repository->count([]);
$filteredCount = (clone $qb)->select('COUNT(p.id)')->getQuery()->getSingleScalarResult();
// Get paginated results
$products = $qb
->setFirstResult($start)
->setMaxResults($length)
->getQuery()
->getResult();
$data = array_map(fn($p) => [
'id' => $p->getId(),
'name' => $p->getName(),
'price' => $p->getPrice(),
], $products);
return $this->json([
'draw' => $draw,
'recordsTotal' => $totalCount,
'recordsFiltered' => $filteredCount,
'data' => $data,
]);
}

Error Handling

Return errors in JSON format:

{
"error": "An error occurred while loading the data."
}

DataTables will display this message to the user.