Overview

Namespaces

  • None
  • Yajra
    • Datatables
      • Contracts
      • Engines
      • Facades
      • Generators
      • Html
      • Processors
      • Services
      • Transformers

Classes

  • Yajra\Datatables\Datatables
  • Yajra\Datatables\DatatablesServiceProvider
  • Yajra\Datatables\Engines\BaseEngine
  • Yajra\Datatables\Engines\CollectionEngine
  • Yajra\Datatables\Engines\EloquentEngine
  • Yajra\Datatables\Engines\QueryBuilderEngine
  • Yajra\Datatables\Facades\Datatables
  • Yajra\Datatables\Generators\DataTablesMakeCommand
  • Yajra\Datatables\Generators\DataTablesScopeCommand
  • Yajra\Datatables\Helper
  • Yajra\Datatables\Html\Builder
  • Yajra\Datatables\Html\Column
  • Yajra\Datatables\Html\Parameters
  • Yajra\Datatables\Processors\DataProcessor
  • Yajra\Datatables\Processors\RowProcessor
  • Yajra\Datatables\Request
  • Yajra\Datatables\Services\DataTable
  • Yajra\Datatables\Transformers\DataTransformer

Interfaces

  • Yajra\Datatables\Contracts\DataTableButtonsContract
  • Yajra\Datatables\Contracts\DataTableContract
  • Yajra\Datatables\Contracts\DataTableEngineContract
  • Yajra\Datatables\Contracts\DataTableScopeContract

