Skip to content

Commit 6e46b66

Browse files
authored
Merge pull request #3271 from ChaosPower/fix/3086-edit-index-column
fix: allow editing DT_RowIndex via editColumn
2 parents 4f308d0 + 51677f8 commit 6e46b66

File tree

5 files changed

+119
-5
lines changed

5 files changed

+119
-5
lines changed

.github/workflows/pint.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ jobs:
1616
steps:
1717
- uses: actions/checkout@v4
1818
with:
19-
ref: ${{ github.head_ref }}
19+
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
20+
ref: ${{ github.event.pull_request.head.sha || github.sha }}
2021

2122
- name: "laravel-pint"
2223
uses: aglipanci/laravel-pint-action@latest

src/CollectionDataTable.php

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Illuminate\Support\Collection;
1212
use Illuminate\Support\Facades\Config;
1313
use Illuminate\Support\Str;
14+
use Yajra\DataTables\Utilities\Helper;
1415

1516
class CollectionDataTable extends DataTableAbstract
1617
{
@@ -185,19 +186,41 @@ public function results(): Collection
185186
private function revertIndexColumn($mDataSupport): void
186187
{
187188
if ($this->columnDef['index']) {
188-
$indexColumn = Config::get('datatables.index_column', 'DT_RowIndex');
189+
$indexColumn = (string) Config::get('datatables.index_column', 'DT_RowIndex');
189190
/** @var int|string $index */
190191
$index = $mDataSupport ? $indexColumn : 0;
191192
$start = $this->request->start();
193+
$indexEdits = $mDataSupport ? $this->getIndexColumnEdits($indexColumn) : [];
192194

193-
$this->collection->transform(function ($data) use ($index, &$start) {
195+
$this->collection->transform(function ($data) use ($index, &$start, $mDataSupport, $indexColumn, $indexEdits) {
194196
$data[$index] = ++$start;
195197

198+
if ($mDataSupport && $indexEdits !== []) {
199+
foreach ($indexEdits as $content) {
200+
$data[$indexColumn] = Helper::compileContent($content, $data, $data);
201+
}
202+
}
203+
196204
return $data;
197205
});
198206
}
199207
}
200208

209+
/**
210+
* Get edit templates/callbacks registered for the index column.
211+
*/
212+
private function getIndexColumnEdits(string $indexColumn): array
213+
{
214+
$edits = [];
215+
foreach ($this->columnDef['edit'] ?? [] as $column) {
216+
if (($column['name'] ?? null) === $indexColumn) {
217+
$edits[] = $column['content'];
218+
}
219+
}
220+
221+
return $edits;
222+
}
223+
201224
/**
202225
* Define the offset of the first item of the collection with respect to
203226
* the FULL dataset the collection was sliced from. It effectively allows the

src/Processors/DataProcessor.php

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ class DataProcessor
4646

4747
protected bool $ignoreGetters = false;
4848

49+
protected string $indexColumn;
50+
4951
public function __construct(protected iterable $results, array $columnDef, protected array $templates, protected int $start = 0)
5052
{
5153
$this->appendColumns = $columnDef['append'] ?? [];
@@ -58,6 +60,7 @@ public function __construct(protected iterable $results, array $columnDef, prote
5860
$this->makeHidden = $columnDef['hidden'] ?? [];
5961
$this->makeVisible = $columnDef['visible'] ?? [];
6062
$this->ignoreGetters = $columnDef['ignore_getters'] ?? false;
63+
$this->indexColumn = (string) Config::get('datatables.index_column', 'DT_RowIndex');
6164
}
6265

6366
/**
@@ -68,7 +71,6 @@ public function __construct(protected iterable $results, array $columnDef, prote
6871
public function process($object = false): array
6972
{
7073
$this->output = [];
71-
$indexColumn = (string) Config::get('datatables.index_column', 'DT_RowIndex');
7274

7375
foreach ($this->results as $row) {
7476
$data = Helper::convertToArray($row, ['hidden' => $this->makeHidden, 'visible' => $this->makeVisible, 'ignore_getters' => $this->ignoreGetters]);
@@ -79,7 +81,8 @@ public function process($object = false): array
7981
$value = $this->removeExcessColumns($value);
8082

8183
if ($this->includeIndex) {
82-
$value[$indexColumn] = ++$this->start;
84+
$value[$this->indexColumn] = ++$this->start;
85+
$value = $this->editIndexColumn($value, $row);
8386
}
8487

8588
$this->output[] = $object ? $value : $this->flatten($value);
@@ -120,13 +123,38 @@ protected function addColumns(array $data, $row): array
120123
protected function editColumns(array $data, object|array $row): array
121124
{
122125
foreach ($this->editColumns as $value) {
126+
if ($this->includeIndex && $value['name'] === $this->indexColumn) {
127+
continue;
128+
}
129+
123130
$value['content'] = Helper::compileContent($value['content'], $data, $row);
124131
Arr::set($data, $value['name'], $value['content']);
125132
}
126133

127134
return $data;
128135
}
129136

137+
/**
138+
* Edit index column after it has been added to the row.
139+
*/
140+
protected function editIndexColumn(array $data, object|array $row): array
141+
{
142+
if (! $this->includeIndex) {
143+
return $data;
144+
}
145+
146+
foreach ($this->editColumns as $value) {
147+
if ($value['name'] !== $this->indexColumn) {
148+
continue;
149+
}
150+
151+
$value['content'] = Helper::compileContent($value['content'], $data, $row);
152+
Arr::set($data, $this->indexColumn, $value['content']);
153+
}
154+
155+
return $data;
156+
}
157+
130158
/**
131159
* Setup additional DT row variables.
132160
*/

tests/Integration/CollectionDataTableTest.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,41 @@ public function it_can_search_on_added_columns()
236236
], $response->getData(true));
237237
}
238238

