Skip to content

Instantly share code, notes, and snippets.

@emsifa
Last active June 9, 2021 15:56
Show Gist options
  • Save emsifa/fe8208c15dbb843217a3 to your computer and use it in GitHub Desktop.
Save emsifa/fe8208c15dbb843217a3 to your computer and use it in GitHub Desktop.
DatatableTrait, simple datatable server side Laravel, no ribet...
<?php // ./app/Traits/Datatable.php
namespace App\Traits;
use Illuminate\Http\Request;
trait Datatable {
public static function datatable(Request $request, array $selects, array $columns_formatter, array $options = [])
{
$options = array_merge([
'searchables' => [],
'modifyQuery' => function($query) {
return $query;
},
], $options);
$page = (int) $request->get("draw", 1);
$count = (int) $request->get("length", 20);
$search = $request->get("search");
$offset = (int) $request->get("start", 0);
$columns = $request->get("columns");
$orders = $request->get("order");
$order_opt = $orders[0];
$order_col = $columns[(int) $order_opt['column']]['name'];
$order_asc = $order_opt['dir'];
$recordsTotal = $recordsFiltered = static::count();
$query = static::select($selects);
if(!empty($search['value']) AND is_array($options['searchables'])) {
if(!empty($options['searchables'])) {
$searchables = $options['searchables'];
} else {
$searchables = isset(static::$searchables)? static::$searchables : [];
}
foreach($searchables as $key => $format) {
$keyword = str_replace('{keyword}', $search['value'], $format);
$query->where($key, 'like', $keyword);
}
}
call_user_func($options['modifyQuery'], $query);
if($order_col) {
$query->orderBy($order_col, $order_asc);
}
$query->skip($offset)->take($count);
$collection = $query->get();
$datas = [];
foreach($collection as $i => $row) {
$data = [];
foreach($columns_formatter as $col) {
$data[] = static::columnValue($col, $row, $i);
}
$datas[] = $data;
}
return [
'draw' => $page,
'recordsTotal' => $recordsTotal,
'recordsFiltered' => $recordsFiltered,
'data' => $datas
];
}
protected static function columnValue($__template, &$row, $index)
{
if($__template instanceof \Closure) {
return call_user_func($__template, $row, $index);
} elseif(is_string($__template)) {
$__template = str_replace('{{', '<?php echo strip_tags(', $__template);
$__template = str_replace('{!!', '<? php echo (', $__template);
$__template = str_replace(['}}','!!}'], ');?>', $__template);
ob_start();
eval(' ?> '.$__template.' <?php ');
return ob_get_clean();
}
}
}
<?php namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ExampleController extends Controller {
public function datatableProducts(Request $request)
{
return Product::datatable($request, ['*'], [
'{{ $row->name }}',
'<span class="label label-info">{{ $row->category->name }}</span>',
'Rp. {{ number_format($row->price, 0) }}',
'{{ $row->published? "publish" : "draft" }}',
'<small>{{ $row->created_at->format("d M, Y") }}</small>',
'<a href="{{ route(\'page-edit-product\', [\'id\' => $row->id]) }}">edit</a>'
]);
}
}
<?php namespace App;
use App\Traits;
use Illuminate\Eloquent\Model;
// Model Product
class Product extends Model {
use Traits\Datatable;
protected $table = "products";
public function category()
{
return $this->hasOne('App\Category', 'id', 'id_category');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment