My symfony project needed to load a DataTables table from an ajax call. I found a few implementations on the interwebs but they didn't work for me:
- the table contained data joined from multiple tables
- the various query builders relied on doctrine DQL, which is sometimes tough to follow
After some brief hacking, I came up with a simple data table query sql query builder, which lets me get the data in a reasonably concise way that I could follow:
This class takes a base query in plain sql (provided by a Repository), and adds the necessary filtering and sorting as passed by the datatables ajax call. The file is given below, and a simple set of unit tests to show how the class modifies the base query according to the parameters.
The twig template (example below) sets up datatables as expected, and passes the SQL column names in the columnDefs
The controller method is quite brief:
#[Route('/datatables', name: 'app_term_datatables', methods: ['POST'])]
public function datatables_source(Request $request, TermRepository $repo): JsonResponse
{
$parameters = $request->request->all();
$data = $repo->getDataTablesList($parameters);
$data["draw"] = $parameters['draw'];
return $this->json($data);
}
The repo has a method that contains the "base query" that is used by DataTablesMySqlQuery
:
/** Returns data for ajax paging. */
public function getDataTablesList($parameters) {
$base_sql = "SELECT
fieldA, fieldB, fieldC, etc etc etc ... etc.
";
$conn = $this->getEntityManager()->getConnection();
return DataTablesMySqlQuery::getData($base_sql, $parameters, $conn);
}
The base_sql can be as complicated as you need. The DataTablesMySqlQuery
uses this to create and execute sql that returns:
- the total count of objects
- the count of filtered objects
- the subset of records that should be rendered
- DataTablesMySqlQuery.php - the magic file
- DataTablesMySqlQuery_Test.php - some phpunit tests to show how queries are built
- index.html.twig - a twig file from my project showing the datatables config, just for kicks.
Cheers! jz
Update: it turns out that the above doesn't work if the base sql has a WHERE in it already. The updated code is at https://github.com/jzohrab/lwt/blob/master/src/Repository/DataTablesMySqlQuery.php. Cheers, z