239+
#[Test]
240+
public function it_can_edit_auto_index_column()
241+
{
242+
config()->set('app.debug', false);
243+
request()->merge([
244+
'columns' => [
245+
['data' => 'DT_RowIndex', 'name' => 'index', 'searchable' => 'false', 'orderable' => 'false'],
246+
['data' => 'id', 'name' => 'id', 'searchable' => 'false', 'orderable' => 'false'],
247+
['data' => 'name', 'name' => 'name', 'searchable' => 'true', 'orderable' => 'true'],
248+
],
249+
'order' => [['column' => 2, 'dir' => 'desc']],
250+
'start' => 0,
251+
'length' => 10,
252+
'draw' => 1,
253+
]);
254+
255+
$collection = collect([
256+
['id' => 1, 'name' => 'Alpha'],
257+
['id' => 2, 'name' => 'Beta'],
258+
]);
259+
260+
$dataTable = app('datatables')->collection($collection);
261+
/** @var JsonResponse $response */
262+
$response = $dataTable
263+
->addIndexColumn()
264+
->editColumn('DT_RowIndex', 'Row {{$DT_RowIndex}}')
265+
->toJson();
266+
267+
$json = $response->getData(true);
268+
269+
$this->assertSame('Beta', $json['data'][0]['name']);
270+
$this->assertSame('Row 1', $json['data'][0]['DT_RowIndex']);
271+
$this->assertSame('Row 2', $json['data'][1]['DT_RowIndex']);
272+
}
273+
239274
#[Test]
240275
public function it_accepts_array_data_source()
241276
{

tests/Integration/QueryDataTableTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,27 @@ public function it_can_return_auto_index_column()
282282
$this->assertArrayHasKey('DT_RowIndex', $crawler->json()['data'][0]);
283283
}
284284

285+
#[Test]
286+
public function it_can_edit_auto_index_column()
287+
{
288+
$crawler = $this->call('GET', '/query/indexColumn/edit', [
289+
'columns' => [
290+
['data' => 'DT_RowIndex', 'name' => 'index', 'searchable' => 'false', 'orderable' => 'false'],
291+
['data' => 'name', 'name' => 'name', 'searchable' => 'true', 'orderable' => 'true'],
292+
['data' => 'email', 'name' => 'email', 'searchable' => 'true', 'orderable' => 'true'],
293+
],
294+
'search' => ['value' => 'Record-19'],
295+
]);
296+
297+
$crawler->assertJson([
298+
'draw' => 0,
299+
'recordsTotal' => 20,
300+
'recordsFiltered' => 1,
301+
]);
302+
303+
$this->assertSame('<a href="/users/19">1</a>', $crawler->json()['data'][0]['DT_RowIndex']);
304+
}
305+
285306
#[Test]
286307
public function it_allows_search_on_added_column_with_custom_filter_handler()
287308
{
@@ -463,6 +484,12 @@ protected function setUp(): void
463484
->addIndexColumn()
464485
->toJson());
465486

487+
$router->get('/query/indexColumn/edit', fn (DataTables $dataTable) => $dataTable->query(DB::table('users'))
488+
->addIndexColumn()
489+
->editColumn('DT_RowIndex', '<a href="/users/{{$id}}">{{$DT_RowIndex}}</a>')
490+
->rawColumns(['DT_RowIndex'])
491+
->toJson());
492+
466493
$router->get('/query/filterColumn', fn (DataTables $dataTable) => $dataTable->query(DB::table('users'))
467494
->addColumn('foo', 'bar')
468495
->filterColumn('foo', function (Builder $builder, $keyword) {

0 commit comments

Comments
 (0)