Skip to content

Commit 4d051a8

Browse files
committed
feat: allow adding laravel view to layout
1 parent 1c8b2a0 commit 4d051a8

File tree

4 files changed

+145
-44
lines changed

4 files changed

+145
-44
lines changed

src/Html/Enums/LayoutPosition.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,25 @@
44

55
namespace Yajra\DataTables\Html\Enums;
66

7+
use Illuminate\Support\Str;
8+
79
enum LayoutPosition: string
810
{
9-
case Start = 'Start';
10-
case End = 'End';
11+
case Top = 'top';
12+
case TopStart = 'topStart';
13+
case TopEnd = 'topEnd';
14+
case Bottom = 'bottom';
15+
case BottomStart = 'bottomStart';
16+
case BottomEnd = 'bottomEnd';
17+
18+
public function withOrder(?int $order): string
19+
{
20+
if ($order && $order > 0) {
21+
$parts = Str::of($this->value)->ucsplit();
22+
23+
return $parts->shift().$order.$parts->first();
24+
}
25+
26+
return $this->value;
27+
}
1128
}

src/Html/Layout.php

Lines changed: 62 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@
44

55
namespace Yajra\DataTables\Html;
66

7+
use Illuminate\Contracts\Support\Renderable;
78
use Illuminate\Support\Fluent;
89
use Illuminate\Support\Traits\Macroable;
10+
use InvalidArgumentException;
11+
use Throwable;
912
use Yajra\DataTables\Html\Enums\LayoutPosition;
1013

1114
class Layout extends Fluent
@@ -17,79 +20,104 @@ public static function make(array $options = []): static
1720
return new static($options);
1821
}
1922

20-
public function topStart(string|array|null $options, int $order = 0): static
23+
public function top(array|string|null $options, ?int $order = null): static
2124
{
22-
return $this->top($options, $order, LayoutPosition::Start);
25+
$this->attributes[LayoutPosition::Top->withOrder($order)] = $options;
26+
27+
return $this;
2328
}
2429

25-
public function top(array|string|null $options, ?int $order = null, ?LayoutPosition $position = null): static
30+
public function topStart(string|array|null $options, ?int $order = null): static
2631
{
27-
if ($order > 0) {
28-
$this->attributes["top{$order}{$position?->value}"] = $options;
29-
} else {
30-
$this->attributes["top{$position?->value}"] = $options;
31-
}
32+
$this->attributes[LayoutPosition::TopStart->withOrder($order)] = $options;
3233

3334
return $this;
3435
}
3536

36-
public function topEnd(string|array|null $options, int $order = 0): static
37+
public function topEnd(string|array|null $options, ?int $order = null): static
3738
{
38-
return $this->top($options, $order, LayoutPosition::End);
39+
$this->attributes[LayoutPosition::TopEnd->withOrder($order)] = $options;
40+
41+
return $this;
3942
}
4043

41-
public function topEndView(string $selector, int $order = 0): static
44+
public function topView(string $selector, ?int $order = null): static
4245
{
43-
return $this->topView($selector, $order, LayoutPosition::End);
46+
return $this->top($this->renderCustomElement($selector), $order);
4447
}
4548

46-
public function topView(string $selector, int $order = 0, ?LayoutPosition $position = null): static
49+
public function topStartView(string $selector, ?int $order = null): static
4750
{
48-
$script = "function() { return $('{$selector}').html(); }";
51+
return $this->topStart($this->renderCustomElement($selector), $order);
52+
}
4953

50-
return $this->top($script, $order, $position);
54+
public function topEndView(string $selector, ?int $order = null): static
55+
{
56+
return $this->topEnd($this->renderCustomElement($selector), $order);
5157
}
5258

53-
public function bottomStartView(string $selector, int $order = 0): static
59+
public function bottom(array|string|null $options, ?int $order = null): static
5460
{
55-
return $this->bottomView($selector, $order, LayoutPosition::Start);
61+
$this->attributes[LayoutPosition::Bottom->withOrder($order)] = $options;
62+
63+
return $this;
5664
}
5765

58-
public function bottomView(string $selector, int $order = 0, ?LayoutPosition $position = null): static
66+
public function bottomStart(string|array|null $options, ?int $order = null): static
5967
{
60-
$script = "function() { return $('{$selector}').html(); }";
68+
$this->attributes[LayoutPosition::BottomStart->withOrder($order)] = $options;
6169

62-
return $this->bottom($script, $order, $position);
70+
return $this;
6371
}
6472

65-
public function bottom(array|string|null $options, ?int $order = null, ?LayoutPosition $position = null): static
73+
public function bottomEnd(string|array|null $options, ?int $order = null): static
6674
{
67-
if ($order > 0) {
68-
$this->attributes["bottom{$order}{$position?->value}"] = $options;
69-
} else {
70-
$this->attributes["bottom{$position?->value}"] = $options;
71-
}
75+
$this->attributes[LayoutPosition::BottomEnd->withOrder($order)] = $options;
7276

7377
return $this;
7478
}
7579

76-
public function bottomEndView(string $selector, int $order = 0): static
80+
public function bottomView(string $selector, ?int $order = null): static
7781
{
78-
return $this->bottomView($selector, $order, LayoutPosition::End);
82+
return $this->bottom($this->renderCustomElement($selector), $order);
7983
}
8084

81-
public function topStartView(string $selector, int $order = 0): static
85+
public function bottomStartView(string $selector, ?int $order = null): static
8286
{
83-
return $this->topView($selector, $order, LayoutPosition::Start);
87+
return $this->bottomStart($this->renderCustomElement($selector), $order);
8488
}
8589

