@@ -6,21 +6,30 @@ use EasyCorp\Bundle\EasyAdminBundle\Config\Action; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Actions; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Assets; | |||
use EasyCorp\Bundle\EasyAdminBundle\Config\Crud; | |||
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext; | |||
use EasyCorp\Bundle\EasyAdminBundle\Controller\AbstractCrudController as EaAbstractCrudController; | |||
use EasyCorp\Bundle\EasyAdminBundle\Router\AdminUrlGenerator; | |||
use Lc\SovBundle\Doctrine\EntityManager; | |||
use Lc\SovBundle\Doctrine\Extension\TranslatableInterface; | |||
use Symfony\Component\HttpFoundation\JsonResponse; | |||
use Symfony\Component\HttpFoundation\RequestStack; | |||
use Symfony\Component\HttpFoundation\Session\SessionInterface; | |||
use Symfony\Component\Validator\Constraints\Json; | |||
use Twig\Environment; | |||
abstract class AbstractCrudController extends EaAbstractCrudController | |||
{ | |||
protected $session; | |||
protected $request; | |||
protected $em; | |||
protected $twig; | |||
public function __construct(SessionInterface $session, RequestStack $request) | |||
public function __construct(SessionInterface $session, RequestStack $request, EntityManager $em, Environment $twig) | |||
{ | |||
$this->session = $session; | |||
$this->request = $request; | |||
$this->em = $em; | |||
$this->twig = $twig; | |||
} | |||
public function configureActions(Actions $actions): Actions | |||
@@ -38,30 +47,38 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
); | |||
} | |||
$actionSaveAndReturn = [ | |||
'add-class' => 'float-right', | |||
'icon' => 'check', | |||
]; | |||
$actionIndex = [ | |||
'icon' => 'chevron-left', | |||
'class' => 'btn btn-link', | |||
]; | |||
/* Boutons des actions dans les listes */ | |||
$actionsArray[Crud::PAGE_INDEX] = [ | |||
Action::NEW => [ | |||
'icon' => 'plus', | |||
'label' => 'Créer' | |||
], | |||
Action::EDIT => [ | |||
'class' => 'btn btn-sm btn-primary', | |||
'icon' => 'edit', | |||
'label' => false, | |||
], | |||
Action::DELETE => [ | |||
'class' => 'btn btn-sm btn-default', | |||
'icon' => 'trash', | |||
'label' => false, | |||
'dropdown' => true, | |||
], | |||
Action::BATCH_DELETE => [ | |||
'class' => 'btn btn-danger', | |||
'icon' => 'trash', | |||
], | |||
]; | |||
/* Boutons des actions dans l'édition */ | |||
$actionSaveAndReturn = [ | |||
'add-class' => 'float-right', | |||
'icon' => 'check', | |||
]; | |||
$actionIndex = [ | |||
'icon' => 'chevron-left', | |||
'class' => 'btn btn-link', | |||
]; | |||
$actionsArray[Crud::PAGE_EDIT] = [ | |||
Action::SAVE_AND_CONTINUE => [ | |||
'class' => 'btn btn-info float-right', | |||
@@ -71,14 +88,15 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
'class' => 'btn btn-link text-danger', | |||
], | |||
Action::SAVE_AND_RETURN => $actionSaveAndReturn, | |||
Action::INDEX=>$actionIndex | |||
Action::INDEX => $actionIndex | |||
]; | |||
$actionsArray[Crud::PAGE_NEW] = [ | |||
Action::SAVE_AND_ADD_ANOTHER => [ | |||
'class' => 'btn btn-info float-right', | |||
], | |||
Action::SAVE_AND_RETURN => $actionSaveAndReturn, | |||
Action::INDEX=>$actionIndex | |||
Action::INDEX => $actionIndex | |||
]; | |||
$actions->add(Crud::PAGE_EDIT, Action::INDEX); | |||
@@ -99,16 +117,22 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
if (isset($button['add-class'])) { | |||
$action->addCssClass($button['add-class']); | |||
} | |||
if (isset($button['class'])) { | |||
$action->setCssClass($button['class']); | |||
} | |||
if (isset($button['icon'])) { | |||
$action->setIcon('fa fa-'.$button['icon']); | |||
$action->setIcon('fa fa-' . $button['icon']); | |||
} | |||
if (isset($button['label'])) { | |||
$action->setLabel($button['label']); | |||
} | |||
if (isset($button['dropdown']) && $button['dropdown']) { | |||
$action->addCssClass('in-dropdown'); | |||
} | |||
return $action; | |||
} | |||
@@ -121,7 +145,7 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
public function configureCrud(Crud $crud): Crud | |||
{ | |||
$crud = parent::configureCrud($crud);; | |||
$crud = parent::configureCrud($crud); | |||
$this->setMaxResults($crud); | |||
@@ -132,7 +156,7 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
{ | |||
$entityClass = $this->getEntityFqcn(); | |||
$paramListMaxResults = 'listMaxResults'; | |||
$paramSessionListMaxResults = $entityClass.'-'.$paramListMaxResults; | |||
$paramSessionListMaxResults = $entityClass . '-' . $paramListMaxResults; | |||
$requestListMaxResults = $this->request->getCurrentRequest()->get($paramListMaxResults); | |||
if ($requestListMaxResults) { | |||
@@ -145,4 +169,14 @@ abstract class AbstractCrudController extends EaAbstractCrudController | |||
$crud->setPaginatorPageSize($maxResults); | |||
} | |||
public function index(AdminContext $context) | |||
{ | |||
$responseParameters = parent::index($context); | |||
// Liste des fields | |||
$responseParameters->set('fields', $this->configureFields('index')); | |||
return $responseParameters; | |||
} | |||
} |
@@ -36,7 +36,9 @@ class DashboardController extends AbstractDashboardController | |||
public function configureAssets(): Assets | |||
{ | |||
$assets = parent::configureAssets(); | |||
$assets->addWebpackEncoreEntry('adminlte-common'); | |||
$assets->addWebpackEncoreEntry('adminlte-index'); | |||
return $assets; | |||
} |
@@ -15,13 +15,21 @@ import 'adminlte-plugin/select2/js/i18n/fr.js'; | |||
import 'adminlte-plugin/select2/css/select2.min.css'; | |||
import 'adminlte-plugin/select2-bootstrap4-theme/select2-bootstrap4.min.css'; | |||
// Toastr | |||
import toastr from 'toastr/toastr.js' ; | |||
import 'toastr/toastr.scss' ; | |||
global.toastr = toastr ; | |||
// Tools | |||
import { Tools } from '../../../tools/tools.js'; | |||
global.Tools = Tools; | |||
import { Notification } from './js/notification.js'; | |||
global.Notification = Notification; | |||
// Common | |||
import './common.scss'; | |||
import './common.js' | |||
import './common.js' ; | |||
@@ -5,5 +5,5 @@ | |||
@import 'scss/form/footer'; | |||
@import 'scss/card'; | |||
@import 'scss/modal'; | |||
@import 'scss/toastr'; | |||
@@ -0,0 +1,35 @@ | |||
export class Notification { | |||
static setNotifications(notifications) { | |||
var currentNotifications = new Array(); | |||
for (var type in notifications) { | |||
for (var key in notifications[type]) { | |||
if (!currentNotifications.includes(notifications[type][key])) { | |||
currentNotifications.push(notifications[type][key]); | |||
self.addNotification(type, notifications[type][key]); | |||
} | |||
} | |||
} | |||
} | |||
static addNotification(type, text) { | |||
toastr.options.timeOut = 3000; | |||
toastr.options.onHidden = function () { | |||
if ($('#toast-container .toast').length == 0) $('#toast-close-all').remove(); | |||
}; | |||
toastr[type](text); | |||
if ($('#toast-close-all').length == 0) { | |||
$('#toast-container').prepend('<button id="toast-close-all"><i class="fa fa-times"></i></button>'); | |||
} | |||
$('#toast-close-all').off('click'); | |||
$('#toast-close-all').on('click', function () { | |||
toastr.remove(); | |||
if ($('#toast-container .toast').length == 0) $('#toast-close-all').remove(); | |||
}); | |||
} | |||
} |
@@ -0,0 +1,36 @@ | |||
#toast-container { | |||
width: 350px; | |||
} | |||
.toast { | |||
float: right | |||
} | |||
#toast-container:before:hover { | |||
opacity: 1; | |||
cursor: pointer; | |||
} | |||
#toast-close-all { | |||
border: 0; | |||
position: absolute; | |||
pointer-events: auto; | |||
z-index: 999999999999999999999; | |||
background: #BD362F; | |||
border-radius: 3px; | |||
color: #fff; | |||
opacity: 0.8; | |||
top: 2px; | |||
width: 50px; | |||
height: 50px; | |||
font-size: 30px; | |||
left: 0px; | |||
text-align: center; | |||
-webkit-text-shadow: 0 1px 0 #fff; | |||
text-shadow: 0 1px 0 #fff; | |||
-moz-box-shadow: 0 0 12px #999; | |||
-webkit-box-shadow: 0 0 12px #999; | |||
box-shadow: 0 0 12px #999; | |||
} | |||
@@ -0,0 +1,3 @@ | |||
import './index.js' | |||
import './index.scss' |
@@ -0,0 +1,135 @@ | |||
$(document).ready(function() { | |||
lcCrudIndexToggle() ; | |||
lcCrudIndexBatchActions() ; | |||
}) ; | |||
function lcCrudIndexToggle() { | |||
const toggles = document.querySelectorAll('.custom-switch input[type="checkbox"]'); | |||
for (i = 0; i < toggles.length; i++) { | |||
toggles[i].addEventListener('change', function () { | |||
const toggle = this; | |||
const newValue = this.checked; | |||
const oldValue = !newValue; | |||
const toggleUrl = this.closest('.custom-switch').dataset.url + "&newValue=" + newValue.toString(); | |||
let toggleRequest = $.ajax({type: "POST", url: toggleUrl, data: {}, dataType: 'json'}); | |||
toggleRequest.done(function (response) { | |||
Notification.addNotification('success', 'La propriété a bien été mise à jour.'); | |||
}); | |||
toggleRequest.fail(function () { | |||
toggle.checked = oldValue; | |||
toggle.disabled = true; | |||
toggle.closest('.checkbox-switch').classList.add('disabled'); | |||
Notification.addNotification('error', 'Une erreur est survenue.'); | |||
}); | |||
}); | |||
} | |||
} | |||
function lcCrudIndexBatchActions() { | |||
const titleContent = $('.content-header-title > .title').html(); | |||
$(document).on('click', '.deselect-batch-button', function () { | |||
$(this).closest('.content').find(':checkbox.form-batch-checkbox-all').prop('checked', false).trigger('change'); | |||
}); | |||
$(document).on('change', '.form-batch-checkbox-all', function () { | |||
$(this).closest('.content').find(':checkbox.form-batch-checkbox').prop('checked', $(this).prop('checked')).trigger('change'); | |||
}); | |||
$(document).on('change', '.form-batch-checkbox', function () { | |||
const $content = $(this).closest('.content-wrapper'); | |||
let $input = $content.find(':hidden#batch_form_entityIds'); | |||
let ids = $input.val() ? $input.val().split(',') : []; | |||
const id = $(this).val(); | |||
if ($(this).prop('checked')) { | |||
$(this).closest('tr').addClass('selected-row'); | |||
if (-1 === ids.indexOf(id)) { | |||
ids.push(id); | |||
} | |||
} else { | |||
$(this).closest('tr').removeClass('selected-row'); | |||
ids = ids.filter(function (value) { | |||
return value !== id | |||
}); | |||
$content.find(':checkbox.form-batch-checkbox-all').prop('checked', false); | |||
} | |||
if (0 === ids.length) { | |||
$content.find('.global-actions').show(); | |||
$content.find('.batch-actions').hide(); | |||
$content.find('table').removeClass('table-batch'); | |||
} else { | |||
$content.find('.batch-actions').show(); | |||
$content.find('.global-actions').hide(); | |||
$content.find('table').addClass('table-batch'); | |||
} | |||
$input.val(ids.join(',')); | |||
$content.find('.content-header-title > .title').html(0 === ids.length ? titleContent : ''); | |||
}); | |||
let modalTitle = $('#batch-action-confirmation-title'); | |||
const titleContentWithPlaceholders = modalTitle.text(); | |||
$('[data-action-batch]').on('click', function (event) { | |||
event.preventDefault(); | |||
event.stopPropagation(); | |||
let $actionElement = $(this); | |||
const actionName = $actionElement.attr('data-action-name'); | |||
const selectedItems = $('input[type="checkbox"].form-batch-checkbox:checked'); | |||
modalTitle.text(titleContentWithPlaceholders | |||
.replace('%action_name%', actionName) | |||
.replace('%num_items%', selectedItems.length)); | |||
$('#modal-batch-action').modal({backdrop: true, keyboard: true}) | |||
.off('click', '#modal-batch-action-button') | |||
.on('click', '#modal-batch-action-button', function () { | |||
$actionElement.unbind('click'); | |||
$form = document.createElement('form'); | |||
$form.setAttribute('action', $actionElement.attr('data-action-url')); | |||
$form.setAttribute('method', 'POST'); | |||
$actionNameInput = document.createElement('input'); | |||
$actionNameInput.setAttribute('type', 'hidden'); | |||
$actionNameInput.setAttribute('name', 'batchActionName'); | |||
$actionNameInput.setAttribute('value', $actionElement.attr('data-action-name')); | |||
$form.appendChild($actionNameInput); | |||
$entityFqcnInput = document.createElement('input'); | |||
$entityFqcnInput.setAttribute('type', 'hidden'); | |||
$entityFqcnInput.setAttribute('name', 'entityFqcn'); | |||
$entityFqcnInput.setAttribute('value', $actionElement.attr('data-entity-fqcn')); | |||
$form.appendChild($entityFqcnInput); | |||
$actionUrlInput = document.createElement('input'); | |||
$actionUrlInput.setAttribute('type', 'hidden'); | |||
$actionUrlInput.setAttribute('name', 'batchActionUrl'); | |||
$actionUrlInput.setAttribute('value', $actionElement.attr('data-action-url')); | |||
$form.appendChild($actionUrlInput); | |||
$csrfTokenInput = document.createElement('input'); | |||
$csrfTokenInput.setAttribute('type', 'hidden'); | |||
$csrfTokenInput.setAttribute('name', 'batchActionCsrfToken'); | |||
$csrfTokenInput.setAttribute('value', $actionElement.attr('data-action-csrf-token')); | |||
$form.appendChild($csrfTokenInput); | |||
selectedItems.each((i, item) => { | |||
$entityIdInput = document.createElement('input'); | |||
$entityIdInput.setAttribute('type', 'hidden'); | |||
$entityIdInput.setAttribute('name', `batchActionEntityIds[${i}]`); | |||
$entityIdInput.setAttribute('value', item.value); | |||
$form.appendChild($entityIdInput); | |||
}); | |||
document.body.appendChild($form); | |||
//modalTitle.text(titleContentWithPlaceholders); | |||
$form.submit(); | |||
}); | |||
}); | |||
} |
@@ -0,0 +1,6 @@ | |||
table.table { | |||
.dropdown-actions { | |||
display: inline-block ; | |||
} | |||
} |
@@ -14,7 +14,7 @@ | |||
{% block id %}{{ id_modal }}{% endblock %} | |||
{% block size %}modal-xl{% endblock %} | |||
{% block title %}{{ field.value.legend ? field.value.legend : 'Image' }}{% endblock %} | |||
{% block content %} | |||
{% block body %} | |||
<img src="{{ lc_liip(field.value.path, 'big') }}" alt="{{ field.value.legend }}" /> | |||
{% endblock %} | |||
{% block footer_wrapper %}{% endblock %} |
@@ -1,10 +1,9 @@ | |||
{% set item = entity.instance %} | |||
{% set property_name = field.getProperty() %} | |||
{% set id_toggle = 'toogle-'~item.id~'-'~property_name %} | |||
<div class="custom-control custom-switch custom-switch-on-success custom-switch-off-default" | |||
data-propertyname="{{ property_name }}" data-id={{ item.id }}> | |||
data-url="{{ ea_url({crudAction: 'edit', entityId: item.id, fieldName: property_name }) }}"> | |||
<input type="checkbox" class="custom-control-input" id="{{ id_toggle }}" {{ field.value ? 'checked' }}> | |||
<label class="custom-control-label" for="{{ id_toggle }}"> | |||
{{ field.getCustomOption('toggle_label') ?? field.label }}</label> |
@@ -44,14 +44,14 @@ | |||
{% set has_filters = filters|length > 0 %} | |||
{% set has_datagrid_tools = has_search or has_filters %} | |||
<div class="card card-table card-outline card-primary"> | |||
<div class="card-header"> | |||
{% embed '@LcSov/adminlte/embed/card.html.twig' %} | |||
{% block css %}card-table card-outline card-primary{% endblock %} | |||
{% block header %} | |||
<span data-toggle="tooltip" class="badge badge-light" data-original-title="Total" title="Total"> | |||
{{ paginator.numResults }} résultats | |||
</span> | |||
</div> | |||
<div class="card-body"> | |||
{% endblock %} | |||
{% block body %} | |||
<div class="table-responsive"> | |||
<table class="table table-bordered table-hover table-striped"> | |||
<thead> | |||
@@ -59,14 +59,19 @@ | |||
<tr> | |||
{% if has_batch_actions %} | |||
<th class=""><span><input type="checkbox" | |||
class="form-check-input m-0 align-middle form-batch-checkbox-all"></span> | |||
<th class=""> | |||
<input type="hidden" id="batch_form_entityIds" value="" /> | |||
<span><input type="checkbox" | |||
class="form-check-input m-0 align-middle form-batch-checkbox-all"></span> | |||
</th> | |||
{% endif %} | |||
{% set ea_sort_asc = constant('EasyCorp\\Bundle\\EasyAdminBundle\\Config\\Option\\SortOrder::ASC') %} | |||
{% set ea_sort_desc = constant('EasyCorp\\Bundle\\EasyAdminBundle\\Config\\Option\\SortOrder::DESC') %} | |||
{% for field in entities|first.fields ?? [] %} | |||
{% for field in fields ?? [] %} | |||
{% set field = field.getAsDto() %} | |||
{% set is_sorting_field = ea.search.isSortingField(field.property) %} | |||
{% set next_sort_direction = is_sorting_field ? (ea.search.sortDirection(field.property) == ea_sort_desc ? ea_sort_asc : ea_sort_desc) : ea_sort_desc %} | |||
{% set column_icon = is_sorting_field ? (next_sort_direction == ea_sort_desc ? 'fa-arrow-up' : 'fa-arrow-down') : 'fa-sort' %} | |||
@@ -83,7 +88,8 @@ | |||
</th> | |||
{% endfor %} | |||
<th class="w-1" {% if ea.crud.showEntityActionsAsDropdown %}width="10px"{% endif %} dir="{{ ea.i18n.textDirection }}"> | |||
<th class="w-1" {% if ea.crud.showEntityActionsAsDropdown %}width="10px"{% endif %} | |||
dir="{{ ea.i18n.textDirection }}"> | |||
<span class="sr-only">{{ 'action.entity_actions'|trans(ea.i18n.translationParameters, 'EasyAdminBundle') }}</span> | |||
</th> | |||
</tr> | |||
@@ -110,25 +116,33 @@ | |||
{% endfor %} | |||
{% block entity_actions %} | |||
<td class="actions"> | |||
<td class="actions text-right"> | |||
{% set in_dropdown_class = 'in-dropdown' %} | |||
{% for action in entity.actions %} | |||
{% if not (in_dropdown_class in action.cssClass) %} | |||
{{ include(action.templatePath, { action: action, entity: entity, isIncludedInDropdown: 0 }, with_context = false) }} | |||
{% endif %} | |||
{% endfor %} | |||
<div class="dropdown dropdown-actions"> | |||
<a class="dropdown-toggle btn btn-secondary btn-sm" href="#" | |||
role="button" data-toggle="dropdown" aria-haspopup="true" | |||
aria-expanded="false"> | |||
</a> | |||
<div class="dropdown-menu dropdown-menu-right"> | |||
{% for action in entity.actions %} | |||
{% if in_dropdown_class in action.cssClass %} | |||
{{ include(action.templatePath, { action: action, isIncludedInDropdown: 1 }, with_context = false) }} | |||
{% endif %} | |||
{% endfor %} | |||
</div> | |||
</div> | |||
{% if not ea.crud.showEntityActionsAsDropdown %} | |||
{% for action in entity.actions %} | |||
{{ include(action.templatePath, { action: action, entity: entity, isIncludedInDropdown: ea.crud.showEntityActionsAsDropdown }, with_context = false) }} | |||
{% endfor %} | |||
{% else %} | |||
<div class="dropdown dropdown-actions"> | |||
<a class="dropdown-toggle btn btn-secondary btn-sm" href="#" | |||
role="button" data-toggle="dropdown" aria-haspopup="true" | |||
aria-expanded="false"> | |||
<i class="fa fa-fw fa-ellipsis-h"></i> | |||
</a> | |||
<div class="dropdown-menu dropdown-menu-right"> | |||
{% for action in entity.actions %} | |||
{{ include(action.templatePath, { action: action, isIncludedInDropdown: ea.crud.showEntityActionsAsDropdown }, with_context = false) }} | |||
{% endfor %} | |||
</div> | |||
</div> | |||
{% endif %} | |||
</td> | |||
{% endblock entity_actions %} | |||
@@ -155,18 +169,15 @@ | |||
</tbody> | |||
</table> | |||
</div> | |||
</div> | |||
{% if entities|length > 0 %} | |||
<div class="card-footer"> | |||
<div class="row"> | |||
{% block paginator %} | |||
{{ include(ea.templatePath('crud/paginator')) }} | |||
{% endblock paginator %} | |||
</div> | |||
{% endblock %} | |||
{% block footer %} | |||
<div class="row"> | |||
{% block paginator %} | |||
{{ include(ea.templatePath('crud/paginator')) }} | |||
{% endblock paginator %} | |||
</div> | |||
{% endif %} | |||
</div> | |||
{% endblock %} | |||
{% endembed %} | |||
{% block delete_form %} | |||
{{ include('@EasyAdmin/crud/includes/_delete_form.html.twig', with_context = false) }} | |||
@@ -186,40 +197,19 @@ | |||
<script type="text/javascript"> | |||
$(function () { | |||
const customSwitches = document.querySelectorAll('td.field-boolean .custom-control.custom-switch input[type="checkbox"]'); | |||
for (i = 0; i < customSwitches.length; i++) { | |||
customSwitches[i].addEventListener('change', function () { | |||
const customSwitch = this; | |||
const newValue = this.checked; | |||
const oldValue = !newValue; | |||
const toggleUrl = this.getAttribute('data-toggle-url') + "&newValue=" + newValue.toString(); | |||
let toggleRequest = $.ajax({type: "GET", url: toggleUrl, data: {}}); | |||
toggleRequest.done(function (result) { | |||
}); | |||
toggleRequest.fail(function () { | |||
// in case of error, restore the original value and disable the toggle | |||
customSwitch.checked = oldValue; | |||
customSwitch.disabled = true; | |||
customSwitch.closest('.custom-switch').classList.add('disabled'); | |||
}); | |||
}); | |||
} | |||
/* $('.action-delete').on('click', function (e) { | |||
e.preventDefault(); | |||
const formAction = $(this).attr('formaction'); | |||
/* $('.action-delete').on('click', function (e) { | |||
e.preventDefault(); | |||
const formAction = $(this).attr('formaction'); | |||
$('#modal-delete').modal({backdrop: true, keyboard: true}) | |||
.off('click', '#modal-delete-button') | |||
.on('click', '#modal-delete-button', function () { | |||
let deleteForm = $('#delete-form'); | |||
deleteForm.attr('action', formAction); | |||
deleteForm.submit(); | |||
}); | |||
});*/ | |||
$('#modal-delete').modal({backdrop: true, keyboard: true}) | |||
.off('click', '#modal-delete-button') | |||
.on('click', '#modal-delete-button', function () { | |||
let deleteForm = $('#delete-form'); | |||
deleteForm.attr('action', formAction); | |||
deleteForm.submit(); | |||
}); | |||
});*/ | |||
{% if filters|length > 0 %} | |||
const filterModal = document.querySelector('#modal-filters'); | |||
@@ -281,107 +271,7 @@ | |||
{% if has_batch_actions %} | |||
const titleContent = $('.content-header-title > .title').html(); | |||
$(document).on('click', '.deselect-batch-button', function () { | |||
$(this).closest('.content').find(':checkbox.form-batch-checkbox-all').prop('checked', false).trigger('change'); | |||
}); | |||
$(document).on('change', '.form-batch-checkbox-all', function () { | |||
$(this).closest('.content').find(':checkbox.form-batch-checkbox').prop('checked', $(this).prop('checked')).trigger('change'); | |||
}); | |||
$(document).on('change', '.form-batch-checkbox', function () { | |||
const $content = $(this).closest('.content'); | |||
let $input = $content.find(':hidden#batch_form_entityIds'); | |||
let ids = $input.val() ? $input.val().split(',') : []; | |||
const id = $(this).val(); | |||
if ($(this).prop('checked')) { | |||
$(this).closest('tr').addClass('selected-row'); | |||
if (-1 === ids.indexOf(id)) { | |||
ids.push(id); | |||
} | |||
} else { | |||
$(this).closest('tr').removeClass('selected-row'); | |||
ids = ids.filter(function (value) { | |||
return value !== id | |||
}); | |||
$content.find(':checkbox.form-batch-checkbox-all').prop('checked', false); | |||
} | |||
if (0 === ids.length) { | |||
$content.find('.global-actions').show(); | |||
$content.find('.batch-actions').hide(); | |||
$content.find('table').removeClass('table-batch'); | |||
} else { | |||
$content.find('.batch-actions').show(); | |||
$content.find('.global-actions').hide(); | |||
$content.find('table').addClass('table-batch'); | |||
} | |||
$input.val(ids.join(',')); | |||
$content.find('.content-header-title > .title').html(0 === ids.length ? titleContent : ''); | |||
}); | |||
let modalTitle = $('#batch-action-confirmation-title'); | |||
const titleContentWithPlaceholders = modalTitle.text(); | |||
$('[data-action-batch]').on('click', function (event) { | |||
event.preventDefault(); | |||
event.stopPropagation(); | |||
let $actionElement = $(this); | |||
const actionName = $actionElement.attr('data-action-name'); | |||
const selectedItems = $('input[type="checkbox"].form-batch-checkbox:checked'); | |||
modalTitle.text(titleContentWithPlaceholders | |||
.replace('%action_name%', actionName) | |||
.replace('%num_items%', selectedItems.length)); | |||
$('#modal-batch-action').modal({backdrop: true, keyboard: true}) | |||
.off('click', '#modal-batch-action-button') | |||
.on('click', '#modal-batch-action-button', function () { | |||
$actionElement.unbind('click'); | |||
$form = document.createElement('form'); | |||
$form.setAttribute('action', $actionElement.attr('data-action-url')); | |||
$form.setAttribute('method', 'POST'); | |||
$actionNameInput = document.createElement('input'); | |||
$actionNameInput.setAttribute('type', 'hidden'); | |||
$actionNameInput.setAttribute('name', 'batchActionName'); | |||
$actionNameInput.setAttribute('value', $actionElement.attr('data-action-name')); | |||
$form.appendChild($actionNameInput); | |||
$entityFqcnInput = document.createElement('input'); | |||
$entityFqcnInput.setAttribute('type', 'hidden'); | |||
$entityFqcnInput.setAttribute('name', 'entityFqcn'); | |||
$entityFqcnInput.setAttribute('value', $actionElement.attr('data-entity-fqcn')); | |||
$form.appendChild($entityFqcnInput); | |||
$actionUrlInput = document.createElement('input'); | |||
$actionUrlInput.setAttribute('type', 'hidden'); | |||
$actionUrlInput.setAttribute('name', 'batchActionUrl'); | |||
$actionUrlInput.setAttribute('value', $actionElement.attr('data-action-url')); | |||
$form.appendChild($actionUrlInput); | |||
$csrfTokenInput = document.createElement('input'); | |||
$csrfTokenInput.setAttribute('type', 'hidden'); | |||
$csrfTokenInput.setAttribute('name', 'batchActionCsrfToken'); | |||
$csrfTokenInput.setAttribute('value', $actionElement.attr('data-action-csrf-token')); | |||
$form.appendChild($csrfTokenInput); | |||
selectedItems.each((i, item) => { | |||
$entityIdInput = document.createElement('input'); | |||
$entityIdInput.setAttribute('type', 'hidden'); | |||
$entityIdInput.setAttribute('name', `batchActionEntityIds[${i}]`); | |||
$entityIdInput.setAttribute('value', item.value); | |||
$form.appendChild($entityIdInput); | |||
}); | |||
document.body.appendChild($form); | |||
//modalTitle.text(titleContentWithPlaceholders); | |||
$form.submit(); | |||
}); | |||
}); | |||
{% endif %} | |||
}); | |||
</script> |
@@ -0,0 +1,22 @@ | |||
<div class="card {% block css %}{% endblock %}" id="{% block id %}{% endblock %}"> | |||
{% block header_wrapper %} | |||
<div class="card-header"> | |||
{% block header %} | |||
{% endblock header %} | |||
</div> | |||
{% endblock header_wrapper %} | |||
{% block body_wrapper %} | |||
<div class="card-body"> | |||
{% block body %} | |||
{% endblock %} | |||
</div> | |||
{% endblock body_wrapper %} | |||
{% block footer_wrapper %} | |||
<div class="card-footer"> | |||
{% block footer %} | |||
{% endblock footer %} | |||
</div> | |||
{% endblock footer_wrapper %} | |||
</div> |
@@ -1,5 +1,4 @@ | |||
<div class="modal fade show" id="{% block id %}{% endblock %}"> | |||
<div class="modal-dialog {% block size %}{% endblock %}"> | |||
{% block form_start %}{% endblock %} | |||
<div class="modal-content"> | |||
@@ -10,7 +9,7 @@ | |||
</button> | |||
</div> | |||
<div class="modal-body"> | |||
{% block content %} | |||
{% block body %} | |||
{% endblock %} | |||
</div> | |||
{% block footer_wrapper %} | |||
@@ -25,5 +24,4 @@ | |||
{% block form_end %}{% endblock %} | |||
<!-- /.modal-content --> | |||
</div> | |||
</div> |