npm package: @pyxisdigital/modalhandler
Description: Pop-up modals for symfony standard CRUD
Author: Jakub Bochenek
Latest version: 1.22.14

##ModalHandler.js

Library to display urls in a pop up modal box.
Originally created to transform Symfony standard crud to one page app.
Library is using JSB extendable Toolkit to inject Javascript Behaviour into rendered HTML.
https://github.com/DracoBlue/jsb

[comment]: <> (##Below instruction is how to install this package from npm registry)

[comment]: <> (&#40;you can also use it by copy/paste from this repo&#41;)

###Install

Download files from repo:
```
https://bitbucket.org/finstod/modalhandler/src/master/
```

Place and include files from **build/prod** in your project
e.g.
js:
<script src="{{ asset('assets/ModalHandler.js') }}"></script>

css:
<link rel="stylesheet" href="{{ asset('assets/ModalHandler.css') }}"/>


####Yarn

```console

yarn add @pyxisdigital/modalhandler

```

####NPM

```console

npm install @pyxisdigital/modalhandler

```

Javascript

```javascript

import '@pyxisdigital/modalhandler/ModalHandler';

```

There are also compiled css and js files if you`re not using a compiler

```javascript

@pyxisdigital/modalhandler/prod/ModalHandler.js

@pyxisdigital/modalhandler/prod/ModalHandler.css

```


### 1. Applying behaviour to URL
* Add classes "jsb_ jsb_ModalHandler" to link tag e.g.

```html
   <a class="jsb_ jsb_ModalHandler" href="action_html.html">Edit</a>
```

### 2 .Applying  behaviour to Forms
* Add classes "jsb_ jsb_ModalHandler" to <form> tag
* Pass as "data-jsb" "listRefreshUrl" parameter an url to refresh list data after saving a form
* Pass as "data-jsb" "listRefreshContainerClass" parameter a class of the container to inject a refreshed list
* Set a form type (new/edit) by 'data-isedit': true/false

```twig
{% set jsbData = {
    'listRefreshUrl': path('wleimport_index'),
    'listRefreshContainerClass': 'listContainer'
} | json_encode
%}

{{ form_start(form,
    {'attr':
        {
            'class': 'jsb_ jsb_ModalHandler',
            'data-jsb': jsbData,
            'data-isedit': true
        }
    }
)
}}
```
### 2. Twig templates modification

#### 2.1 List template
*  In the list template create a list container e.g.

Example:

```twig
{% extends 'base.html.twig' %}

{% block title %}{{ 'frontend.list.header' | trans(domain = 'frontend') }}{% endblock %}

{% block body %}
    <h3>{{ 'frontend.list.header' | trans(domain = 'frontend') }}</h3>
    {{ include('frontend/_messages.html.twig') }}
    <div id="listContainer">
        {{ include('frontend/_items_list.html.twig') }}
        <a class="btn btn-primary jsb_ jsb_ModalHandler" href="{{ path('frontend_new') }}">{{ 'frontend.buttons.add_new' | trans(domain = 'frontend') }}</a>
    </div>
{% endblock %}


```
#### 2.2 Show template

```twig
<div class="frontend_container">
    <div class="modal-header">
        <h3 class="modal-title" >{{ 'frontend.show.header' | trans(domain = 'frontend') }} {{ frontend.name }}</h3>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
    <div class="modal-body">
            <table class="table">
                <tbody>
                    <tr>
                        <th>Id</th>
                        <td>{{ frontend.id }}</td>
                    </tr>
                    <tr>
                        <th>Name</th>
                        <td>{{ frontend.name }}</td>
                    </tr>
                    <tr>
                        <th>Email</th>
                        <td>{{ frontend.email }}</td>
                    </tr>
                </tbody>
            </table>
    </div>
    <div class="modal-footer">
        <ul class="buttons_list">
            <li>
                <button class="btn btn-secondary" data-dismiss="modal">{{ 'frontend.buttons.back' | trans(domain = 'frontend') }}</button>
            </li>
            <li>
                <a class="btn btn-primary jsb_ jsb_ModalHandler" href="{{ path('frontend_edit', {'id': frontend.id}) }}">{{ 'frontend.buttons.edit' | trans(domain = 'frontend') }}</a>
            </li>
            <li>{{ include('frontend/_delete_form.html.twig') }}</li>
        </ul>
    </div>
</div>
```
#### 2.3 New Template
```twig
<div class="content_container">
    <div class="modal-header">
        <h3 class="modal-title" >{{ 'frontend.new.header' | trans(domain = 'frontend') }}</h3>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
    {{ include('frontend/_form.html.twig', {'button_label': 'frontend.buttons.save' }) }}
</div>
```
#### 2.4 Edit Tempalte ####
```twig
<div class="content_container">
    <div class="modal-header">
        <h3 class="modal-title" >{{ 'frontend.edit.header' | trans(domain = 'frontend') }} {{ frontend.name }}</h3>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
        </button>
    </div>
    {{ include('frontend/_form.html.twig', {'button_label': 'frontend.buttons.update' }) }}
</div>
```
##### 2.4.1 Form template
```twig
<div class="modal-body">
    {{ include('frontend/_messages.html.twig') }}

    {% set route = path('frontend_index') %}
    {% set jsbData = {
        'listRefreshUrl': route,
        'listRefreshContainerClass': 'listContainer'
    } | json_encode
    %}

    {{ form_start(form,
        {'attr':
            {
                'id':'frontendForm',
                'novalidate': 'novalidate',
                'class': 'jsb_ jsb_ModalHandler',
                'data-jsb': jsbData,
                'data-isedit': frontend.id
            }
        }
    )
    }}xzO-][
    >
        <div class="tab-pane fade show active" id="frontend_data" role="tabpanel" >
            <div class="row">
                <div class="col-12">
                    {{ form_widget(form) }}
                </div>
            </div>
        </div>
    </div>
    {{ form_end(form) }}
</div>
<div class="modal-footer">
    <ul class="buttons_list">
        <li>
            <button class="btn btn-secondary" data-dismiss="modal">{{ 'frontend.buttons.back' | trans(domain = 'frontend') }}</button>
        </li>
        <li>
            <button form="frontendForm" class="btn btn-success" type="submit">{{ button_label | trans(domain = 'frontend') }}</button>
        </li>
        {% if frontend.id is not null %}
            <li>
                <a class="btn btn-warning jsb_ jsb_ModalHandler" href="{{ path('frontend_show', {'id': frontend.id}) }}">{{ 'frontend.buttons.show' | trans(domain = 'frontend') }}</a>
            </li>
            <li>{{ include('frontend/_delete_form.html.twig') }}</li>
        {% endif %}
    </ul>
</div>
```

#### 2.5 Delete Template 

* Add to the submit button classes "jsb_ jsb_ModalHandler"
* Add data-deletebutton="true" to submit button
* Add form id in data-form="deleteFormId". (same as form id)

Confirmation dialog will be displayed after clicking a delete button

Example:
```html
<form
        id="frontend-delete-form-{{ frontend.id }}"
        class="modal-manager-delete-form"
        method="post"
        action="{{ path('frontend_delete', {'id': frontend.id}) }}"
>
    <input type="hidden" name="_method" value="DELETE">
    <input type="hidden" name="_token" value="{{ csrf_token('delete' ~ frontend.id) }}">
    <a
            data-deletebutton="true"
            data-form="frontend-delete-form-{{ frontend.id }}"
            class="btn btn-danger delete-button jsb_ jsb_ModalHandler"
    >
        {{ 'frontend.buttons.delete' | trans(domain = 'frontend') }}
    </a>
</form>
```
### DateTime picker
There is build in date time picker ( https://github.com/Eonasdan/tempus-dominus)
loaded for every object with 
```css
mh_date_widget
```
class
e.g.
```php
    $form->add(
                'createdAt',
                DateType::class,
                [
                    'widget' => 'single_text',
                    'input' => 'datetime_immutable',
                    'format' => 'YYYY-MM-DD',
                    'label' => 'frontend.field.createdAt',
                    'required' => false,
                    'html5' => false,
                    'attr' => [
                        'class' => 'mh_date_widget'
                    ]
                ]
            )
```

[comment]: <> (### Events)

[comment]: <> (ModalHandler is firing two jsb events:)

[comment]: <> (* ModalHandler::DATA_LOADED - fired after request is finished and data is loade into html)

[comment]: <> (* ModalHandler::DATA_REFRESHED - fired after request that refresh list is executred)

[comment]: <> (To catch events in your code you have to import and use jsb and compile a ModalHandler from dev source fodler )

[comment]: <> (```js)

[comment]: <> (import jsb from 'node-jsb';)

[comment]: <> (import '@pyxisdigital/modalhandler/ModalHandler';)

[comment]: <> (```)