86-
public function bottomStart(string|array|null $options, int $order = 0): static
90+
public function bottomEndView(string $selector, ?int $order = null): static
8791
{
88-
return $this->bottom($options, $order, LayoutPosition::Start);
92+
return $this->bottomEnd($this->renderCustomElement($selector), $order);
8993
}
9094

91-
public function bottomEnd(string|array|null $options, int $order = 0): static
95+
/**
96+
* @param Renderable|view-string $view
97+
*
98+
* @throws Throwable
99+
*/
100+
public function addView(
101+
Renderable|string $view,
102+
LayoutPosition $layoutPosition,
103+
?int $order = null
104+
): static {
105+
$html = $view instanceof Renderable ? $view->render() : view($view)->render();
106+
$element = json_encode($html);
107+
108+
if ($element === false) {
109+
throw new InvalidArgumentException("Cannot render view [$html] to json.");
110+
}
111+
112+
$this->attributes[$layoutPosition->withOrder($order)] = $this->renderCustomElement($element, false);
113+
114+
return $this;
115+
}
116+
117+
private function renderCustomElement(string $element, bool $asJsSelector = true): string
92118
{
93-
return $this->bottom($options, $order, LayoutPosition::End);
119+
$html = $asJsSelector ? "$('{$element}').html()" : $element;
120+
121+
return "function() { return $html; }";
94122
}
95123
}

tests/LayoutTest.php

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Yajra\DataTables\Html\Tests;
44

5+
use Illuminate\Support\Facades\View;
6+
use InvalidArgumentException;
57
use PHPUnit\Framework\Attributes\Test;
68
use Yajra\DataTables\Html\Builder;
79
use Yajra\DataTables\Html\Enums\LayoutPosition;
@@ -37,16 +39,16 @@ public function it_can_set_positions(): void
3739
$layout->bottom('test', 1);
3840
$this->assertEquals('test', $layout->get('bottom1'));
3941

40-
$layout->top('test', 1, LayoutPosition::Start);
42+
$layout->topStart('test', 1);
4143
$this->assertEquals('test', $layout->get('top1Start'));
4244

43-
$layout->bottom('test', 1, LayoutPosition::Start);
45+
$layout->bottomStart('test', 1);
4446
$this->assertEquals('test', $layout->get('bottom1Start'));
4547

46-
$layout->top('test', 1, LayoutPosition::End);
48+
$layout->topEnd('test', 1);
4749
$this->assertEquals('test', $layout->get('top1End'));
4850

49-
$layout->bottom('test', 1, LayoutPosition::End);
51+
$layout->bottomEnd('test', 1);
5052
$this->assertEquals('test', $layout->get('bottom1End'));
5153
}
5254

@@ -63,10 +65,10 @@ public function it_can_be_used_in_builder(): void
6365
$layout->bottomEnd('test');
6466
$layout->top('test', 1);
6567
$layout->bottom('test', 1);
66-
$layout->top('test', 1, LayoutPosition::Start);
67-
$layout->bottom('test', 1, LayoutPosition::Start);
68-
$layout->top('test', 1, LayoutPosition::End);
69-
$layout->bottom('test', 1, LayoutPosition::End);
68+
$layout->topStart('test', 1);
69+
$layout->bottomStart('test', 1);
70+
$layout->topEnd('test', 1);
71+
$layout->bottomEnd('test', 1);
7072
});
7173

7274
$this->assertArrayHasKey('layout', $builder->getAttributes());
@@ -179,4 +181,57 @@ public function it_can_accept_js_selector_for_layout_content(): void
179181
$builder->getAttributes()['layout']['bottomEnd']
180182
);
181183
}
184+
185+
#[Test]
186+
public function it_can_accept_view_instance_or_string_for_layout_content(): void
187+
{
188+
View::addLocation(__DIR__.'/TestBlade');
189+
190+
$builder = resolve(Builder::class);
191+
192+
$view = view('test-view');
193+
194+
$builder->layout(fn (Layout $layout) => $layout
195+
->addView(
196+
view: $view,
197+
layoutPosition: LayoutPosition::TopStart,
198+
order: 1
199+
)->addView(
200+
view: 'test-view',
201+
layoutPosition: LayoutPosition::BottomEnd,
202+
order: 2
203+
));
204+
205+
$this->assertArrayHasKey('layout', $builder->getAttributes());
206+
$this->assertArrayHasKey('top1Start', $builder->getAttributes()['layout']);
207+
$this->assertEquals(
208+
'function() { return '.json_encode($view->render()).'; }',
209+
$builder->getAttributes()['layout']['top1Start']
210+
);
211+
212+
$this->assertArrayHasKey('layout', $builder->getAttributes());
213+
$this->assertArrayHasKey('bottom2End', $builder->getAttributes()['layout']);
214+
$this->assertEquals(
215+
'function() { return '.json_encode($view->render()).'; }',
216+
$builder->getAttributes()['layout']['bottom2End']
217+
);
218+
}
219+
220+
#[Test]
221+
public function it_throws_an_exception_if_the_view_does_not_exist_when_adding_view(): void
222+
{
223+
$this->expectException(InvalidArgumentException::class);
224+
$this->expectExceptionMessage('View [non-existent-view] not found.');
225+
226+
$builder = resolve(Builder::class);
227+
$builder->layout(fn (Layout $layout) => $layout
228+
->addView(
229+
view: 'non-existent-view',
230+
layoutPosition: LayoutPosition::Top,
231+
)
232+
->addView(
233+
view: view('non-existent-view'),
234+
layoutPosition: LayoutPosition::Bottom,
235+
));
236+
}
182237
}

tests/TestBlade/test-view.blade.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<p>Test blade file</p>

0 commit comments

Comments
 (0)