Functions

  • config_path
  • public_path
  • Overview
  • Namespace
  • Class
  1: <?php
  2: 
  3: namespace Yajra\Datatables\Html;
  4: 
  5: use Collective\Html\FormBuilder;
  6: use Collective\Html\HtmlBuilder;
  7: use Illuminate\Contracts\Config\Repository;
  8: use Illuminate\Contracts\View\Factory;
  9: use Illuminate\Routing\UrlGenerator;
 10: use Illuminate\Support\Collection;
 11: use Illuminate\Support\Facades\Config;
 12: use Illuminate\Support\Str;
 13: 
 14: /**
 15:  * Class Builder.
 16:  *
 17:  * @package Yajra\Datatables\Html
 18:  * @author  Arjay Angeles <aqangeles@gmail.com>
 19:  */
 20: class Builder
 21: {
 22:     /**
 23:      * @var Collection
 24:      */
 25:     public $collection;
 26: 
 27:     /**
 28:      * @var Repository
 29:      */
 30:     public $config;
 31: 
 32:     /**
 33:      * @var Factory
 34:      */
 35:     public $view;
 36: 
 37:     /**
 38:      * @var HtmlBuilder
 39:      */
 40:     public $html;
 41: 
 42:     /**
 43:      * @var UrlGenerator
 44:      */
 45:     public $url;
 46: 
 47:     /**
 48:      * @var FormBuilder
 49:      */
 50:     public $form;
 51: 
 52:     /**
 53:      * @var string|array
 54:      */
 55:     protected $ajax = '';
 56: 
 57:     /**
 58:      * @var array
 59:      */
 60:     protected $tableAttributes = ['class' => 'table', 'id' => 'dataTableBuilder'];
 61: 
 62:     /**
 63:      * @var string
 64:      */
 65:     protected $template = '';
 66: 
 67:     /**
 68:      * @var array
 69:      */
 70:     protected $attributes = [];
 71: 
 72:     /**
 73:      * Lists of valid DataTables Callbacks.
 74:      *
 75:      * @link https://datatables.net/reference/option/.
 76:      * @var array
 77:      */
 78:     protected $validCallbacks = [
 79:         'createdRow',
 80:         'drawCallback',
 81:         'footerCallback',
 82:         'formatNumber',
 83:         'headerCallback',
 84:         'infoCallback',
 85:         'initComplete',
 86:         'preDrawCallback',
 87:         'rowCallback',
 88:         'stateLoadCallback',
 89:         'stateLoaded',
 90:         'stateLoadParams',
 91:         'stateSaveCallback',
 92:         'stateSaveParams',
 93:     ];
 94: 
 95:     /**
 96:      * @param Repository $config
 97:      * @param Factory $view
 98:      * @param HtmlBuilder $html
 99:      * @param UrlGenerator $url
100:      * @param FormBuilder $form
101:      */
102:     public function __construct(
103:         Repository $config,
104:         Factory $view,
105:         HtmlBuilder $html,
106:         UrlGenerator $url,
107:         FormBuilder $form
108:     ) {
109:         $this->config     = $config;
110:         $this->view       = $view;
111:         $this->html       = $html;
112:         $this->url        = $url;
113:         $this->collection = new Collection;
114:         $this->form       = $form;
115:     }
116: 
117:     /**
118:      * Generate DataTable javascript.
119:      *
120:      * @param  null $script
121:      * @param  array $attributes
122:      * @return string
123:      */
124:     public function scripts($script = null, array $attributes = ['type' => 'text/javascript'])
125:     {
126:         $script = $script ?: $this->generateScripts();
127: 
128:         return '<script' . $this->html->attributes($attributes) . '>' . $script . '</script>' . PHP_EOL;
129:     }
130: 
131:     /**
132:      * Get generated raw scripts.
133:      *
134:      * @return string
135:      */
136:     public function generateScripts()
137:     {
138:         $args = array_merge(
139:             $this->attributes, [
140:                 'ajax'    => $this->ajax,
141:                 'columns' => $this->collection->toArray(),
142:             ]
143:         );
144: 
145:         $parameters = $this->parameterize($args);
146: 
147:         return sprintf(
148:             $this->template(),
149:             $this->tableAttributes['id'], $parameters
150:         );
151:     }
152: 
153:     /**
154:      * Generate DataTables js parameters.
155:      *
156:      * @param  array $attributes
157:      * @return string
158:      */
159:     public function parameterize($attributes = [])
160:     {
161:         $parameters = (new Parameters($attributes))->toArray();
162: 
163:         list($ajaxDataFunction, $parameters) = $this->encodeAjaxDataFunction($parameters);
164:         list($columnFunctions, $parameters) = $this->encodeColumnFunctions($parameters);
165:         list($callbackFunctions, $parameters) = $this->encodeCallbackFunctions($parameters);
166: 
167:         $json = json_encode($parameters);
168: 
169:         $json = $this->decodeAjaxDataFunction($ajaxDataFunction, $json);
170:         $json = $this->decodeColumnFunctions($columnFunctions, $json);
171:         $json = $this->decodeCallbackFunctions($callbackFunctions, $json);
172: 
173:         return $json;
174:     }
175: 
176:     /**
177:      * Encode ajax data function param.
178:      *
179:      * @param array $parameters
180:      * @return mixed
181:      */
182:     protected function encodeAjaxDataFunction($parameters)
183:     {
184:         $ajaxData = '';
185:         if (isset($parameters['ajax']['data'])) {
186:             $ajaxData                   = $parameters['ajax']['data'];
187:             $parameters['ajax']['data'] = "#ajax_data#";
188:         }
189: 
190:         return [$ajaxData, $parameters];
191:     }
192: 
193:     /**
194:      * Encode columns render function.
195:      *
196:      * @param array $parameters
197:      * @return array
198:      */
199:     protected function encodeColumnFunctions(array $parameters)
200:     {
201:         $columnFunctions = [];
202:         foreach ($parameters['columns'] as $i => $column) {
203:             unset($parameters['columns'][$i]['exportable']);
204:             unset($parameters['columns'][$i]['printable']);
205:             unset($parameters['columns'][$i]['footer']);
206: 
207:             if (isset($column['render'])) {
208:                 $columnFunctions[$i]                 = $column['render'];
209:                 $parameters['columns'][$i]['render'] = "#column_function.{$i}#";
210:             }
211:         }
212: 
213:         return [$columnFunctions, $parameters];
214:     }
215: 
216:     /**
217:      * Encode DataTables callbacks function.
218:      *
219:      * @param array $parameters
220:      * @return array
221:      */
222:     protected function encodeCallbackFunctions(array $parameters)
223:     {
224:         $callbackFunctions = [];
225:         foreach ($parameters as $key => $callback) {
226:             if (in_array($key, $this->validCallbacks)) {
227:                 $callbackFunctions[$key] = $this->compileCallback($callback);
228:                 $parameters[$key]        = "#callback_function.{$key}#";
229:             }
230:         }
231: 
232:         return [$callbackFunctions, $parameters];
233:     }
234: 
235:     /**
236:      * Compile DataTable callback value.
237:      *
238:      * @param mixed $callback
239:      * @return mixed|string
240:      */
241:     private function compileCallback($callback)
242:     {
243:         if (is_callable($callback)) {
244:             return value($callback);
245:         } elseif ($this->view->exists($callback)) {
246:             return $this->view->make($callback)->render();
247:         }
248: 
249:         return $callback;
250:     }
251: 
252:     /**
253:      * Decode ajax data method.
254:      *
255:      * @param string $function
256:      * @param string $json
257:      * @return string
258:      */
259:     protected function decodeAjaxDataFunction($function, $json)
260:     {
261:         return str_replace("\"#ajax_data#\"", $function, $json);
262:     }
263: 
264:     /**
265:      * Decode columns render functions.
266:      *
267:      * @param array $columnFunctions
268:      * @param string $json
269:      * @return string
270:      */
271:     protected function decodeColumnFunctions(array $columnFunctions, $json)
272:     {
273:         foreach ($columnFunctions as $i => $function) {
274:             $json = str_replace("\"#column_function.{$i}#\"", $function, $json);
275:         }
276: 
277:         return $json;
278:     }
279: 
280:     /**
281:      * Decode DataTables callbacks function.
282:      *
283:      * @param array $callbackFunctions
284:      * @param string $json
285:      * @return string
286:      */
287:     protected function decodeCallbackFunctions(array $callbackFunctions, $json)
288:     {
289:         foreach ($callbackFunctions as $i => $function) {
290:             $json = str_replace("\"#callback_function.{$i}#\"", $function, $json);
291:         }
292: 
293:         return $json;
294:     }
295: 
296:     /**
297:      * Get javascript template to use.
298:      *
299:      * @return string
300:      */
301:     protected function template()
302:     {
303:         return $this->view->make(
304:             $this->template ?: $this->config->get('datatables.script_template', 'datatables::script')
305:         )->render();
306:     }
307: 
308:     /**
309:      * Sets HTML table attribute(s).
310:      *
311:      * @param string|array $attribute
312:      * @param mixed $value
313:      * @return $this
314:      */
315:     public function setTableAttribute($attribute, $value = null)
316:     {
317:         if (is_array($attribute)) {
318:             $this->setTableAttributes($attribute);
319:         } else {
320:             $this->tableAttributes[$attribute] = $value;
321:         }
322: 
323:         return $this;
324:     }
325: 
326:     /**
327:      * Sets multiple HTML table attributes at once.
328:      *
329:      * @param array $attributes
330:      * @return $this
331:      */
332:     public function setTableAttributes(array $attributes)
333:     {
334:         foreach ($attributes as $attribute => $value) {
335:             $this->setTableAttribute($attribute, $value);
336:         }
337: 
338:         return $this;
339:     }
340: 
341:     /**
342:      * Retrieves HTML table attribute value.
343:      *
344:      * @param string $attribute
345:      * @return mixed
346:      * @throws \Exception
347:      */
348:     public function getTableAttribute($attribute)
349:     {
350:         if (! array_key_exists($attribute, $this->tableAttributes)) {
351:             throw new \Exception("Table attribute '{$attribute}' does not exist.");
352:         }
353: 
354:         return $this->tableAttributes[$attribute];
355:     }
356: 
357:     /**
358:      * Add a column in collection using attributes.
359:      *
360:      * @param  array $attributes
361:      * @return $this
362:      */
363:     public function addColumn(array $attributes)
364:     {
365:         $this->collection->push(new Column($attributes));
366: 
367:         return $this;
368:     }
369: 
370:     /**
371:      * Add a Column object in collection.
372:      *
373:      * @param \Yajra\Datatables\Html\Column $column
374:      * @return $this
375:      */
376:     public function add(Column $column)
377:     {
378:         $this->collection->push($column);
379: 
380:         return $this;
381:     }
382: 
383:     /**
384:      * Set datatables columns from array definition.
385:      *
386:      * @param array $columns
387:      * @return $this
388:      */
389:     public function columns(array $columns)
390:     {
391:         foreach ($columns as $key => $value) {
392:             if (! is_a($value, Column::class)) {
393:                 if (is_array($value)) {
394:                     $attributes = array_merge(['name' => $key, 'data' => $key], $this->setTitle($key, $value));
395:                 } else {
396:                     $attributes = [
397:                         'name'  => $value,
398:                         'data'  => $value,
399:                         'title' => $this->getQualifiedTitle($value),
400:                     ];
401:                 }
402: 
403:                 $this->collection->push(new Column($attributes));
404:             } else {
405:                 $this->collection->push($value);
406:             }
407:         }
408: 
409:         return $this;
410:     }
411: 
412:     /**
413:      * Set title attribute of an array if not set.
414:      *
415:      * @param string $title
416:      * @param array $attributes
417:      * @return array
418:      */
419:     public function setTitle($title, array $attributes)
420:     {
421:         if (! isset($attributes['title'])) {
422:             $attributes['title'] = $this->getQualifiedTitle($title);
423:         }
424: 
425:         return $attributes;
426:     }
427: 
428:     /**
429:      * Convert string into a readable title.
430:      *
431:      * @param string $title
432:      * @return string
433:      */
434:     public function getQualifiedTitle($title)
435:     {
436:         return Str::title(str_replace(['.', '_'], ' ', Str::snake($title)));
437:     }
438: 
439:     /**
440:      * Add a checkbox column.
441:      *
442:      * @param  array $attributes
443:      * @return $this
444:      */
445:     public function addCheckbox(array $attributes = [])
446:     {
447:         $attributes = array_merge([
448:             'defaultContent' => '<input type="checkbox" ' . $this->html->attributes($attributes) . '/>',
449:             'title'          => $this->form->checkbox('', '', false, ['id' => 'dataTablesCheckbox']),
450:             'data'           => 'checkbox',
451:             'name'           => 'checkbox',
452:             'orderable'      => false,
453:             'searchable'     => false,
454:             'exportable'     => false,
455:             'printable'      => true,
456:             'width'          => '10px',
457:         ], $attributes);
458:         $this->collection->push(new Column($attributes));
459: 
460:         return $this;
461:     }
462: 
463:     /**
464:      * Add a action column.
465:      *
466:      * @param  array $attributes
467:      * @return $this
468:      */
469:     public function addAction(array $attributes = [])
470:     {
471:         $attributes = array_merge([
472:             'defaultContent' => '',
473:             'data'           => 'action',
474:             'name'           => 'action',
475:             'title'          => 'Action',
476:             'render'         => null,
477:             'orderable'      => false,
478:             'searchable'     => false,
479:             'exportable'     => false,
480:             'printable'      => true,
481:             'footer'         => '',
482:         ], $attributes);
483:         $this->collection->push(new Column($attributes));
484: 
485:         return $this;
486:     }
487: 
488:     /**
489:      * Add a index column.
490:      *
491:      * @param  array $attributes
492:      * @return $this
493:      */
494:     public function addIndex(array $attributes = [])
495:     {
496:         $indexColumn = Config::get('datatables.index_column', 'DT_Row_Index');
497:         $attributes  = array_merge([
498:             'defaultContent' => '',
499:             'data'           => $indexColumn,
500:             'name'           => $indexColumn,
501:             'title'          => '',
502:             'render'         => null,
503:             'orderable'      => false,
504:             'searchable'     => false,
505:             'exportable'     => false,
506:             'printable'      => true,
507:             'footer'         => '',
508:         ], $attributes);
509:         $this->collection->push(new Column($attributes));
510: 
511:         return $this;
512:     }
513: 
514:     /**
515:      * Setup ajax parameter
516:      *
517:      * @param  string|array $attributes
518:      * @return $this
519:      */
520:     public function ajax($attributes)
521:     {
522:         $this->ajax = $attributes;
523: 
524:         return $this;
525:     }
526: 
527:     /**
528:      * Generate DataTable's table html.
529:      *
530:      * @param array $attributes
531:      * @param bool $drawFooter
532:      * @return string
533:      */
534:     public function table(array $attributes = [], $drawFooter = false)
535:     {
536:         $this->tableAttributes = array_merge($this->tableAttributes, $attributes);
537: 
538:         $th       = $this->compileTableHeaders();
539:         $htmlAttr = $this->html->attributes($this->tableAttributes);
540: 
541:         $tableHtml = '<table ' . $htmlAttr . '>';
542:         $tableHtml .= '<thead><tr>' . implode('', $th) . '</tr></thead>';
543:         if ($drawFooter) {
544:             $tf = $this->compileTableFooter();
545:             $tableHtml .= '<tfoot><tr>' . implode('', $tf) . '</tr></tfoot>';
546:         }
547:         $tableHtml .= '</table>';
548: 
549:         return $tableHtml;
550:     }
551: 
552:     /**
553:      * Compile table headers and to support responsive extension.
554:      *
555:      * @return array
556:      */
557:     private function compileTableHeaders()
558:     {
559:         $th = [];
560:         foreach ($this->collection->toArray() as $row) {
561:             $thAttr = $this->html->attributes(
562:                 array_only($row, ['class', 'id', 'width', 'style', 'data-class', 'data-hide'])
563:             );
564:             $th[]   = '<th ' . $thAttr . '>' . $row['title'] . '</th>';
565:         }
566: 
567:         return $th;
568:     }
569: 
570:     /**
571:      * Compile table footer contents.
572:      *
573:      * @return array
574:      */
575:     private function compileTableFooter()
576:     {
577:         $footer = [];
578:         foreach ($this->collection->toArray() as $row) {
579:             $footer[] = '<th>' . $row['footer'] . '</th>';
580:         }
581: 
582:         return $footer;
583:     }
584: 
585:     /**
586:      * Configure DataTable's parameters.
587:      *
588:      * @param  array $attributes
589:      * @return $this
590:      */
591:     public function parameters(array $attributes = [])
592:     {
593:         $this->attributes = array_merge($this->attributes, $attributes);
594: 
595:         return $this;
596:     }
597: 
598:     /**
599:      * Set custom javascript template.
600:      *
601:      * @param string $template
602:      * @return $this
603:      */
604:     public function setTemplate($template)
605:     {
606:         $this->template = $template;
607: 
608:         return $this;
609:     }
610: 
611:     /**
612:      * Get collection of columns.
613:      *
614:      * @return Collection
615:      */
616:     public function getColumns()
617:     {
618:         return $this->collection;
619:     }
620: }
621: 
API documentation generated by ApiGen