1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Yajra\DataTables\Html; |
4
|
|
|
|
5
|
|
|
use Illuminate\Support\Arr; |
6
|
|
|
use Illuminate\Support\Str; |
7
|
|
|
use Illuminate\Support\Fluent; |
8
|
|
|
|
9
|
|
|
/** |
10
|
|
|
* @property string data |
11
|
|
|
* @property string name |
12
|
|
|
* @property string orderable |
13
|
|
|
* @property string searchable |
14
|
|
|
* @property string printable |
15
|
|
|
* @property string exportable |
16
|
|
|
* @property string footer |
17
|
|
|
* @property array attributes |
18
|
|
|
* @see https://datatables.net/reference/option/#columns |
19
|
|
|
*/ |
20
|
|
|
class Column extends Fluent |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* @param array $attributes |
24
|
|
|
*/ |
25
|
|
|
public function __construct($attributes = []) |
26
|
|
|
{ |
27
|
|
|
$attributes['title'] = isset($attributes['title']) ? $attributes['title'] : self::titleFormat($attributes['data']); |
28
|
|
|
$attributes['orderable'] = isset($attributes['orderable']) ? $attributes['orderable'] : true; |
29
|
|
|
$attributes['searchable'] = isset($attributes['searchable']) ? $attributes['searchable'] : true; |
30
|
|
|
$attributes['exportable'] = isset($attributes['exportable']) ? $attributes['exportable'] : true; |
31
|
|
|
$attributes['printable'] = isset($attributes['printable']) ? $attributes['printable'] : true; |
32
|
|
|
$attributes['footer'] = isset($attributes['footer']) ? $attributes['footer'] : ''; |
33
|
|
|
$attributes['attributes'] = isset($attributes['attributes']) ? $attributes['attributes'] : []; |
34
|
|
|
|
35
|
|
|
// Allow methods override attribute value |
36
|
|
|
foreach ($attributes as $attribute => $value) { |
37
|
|
|
$method = 'parse' . ucfirst(strtolower($attribute)); |
38
|
|
|
if (! is_null($value) && method_exists($this, $method)) { |
39
|
|
|
$attributes[$attribute] = $this->$method($value); |
40
|
|
|
} |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
if (! isset($attributes['name']) && isset($attributes['data'])) { |
44
|
|
|
$attributes['name'] = $attributes['data']; |
45
|
|
|
} |
46
|
|
|
|
47
|
|
|
parent::__construct($attributes); |
48
|
|
|
} |
49
|
|
|
|
50
|
|
|
/** |
51
|
|
|
* Format string to title case. |
52
|
|
|
* |
53
|
|
|
* @param string $value |
54
|
|
|
* @return string |
55
|
|
|
*/ |
56
|
|
|
public static function titleFormat($value) |
57
|
|
|
{ |
58
|
|
|
return Str::title(str_replace('_', ' ', $value)); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Create a computed column that is not searchable/orderable. |
63
|
|
|
* |
64
|
|
|
* @param string $data |
65
|
|
|
* @param string|null $title |
66
|
|
|
* @return Column |
67
|
|
|
*/ |
68
|
|
|
public static function computed($data, $title = null) |
69
|
|
|
{ |
70
|
|
|
if (is_null($title)) { |
71
|
|
|
$title = self::titleFormat($data); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
return static::make($data)->title($title)->orderable(false)->searchable(false); |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* Set column searchable flag. |
79
|
|
|
* |
80
|
|
|
* @param bool $flag |
81
|
|
|
* @return $this |
82
|
|
|
* @see https://datatables.net/reference/option/columns.searchable |
83
|
|
|
*/ |
84
|
|
|
public function searchable(bool $flag = true) |
85
|
|
|
{ |
86
|
|
|
$this->attributes['searchable'] = $flag; |
87
|
|
|
|
88
|
|
|
return $this; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* Set column orderable flag. |
93
|
|
|
* |
94
|
|
|
* @param bool $flag |
95
|
|
|
* @return $this |
96
|
|
|
* @see https://datatables.net/reference/option/columns.orderable |
97
|
|
|
*/ |
98
|
|
|
public function orderable(bool $flag = true) |
99
|
|
|
{ |
100
|
|
|
$this->attributes['orderable'] = $flag; |
101
|
|
|
|
102
|
|
|
return $this; |
103
|
|
|
} |
104
|
|
|
|
105
|
|
|
/** |
106
|
|
|
* Set column responsive priority. |
107
|
|
|
* |
108
|
|
|
* @param int|string $value |
109
|
|
|
* @return $this |
110
|
|
|
* @see https://datatables.net/reference/option/columns.responsivePriority |
111
|
|
|
*/ |
112
|
|
|
public function responsivePriority($value) |
113
|
|
|
{ |
114
|
|
|
$this->attributes['responsivePriority'] = $value; |
115
|
|
|
|
116
|
|
|
return $this; |
117
|
|
|
} |
118
|
|
|
|
119
|
|
|
/** |
120
|
|
|
* Set column title. |
121
|
|
|
* |
122
|
|
|
* @param string $value |
123
|
|
|
* @return $this |
124
|
|
|
* @see https://datatables.net/reference/option/columns.title |
125
|
|
|
*/ |
126
|
|
|
public function title($value) |
127
|
|
|
{ |
128
|
|
|
$this->attributes['title'] = $value; |
129
|
|
|
|
130
|
|
|
return $this; |
131
|
|
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* Make a new column instance. |
135
|
|
|
* |
136
|
|
|
* @param string $data |
137
|
|
|
* @param string $name |
138
|
|
|
* @return Column |
139
|
|
|
*/ |
140
|
|
|
public static function make($data, $name = '') |
141
|
|
|
{ |
142
|
|
|
$attr = [ |
143
|
|
|
'data' => $data, |
144
|
|
|
'name' => $name ?: $data, |
145
|
|
|
]; |
146
|
|
|
|
147
|
|
|
return new static($attr); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* Create a checkbox column. |
152
|
|
|
* |
153
|
|
|
* @param string $title |
154
|
|
|
* @return Column |
155
|
|
|
*/ |
156
|
|
|
public static function checkbox($title = '') |
157
|
|
|
{ |
158
|
|
|
return static::make('') |
159
|
|
|
->content('') |
160
|
|
|
->title($title) |
161
|
|
|
->className('select-checkbox') |
162
|
|
|
->orderable(false) |
163
|
|
|
->searchable(false); |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Set column class name. |
168
|
|
|
* |
169
|
|
|
* @param string $class |
170
|
|
|
* @return $this |
171
|
|
|
* @see https://datatables.net/reference/option/columns.className |
172
|
|
|
*/ |
173
|
|
|
public function className($class) |
174
|
|
|
{ |
175
|
|
|
$this->attributes['className'] = $class; |
176
|
|
|
|
177
|
|
|
return $this; |
178
|
|
|
} |
179
|
|
|
|
180
|
|
|
/** |
181
|
|
|
* Set column default content. |
182
|
|
|
* |
183
|
|
|
* @param string $value |
184
|
|
|
* @return $this |
185
|
|
|
* @see https://datatables.net/reference/option/columns.defaultContent |
186
|
|
|
*/ |
187
|
|
|
public function content($value) |
188
|
|
|
{ |
189
|
|
|
$this->attributes['defaultContent'] = $value; |
190
|
|
|
|
191
|
|
|
return $this; |
192
|
|
|
} |
193
|
|
|
|
194
|
|
|
/** |
195
|
|
|
* Set column visible flag. |
196
|
|
|
* |
197
|
|
|
* @param bool $flag |
198
|
|
|
* @return $this |
199
|
|
|
* @see https://datatables.net/reference/option/columns.visible |
200
|
|
|
*/ |
201
|
|
|
public function visible(bool $flag = true) |
202
|
|
|
{ |
203
|
|
|
$this->attributes['visible'] = $flag; |
204
|
|
|
|
205
|
|
|
return $this; |
206
|
|
|
} |
207
|
|
|
|
208
|
|
|
/** |
209
|
|
|
* Set column hidden state. |
210
|
|
|
* |
211
|
|
|
* @return $this |
212
|
|
|
* @see https://datatables.net/reference/option/columns.visible |
213
|
|
|
*/ |
214
|
|
|
public function hidden() |
215
|
|
|
{ |
216
|
|
|
return $this->visible(false); |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
/** |
220
|
|
|
* Append a class name to field. |
221
|
|
|
* |
222
|
|
|
* @param string $class |
223
|
|
|
* @return $this |
224
|
|
|
*/ |
225
|
|
View Code Duplication |
public function addClass($class) |
|
|
|
|
226
|
|
|
{ |
227
|
|
|
if (! isset($this->attributes['className'])) { |
228
|
|
|
$this->attributes['className'] = $class; |
229
|
|
|
} else { |
230
|
|
|
$this->attributes['className'] .= " $class"; |
231
|
|
|
} |
232
|
|
|
|
233
|
|
|
return $this; |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Set column exportable flag. |
238
|
|
|
* |
239
|
|
|
* @param bool $flag |
240
|
|
|
* @return $this |
241
|
|
|
*/ |
242
|
|
|
public function exportable(bool $flag = true) |
243
|
|
|
{ |
244
|
|
|
$this->attributes['exportable'] = $flag; |
245
|
|
|
|
246
|
|
|
return $this; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
/** |
250
|
|
|
* Set column printable flag. |
251
|
|
|
* |
252
|
|
|
* @param bool $flag |
253
|
|
|
* @return $this |
254
|
|
|
*/ |
255
|
|
|
public function printable(bool $flag = true) |
256
|
|
|
{ |
257
|
|
|
$this->attributes['printable'] = $flag; |
258
|
|
|
|
259
|
|
|
return $this; |
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
/** |
263
|
|
|
* Set column width value. |
264
|
|
|
* |
265
|
|
|
* @param int|string $value |
266
|
|
|
* @return $this |
267
|
|
|
* @see https://datatables.net/reference/option/columns.width |
268
|
|
|
*/ |
269
|
|
|
public function width($value) |
270
|
|
|
{ |
271
|
|
|
$this->attributes['width'] = $value; |
272
|
|
|
|
273
|
|
|
return $this; |
274
|
|
|
} |
275
|
|
|
|
276
|
|
|
/** |
277
|
|
|
* Set column data option value. |
278
|
|
|
* |
279
|
|
|
* @param string $value |
280
|
|
|
* @return $this |
281
|
|
|
* @see https://datatables.net/reference/option/columns.data |
282
|
|
|
*/ |
283
|
|
|
public function data($value) |
284
|
|
|
{ |
285
|
|
|
$this->attributes['data'] = $value; |
286
|
|
|
|
287
|
|
|
return $this; |
288
|
|
|
} |
289
|
|
|
|
290
|
|
|
/** |
291
|
|
|
* Set column name option value. |
292
|
|
|
* |
293
|
|
|
* @param string $value |
294
|
|
|
* @return $this |
295
|
|
|
* @see https://datatables.net/reference/option/columns.name |
296
|
|
|
*/ |
297
|
|
|
public function name($value) |
298
|
|
|
{ |
299
|
|
|
$this->attributes['name'] = $value; |
300
|
|
|
|
301
|
|
|
return $this; |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
/** |
305
|
|
|
* Set column edit field option value. |
306
|
|
|
* |
307
|
|
|
* @param string $value |
308
|
|
|
* @return $this |
309
|
|
|
* @see https://datatables.net/reference/option/columns.editField |
310
|
|
|
*/ |
311
|
|
|
public function editField($value) |
312
|
|
|
{ |
313
|
|
|
$this->attributes['editField'] = $value; |
314
|
|
|
|
315
|
|
|
return $this; |
316
|
|
|
} |
317
|
|
|
|
318
|
|
|
/** |
319
|
|
|
* Set column orderData option value. |
320
|
|
|
* |
321
|
|
|
* @param mixed $value |
322
|
|
|
* @return $this |
323
|
|
|
* @see https://datatables.net/reference/option/columns.orderData |
324
|
|
|
*/ |
325
|
|
|
public function orderData($value) |
326
|
|
|
{ |
327
|
|
|
$this->attributes['orderData'] = $value; |
328
|
|
|
|
329
|
|
|
return $this; |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
/** |
333
|
|
|
* Set column orderDataType option value. |
334
|
|
|
* |
335
|
|
|
* @param mixed $value |
336
|
|
|
* @return $this |
337
|
|
|
* @see https://datatables.net/reference/option/columns.orderDataType |
338
|
|
|
*/ |
339
|
|
|
public function orderDataType($value) |
340
|
|
|
{ |
341
|
|
|
$this->attributes['orderDataType'] = $value; |
342
|
|
|
|
343
|
|
|
return $this; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* Set column orderSequence option value. |
348
|
|
|
* |
349
|
|
|
* @param mixed $value |
350
|
|
|
* @return $this |
351
|
|
|
* @see https://datatables.net/reference/option/columns.orderSequence |
352
|
|
|
*/ |
353
|
|
|
public function orderSequence($value) |
354
|
|
|
{ |
355
|
|
|
$this->attributes['orderSequence'] = $value; |
356
|
|
|
|
357
|
|
|
return $this; |
358
|
|
|
} |
359
|
|
|
|
360
|
|
|
/** |
361
|
|
|
* Set column cellType option value. |
362
|
|
|
* |
363
|
|
|
* @param mixed $value |
364
|
|
|
* @return $this |
365
|
|
|
* @see https://datatables.net/reference/option/columns.cellType |
366
|
|
|
*/ |
367
|
|
|
public function cellType($value) |
368
|
|
|
{ |
369
|
|
|
$this->attributes['cellType'] = $value; |
370
|
|
|
|
371
|
|
|
return $this; |
372
|
|
|
} |
373
|
|
|
|
374
|
|
|
/** |
375
|
|
|
* Set column type option value. |
376
|
|
|
* |
377
|
|
|
* @param mixed $value |
378
|
|
|
* @return $this |
379
|
|
|
* @see https://datatables.net/reference/option/columns.type |
380
|
|
|
*/ |
381
|
|
|
public function type($value) |
382
|
|
|
{ |
383
|
|
|
$this->attributes['type'] = $value; |
384
|
|
|
|
385
|
|
|
return $this; |
386
|
|
|
} |
387
|
|
|
|
388
|
|
|
/** |
389
|
|
|
* Set column contentPadding option value. |
390
|
|
|
* |
391
|
|
|
* @param mixed $value |
392
|
|
|
* @return $this |
393
|
|
|
* @see https://datatables.net/reference/option/columns.contentPadding |
394
|
|
|
*/ |
395
|
|
|
public function contentPadding($value) |
396
|
|
|
{ |
397
|
|
|
$this->attributes['contentPadding'] = $value; |
398
|
|
|
|
399
|
|
|
return $this; |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
/** |
403
|
|
|
* Set column createdCell option value. |
404
|
|
|
* |
405
|
|
|
* @param mixed $value |
406
|
|
|
* @return $this |
407
|
|
|
* @see https://datatables.net/reference/option/columns.createdCell |
408
|
|
|
*/ |
409
|
|
|
public function createdCell($value) |
410
|
|
|
{ |
411
|
|
|
$this->attributes['createdCell'] = $value; |
412
|
|
|
|
413
|
|
|
return $this; |
414
|
|
|
} |
415
|
|
|
|
416
|
|
|
/** |
417
|
|
|
* Use the js renderer "$.fn.dataTable.render.". |
418
|
|
|
* |
419
|
|
|
* @param mixed $value |
420
|
|
|
* @param mixed ...$params |
421
|
|
|
* @return $this |
422
|
|
|
* @see https://datatables.net/reference/option/columns.render |
423
|
|
|
*/ |
424
|
|
|
public function renderJs($value, ...$params) |
425
|
|
|
{ |
426
|
|
|
if ($params) { |
|
|
|
|
427
|
|
|
$value .= '('; |
428
|
|
|
foreach ($params as $param) { |
429
|
|
|
$value .= "'{$param}',"; |
430
|
|
|
} |
431
|
|
|
$value = mb_substr($value, 0, -1); |
432
|
|
|
$value .= ')'; |
433
|
|
|
} |
434
|
|
|
|
435
|
|
|
$renderer = '$.fn.dataTable.render.' . $value; |
436
|
|
|
|
437
|
|
|
return $this->render($renderer); |
438
|
|
|
} |
439
|
|
|
|
440
|
|
|
/** |
441
|
|
|
* Set column renderer. |
442
|
|
|
* |
443
|
|
|
* @param mixed $value |
444
|
|
|
* @return $this |
445
|
|
|
* @see https://datatables.net/reference/option/columns.render |
446
|
|
|
*/ |
447
|
|
|
public function render($value) |
448
|
|
|
{ |
449
|
|
|
$this->attributes['render'] = $this->parseRender($value); |
450
|
|
|
|
451
|
|
|
return $this; |
452
|
|
|
} |
453
|
|
|
|
454
|
|
|
/** |
455
|
|
|
* Set column renderer with give raw value. |
456
|
|
|
* |
457
|
|
|
* @param mixed $value |
458
|
|
|
* @return $this |
459
|
|
|
* @see https://datatables.net/reference/option/columns.render |
460
|
|
|
*/ |
461
|
|
|
public function renderRaw($value) |
462
|
|
|
{ |
463
|
|
|
$this->attributes['render'] = $value; |
464
|
|
|
|
465
|
|
|
return $this; |
466
|
|
|
} |
467
|
|
|
|
468
|
|
|
/** |
469
|
|
|
* Parse render attribute. |
470
|
|
|
* |
471
|
|
|
* @param mixed $value |
472
|
|
|
* @return string|null |
473
|
|
|
*/ |
474
|
|
|
public function parseRender($value) |
475
|
|
|
{ |
476
|
|
|
/** @var \Illuminate\Contracts\View\Factory $view */ |
477
|
|
|
$view = app('view'); |
478
|
|
|
$parameters = []; |
479
|
|
|
|
480
|
|
|
if (is_array($value)) { |
481
|
|
|
$parameters = Arr::except($value, 0); |
482
|
|
|
$value = $value[0]; |
483
|
|
|
} |
484
|
|
|
|
485
|
|
|
if (is_callable($value)) { |
486
|
|
|
return $value($parameters); |
487
|
|
|
} elseif ($this->isBuiltInRenderFunction($value)) { |
488
|
|
|
return $value; |
489
|
|
|
} elseif ($view->exists($value)) { |
490
|
|
|
return $view->make($value)->with($parameters)->render(); |
491
|
|
|
} |
492
|
|
|
|
493
|
|
|
return $value ? $this->parseRenderAsString($value) : null; |
494
|
|
|
} |
495
|
|
|
|
496
|
|
|
/** |
497
|
|
|
* Check if given key & value is a valid datatables built-in renderer function. |
498
|
|
|
* |
499
|
|
|
* @param string $value |
500
|
|
|
* @return bool |
501
|
|
|
*/ |
502
|
|
|
private function isBuiltInRenderFunction($value) |
503
|
|
|
{ |
504
|
|
|
if (empty($value)) { |
505
|
|
|
return false; |
506
|
|
|
} |
507
|
|
|
|
508
|
|
|
return Str::startsWith(trim($value), ['$.fn.dataTable.render', '[']); |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
/** |
512
|
|
|
* Display render value as is. |
513
|
|
|
* |
514
|
|
|
* @param mixed $value |
515
|
|
|
* @return string |
516
|
|
|
*/ |
517
|
|
|
private function parseRenderAsString($value) |
518
|
|
|
{ |
519
|
|
|
return "function(data,type,full,meta){return $value;}"; |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
/** |
523
|
|
|
* Set column footer. |
524
|
|
|
* |
525
|
|
|
* @param mixed $value |
526
|
|
|
* @return $this |
527
|
|
|
*/ |
528
|
|
|
public function footer($value) |
529
|
|
|
{ |
530
|
|
|
$this->attributes['footer'] = $value; |
531
|
|
|
|
532
|
|
|
return $this; |
533
|
|
|
} |
534
|
|
|
|
535
|
|
|
/** |
536
|
|
|
* Set custom html title instead defult label. |
537
|
|
|
* |
538
|
|
|
* @param mixed $value |
539
|
|
|
* @return $this |
540
|
|
|
*/ |
541
|
|
|
public function titleAttr($value) |
542
|
|
|
{ |
543
|
|
|
$this->attributes['titleAttr'] = $value; |
544
|
|
|
|
545
|
|
|
return $this; |
546
|
|
|
} |
547
|
|
|
|
548
|
|
|
/** |
549
|
|
|
* @return array |
550
|
|
|
*/ |
551
|
|
|
public function toArray() |
552
|
|
|
{ |
553
|
|
|
return Arr::except($this->attributes, [ |
554
|
|
|
'printable', |
555
|
|
|
'exportable', |
556
|
|
|
'footer', |
557
|
|
|
]); |
558
|
|
|
} |
559
|
|
|
} |
560
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.