Skip to content

Commit

Permalink
Mark modal controller as lazy, add modal action docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Kreyu committed Jan 18, 2025
1 parent ef95ee2 commit 445e4c9
Show file tree
Hide file tree
Showing 5 changed files with 214 additions and 3 deletions.
3 changes: 2 additions & 1 deletion assets/controllers/bootstrap/modal.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Controller } from '@hotwired/stimulus';
import { Modal } from 'bootstrap'; // Import Bootstrap
import { Modal } from 'bootstrap';

/* stimulusFetch: 'lazy' */
export default class extends Controller {
static targets = ['modal'];

Expand Down
1 change: 1 addition & 0 deletions docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ export default defineConfig({
{ text: 'Link', link: '/reference/types/action/link' },
{ text: 'Button', link: '/reference/types/action/button' },
{ text: 'Form', link: '/reference/types/action/form' },
{ text: 'Modal', link: '/reference/types/action/modal' },
{
text: 'Dropdown', link: '/reference/types/action/dropdown',
items: [
Expand Down
74 changes: 73 additions & 1 deletion docs/src/docs/components/actions.md
Original file line number Diff line number Diff line change
Expand Up @@ -599,4 +599,76 @@ $builder
> [!TIP]
> Although any action type can be used, rendering forms and buttons inside a dropdown may look weird.
> Therefore, it is recommended to use [`LinkDropdownItemActionType`](../../reference/types/action/link-dropdown-item.md) for dropdown items,
> so it will be rendered properly as a simple link.
> so it will be rendered properly as a simple link.
## Modal actions

You can define an action to open a modal with contents loaded from given URL.
For example, let's define a modal that displays a post details.

First things first, the built-in modal action type requires additional JavaScript to work properly.
If using the built-in Bootstrap 5 or Tabler (based on Bootstrap) theme, we have to enable the `bootstrap-modal`
script in your `controllers.json` file, because **it is disabled by default**:

```json
{
"controllers": {
"@kreyu/data-table-bundle": {
"bootstrap-modal": {
"enabled": true
}
}
}
}
```

Then, simply add a row action using the `ModalActionType`:

```php
use Kreyu\Bundle\DataTableBundle\Action\Type\ModalActionType;

$builder
->addRowAction('details', ModalActionType::class, [
'route' => 'post_details_modal',
'route_params' => fn (Post $post) => [
'id' => $post->getId(),
],
// You can generate the URL by yourself with "href" option
// instead of using "route" and "route_params":
//
// 'href' => function (Post $post) {
// return $this->urlGenerator->generate('post_details_modal', [
// 'id' => $post->getId(),
// ]);
// },
])
;
```

Now, make sure the `post_details_modal` route is defined in a controller:

```php
#[Route('/posts/{id}/details', name: 'post_details_modal')]
public function details(Post $post): Response
{
return $this->render('posts/details_modal.html.twig', [
'post' => $post,
]);
}
```

Inside the template, we can render the modal however we want:

```twig
{# templates/posts/details_modal.html.twig #}
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<h5 class="modal-title">{{ post.title }}</h5>
<p>{{ post.content }}</p>
</div>
</div>
</div>
```

For more details, see the [`ModalActionType`](../../reference/types/action/modal.md) reference page.
2 changes: 1 addition & 1 deletion docs/src/reference/types/action/dropdown.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

# DropdownActionType

The [`DropdownActionType`](https://github.com/Kreyu/data-table-bundle/blob/main/src/Action/Type/DropdownActionType.php) represents an action rendered as a dropdown, where each item corresponds to separate action.
The [`DropdownActionType`](https://github.com/Kreyu/data-table-bundle/blob/main/src/Action/Type/Dropdown/DropdownActionType.php) represents an action rendered as a dropdown, where each item corresponds to separate action.

## Options

Expand Down
137 changes: 137 additions & 0 deletions docs/src/reference/types/action/modal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
<script setup>
import ActionTypeOptions from "./options/action.md";
</script>

# ModalActionType

The [`ModalActionType`](https://github.com/Kreyu/data-table-bundle/blob/main/src/Action/Type/ModalActionType.php) represents an action
that opens a modal dialog with contents loaded from given URL.

> [!WARNING]
> This action type requires additional JavaScript to work properly. If using the built-in Bootstrap 5 or Tabler (based on Bootstrap) theme,
> enable the `bootstrap-modal` script in your `controllers.json` file, because **it is disabled by default**.
>
> ```json
> {
> "controllers": {
> "@kreyu/data-table-bundle": {
> "bootstrap-modal": {
> "enabled": true
> }
> }
> }
> }
> ```
## Options
### `href`
- **type**: `null`, `string` or `callable` (if using as a row action)
- **default**: `null`
A URL to load the modal contents from. Can be used instead of [`route`](#route) and [`route_params`](#route_params) options,
so in most cases this would require to inject the URL generator service:
```php
use Kreyu\Bundle\DataTableBundle\Action\Type\ModalActionType;
$builder
->addAction('help', ModalActionType::class, [
'href' => $this->urlGenerator->generate('post_help_modal');
])
;
```
When using the `ModalActionType` as a [row action](../../../docs/components/actions.md), you can provide a callable
that will receive the row data as an argument and should return a URL.

```php
use Kreyu\Bundle\DataTableBundle\Action\Type\ModalActionType;

$builder
->addRowAction('details', ModalActionType::class, [
'href' => fn (Post $post) => [
$this->urlGenerator->generate('post_details_modal', [
'id' => $post->getId(),
]),
],
])
;
```

> [!TIP]
> You can use [`route`](#route) and [`route_params`](#route_params) options instead of manually injecting the URL generator service.
> Setting both the `href` and `route` options simultaneously will use the URL provided in the `href` option.
### `route`

- **type**: `null`, `string` or `callable` (if using as a row action)
- **default**: `null`

A route name to generate the URL from. Can be used instead of [`href`](#href) option.

```php
use Kreyu\Bundle\DataTableBundle\Action\Type\ModalActionType;

$builder
->addAction('help', ModalActionType::class, [
'route' => 'post_help_modal',
])
;
```

When using the `ModalActionType` as a [row action](../../../docs/components/actions.md), you can provide a callable
that will receive the row data as an argument and should return a route name.

```php
use Kreyu\Bundle\DataTableBundle\Action\Type\ModalActionType;

$builder
->addRowAction('details', ModalActionType::class, [
'route' => fn (Post $post) => $post->isPublished()
? 'post_published_details_modal'
: 'post_draft_details_modal',
])
;
```

### `route_params`

- **type**: `array` or `callable` (if using as a row action)
- **default**: `[]`

A route params passed to the route provided in [`route`](#route) option. Can be used instead of [`href`](#href) option.

```php
use Kreyu\Bundle\DataTableBundle\Action\Type\ModalActionType;

$builder
->addAction('help', ModalActionType::class, [
'route' => 'post_help_modal',
'route_params' => [
'foo' => 'bar',
],
])
;
```

When using the `ModalActionType` as a [row action](../../../docs/components/actions.md), you can provide a callable
that will receive the row data as an argument and should return a route params array.

```php
use Kreyu\Bundle\DataTableBundle\Action\Type\ModalActionType;

$builder
->addRowAction('details', ModalActionType::class, [
'route' => 'post_details_modal',
'route_params' => fn (Post $post) => [
'id' => $post->getId(),
],
])
;
```

## Inherited options

<ActionTypeOptions/>

0 comments on commit 445e4c9

Please sign in to comment.