You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
6.9KB

  1. {# @var ea \EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext #}
  2. {# @var entity \EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto #}
  3. {% extends ea.templatePath('layout') %}
  4. {% form_theme edit_form with ea.crud.formThemes only %}
  5. {% trans_default_domain ea.i18n.translationDomain %}
  6. {% block body_id 'ea-edit-' ~ entity.name ~ '-' ~ entity.primaryKeyValue %}
  7. {% block body_class 'ea-edit ea-edit-' ~ entity.name %}
  8. {% block configured_head_contents %}
  9. {{ parent() }}
  10. {% for htmlContent in edit_form.vars.ea_crud_form.assets.headContents %}
  11. {{ htmlContent|raw }}
  12. {% endfor %}
  13. {% endblock %}
  14. {% block configured_body_contents %}
  15. {{ parent() }}
  16. {% for htmlContent in edit_form.vars.ea_crud_form.assets.bodyContents %}
  17. {{ htmlContent|raw }}
  18. {% endfor %}
  19. {% endblock %}
  20. {% block configured_stylesheets %}
  21. {{ parent() }}
  22. {% for css_asset in edit_form.vars.ea_crud_form.assets.cssFiles %}
  23. <link rel="stylesheet" href="{{ asset(css_asset) }}">
  24. {% endfor %}
  25. {% for webpack_encore_entry in edit_form.vars.ea_crud_form.assets.webpackEncoreEntries %}
  26. {{ ea_call_function_if_exists('encore_entry_link_tags', webpack_encore_entry) }}
  27. {% endfor %}
  28. {% endblock %}
  29. {% block configured_javascripts %}
  30. {{ parent() }}
  31. {% for js_asset in edit_form.vars.ea_crud_form.assets.jsFiles %}
  32. <script src="{{ asset(js_asset) }}"></script>
  33. {% endfor %}
  34. {% for webpack_encore_entry in edit_form.vars.ea_crud_form.assets.webpackEncoreEntries %}
  35. {{ ea_call_function_if_exists('encore_entry_script_tags', webpack_encore_entry) }}
  36. {% endfor %}
  37. {% endblock %}
  38. {% block content_title %}
  39. {%- apply spaceless -%}
  40. {{ ea.crud.customPageTitle is null
  41. ? (ea.crud.defaultPageTitle|trans(ea.i18n.translationParameters, 'EasyAdminBundle'))|raw
  42. : ea.crud.customPageTitle|trans(ea.i18n.translationParameters)|raw }}
  43. {%- endapply -%}
  44. {% endblock %}
  45. {% block page_actions %}
  46. {% for action in entity.actions %}
  47. {{ include(action.templatePath, { action: action }, with_context = false) }}
  48. {% endfor %}
  49. {% endblock %}
  50. {% block main %}
  51. <div class="card">
  52. <div class="card-body">
  53. {% block edit_form %}
  54. {{ form(edit_form) }}
  55. {% endblock edit_form %}
  56. {% block delete_form %}
  57. {{ include('@EasyAdmin/crud/includes/_delete_form.html.twig', { entity_id: entity.primaryKeyValue }, with_context = false) }}
  58. {% endblock delete_form %}
  59. </div>
  60. </div>
  61. {% endblock %}
  62. {% block body_javascript %}
  63. {{ parent() }}
  64. <script type="text/javascript">
  65. $(function () {
  66. $('.ea-edit-form').areYouSure({'message': '{{ 'form.are_you_sure'|trans({}, 'EasyAdminBundle')|e('js') }}'});
  67. const entityForm = document.querySelector('form.ea-edit-form');
  68. const inputFieldsSelector = 'input,select,textarea';
  69. // Adding visual feedback for invalid fields: any ".form-group" with invalid fields
  70. // receives "has-error" class. The class is removed on click on the ".form-group"
  71. // itself to support custom/complex fields.
  72. entityForm.addEventListener('submit', function (submitEvent) {
  73. entityForm.querySelectorAll(inputFieldsSelector).forEach(function (input) {
  74. if (!input.validity.valid) {
  75. const formGroup = input.closest('div.form-group');
  76. formGroup.classList.add('has-error');
  77. formGroup.addEventListener('click', function onFormGroupClick() {
  78. formGroup.classList.remove('has-error');
  79. formGroup.removeEventListener('click', onFormGroupClick);
  80. });
  81. }
  82. });
  83. const eaEvent = new CustomEvent('ea.form.submit', {
  84. cancelable: true,
  85. detail: {page: 'edit', form: entityForm}
  86. });
  87. const eaEventResult = document.dispatchEvent(eaEvent);
  88. if (false === eaEventResult) {
  89. submitEvent.preventDefault();
  90. submitEvent.stopPropagation();
  91. }
  92. });
  93. // forms with tabs require some special treatment for errors. The problem
  94. // is when the field with errors is included in a tab not currently visible.
  95. // Browser shows this error "An invalid form control with name='...' is not focusable."
  96. // So, the user clicks on Submit button, the form is not submitted and the error
  97. // is not displayed. This JavaScript code ensures that each tab shows a badge with
  98. // the number of errors in it.
  99. entityForm.addEventListener('submit', function () {
  100. const formTabPanes = entityForm.querySelectorAll('.tab-pane');
  101. if (0 === formTabPanes.length) {
  102. return;
  103. }
  104. let firstNavTabItemWithError = null;
  105. formTabPanes.forEach(function (tabPane) {
  106. let tabPaneNumErrors = 0;
  107. tabPane.querySelectorAll(inputFieldsSelector).forEach(function (input) {
  108. if (!input.validity.valid) {
  109. tabPaneNumErrors++;
  110. }
  111. });
  112. let navTabItem = entityForm.querySelector('.nav-item a[href="#' + tabPane.id + '"]');
  113. let existingErrorBadge = navTabItem.querySelector('span.badge.badge-danger');
  114. if (null !== existingErrorBadge) {
  115. navTabItem.removeChild(existingErrorBadge);
  116. }
  117. if (tabPaneNumErrors > 0) {
  118. let newErrorBadge = document.createElement('span');
  119. newErrorBadge.classList.add('badge', 'badge-danger');
  120. newErrorBadge.title = 'form.tab.error_badge_title';
  121. newErrorBadge.textContent = tabPaneNumErrors;
  122. navTabItem.appendChild(newErrorBadge);
  123. if (null === firstNavTabItemWithError) {
  124. firstNavTabItemWithError = navTabItem;
  125. }
  126. }
  127. });
  128. if (firstNavTabItemWithError) {
  129. firstNavTabItemWithError.click();
  130. }
  131. });
  132. $('.action-delete').on('click', function (e) {
  133. e.preventDefault();
  134. const formAction = $(this).attr('formaction');
  135. $('#modal-delete').modal({backdrop: true, keyboard: true})
  136. .off('click', '#modal-delete-button')
  137. .on('click', '#modal-delete-button', function () {
  138. $('#delete-form').attr('action', formAction).trigger('submit');
  139. });
  140. });
  141. });
  142. </script>
  143. <
  144. {% endblock %}