base_list.html.twig 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. {#
  2. This file is part of the Sonata package.
  3. (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  4. For the full copyright and license information, please view the LICENSE
  5. file that was distributed with this source code.
  6. #}
  7. {% extends base_template %}
  8. {%- block actions -%}
  9. {% include 'SonataAdminBundle:CRUD:action_buttons.html.twig' %}
  10. {%- endblock -%}
  11. {% block tab_menu %}{{ knp_menu_render(admin.sidemenu(action), {'currentClass' : 'active', 'template': sonata_admin.adminPool.getTemplate('tab_menu_template')}, 'twig') }}{% endblock %}
  12. {% block title %}
  13. {#
  14. The list template can be used in nested mode,
  15. so we define the title corresponding to the parent's admin.
  16. #}
  17. {% if admin.isChild and admin.parent.subject %}
  18. {{ "title_edit"|trans({'%name%': admin.parent.toString(admin.parent.subject)|truncate(15) }, 'SonataAdminBundle') }}
  19. {% endif %}
  20. {% endblock %}
  21. {% block navbar_title %}
  22. {{ block('title') }}
  23. {% endblock %}
  24. {% block list_table %}
  25. <div class="col-xs-12 col-md-12">
  26. {% set batchactions = admin.batchactions %}
  27. {% if admin.hasRoute('batch') and batchactions|length %}
  28. <form action="{{ admin.generateUrl('batch', {'filter': admin.filterParameters}) }}" method="POST" >
  29. <input type="hidden" name="_sonata_csrf_token" value="{{ csrf_token }}">
  30. {% endif %}
  31. {# Add a margin if no pager to prevent dropdown cropping on window #}
  32. <div class="box box-primary" {% if admin.datagrid.pager.lastPage == 1 %}style="margin-bottom: 100px;"{% endif %}>
  33. <div class="box-body {% if admin.datagrid.results|length > 0 %}table-responsive no-padding{% endif %}">
  34. {{ sonata_block_render_event('sonata.admin.list.table.top', { 'admin': admin }) }}
  35. {% block list_header %}{% endblock %}
  36. {% if admin.datagrid.results|length > 0 %}
  37. <table class="table table-bordered table-striped sonata-ba-list">
  38. {% block table_header %}
  39. <thead>
  40. <tr class="sonata-ba-list-field-header">
  41. {% for field_description in admin.list.elements %}
  42. {% if admin.hasRoute('batch') and field_description.getOption('code') == '_batch' and batchactions|length > 0 %}
  43. <th class="sonata-ba-list-field-header sonata-ba-list-field-header-batch">
  44. <input type="checkbox" id="list_batch_checkbox">
  45. </th>
  46. {% elseif field_description.getOption('code') == '_select' %}
  47. <th class="sonata-ba-list-field-header sonata-ba-list-field-header-select"></th>
  48. {% elseif field_description.name == '_action' and app.request.isXmlHttpRequest %}
  49. {# Action buttons disabled in ajax view! #}
  50. {% elseif field_description.getOption('ajax_hidden') == true and app.request.isXmlHttpRequest %}
  51. {# Disable fields with 'ajax_hidden' option set to true #}
  52. {% else %}
  53. {% set sortable = false %}
  54. {% if field_description.options.sortable is defined and field_description.options.sortable %}
  55. {% set sortable = true %}
  56. {% set sort_parameters = admin.modelmanager.sortparameters(field_description, admin.datagrid) %}
  57. {% set current = admin.datagrid.values._sort_by == field_description or admin.datagrid.values._sort_by.fieldName == sort_parameters.filter._sort_by %}
  58. {% set sort_active_class = current ? 'sonata-ba-list-field-order-active' : '' %}
  59. {% set sort_by = current ? admin.datagrid.values._sort_order : field_description.options._sort_order %}
  60. {% endif %}
  61. {% spaceless %}
  62. <th class="sonata-ba-list-field-header-{{ field_description.type}} {% if sortable %} sonata-ba-list-field-header-order-{{ sort_by|lower }} {{ sort_active_class }}{% endif %}{% if field_description.options.header_class is defined %} {{ field_description.options.header_class }}{% endif %}"{% if field_description.options.header_style is defined %} style="{{ field_description.options.header_style }}"{% endif %}>
  63. {% if sortable %}<a href="{{ admin.generateUrl('list', sort_parameters) }}">{% endif %}
  64. {% if field_description.getOption('label_icon') %}
  65. <i class="sonata-ba-list-field-header-label-icon {{ field_description.getOption('label_icon') }}" aria-hidden="true"></i>
  66. {% endif %}
  67. {{ field_description.label|trans({}, field_description.translationDomain) }}
  68. {% if sortable %}</a>{% endif %}
  69. </th>
  70. {% endspaceless %}
  71. {% endif %}
  72. {% endfor %}
  73. </tr>
  74. </thead>
  75. {% endblock %}
  76. {% block table_body %}
  77. <tbody>
  78. {% include admin.getTemplate('outer_list_rows_' ~ admin.getListMode()) %}
  79. </tbody>
  80. {% endblock %}
  81. {% block table_footer %}
  82. {% endblock %}
  83. </table>
  84. {% else %}
  85. {% block no_result_content %}
  86. <div class="info-box">
  87. <span class="info-box-icon bg-aqua"><i class="fa fa-arrow-circle-right" aria-hidden="true"></i></span>
  88. <div class="info-box-content">
  89. <span class="info-box-text">{{ 'no_result'|trans({}, 'SonataAdminBundle') }}</span>
  90. <div class="progress">
  91. <div class="progress-bar" style="width: 0%"></div>
  92. </div>
  93. <span class="progress-description">
  94. {% if not app.request.xmlHttpRequest %}
  95. <ul class="list-unstyled">
  96. {% include 'SonataAdminBundle:Button:create_button.html.twig' %}
  97. </ul>
  98. {% endif %}
  99. </span>
  100. </div><!-- /.info-box-content -->
  101. </div>
  102. {% endblock %}
  103. {% endif %}
  104. {{ sonata_block_render_event('sonata.admin.list.table.bottom', { 'admin': admin }) }}
  105. </div>
  106. {% block list_footer %}
  107. {% if admin.datagrid.results|length > 0 %}
  108. <div class="box-footer">
  109. <div class="form-inline clearfix">
  110. {% if not app.request.isXmlHttpRequest %}
  111. <div class="pull-left">
  112. {% if admin.hasRoute('batch') and batchactions|length > 0 %}
  113. {% block batch %}
  114. <script>
  115. {% block batch_javascript %}
  116. jQuery(document).ready(function ($) {
  117. // Toggle individual checkboxes when the batch checkbox is changed
  118. $('#list_batch_checkbox').on('ifChanged change', function () {
  119. var checkboxes = $(this)
  120. .closest('table')
  121. .find('td.sonata-ba-list-field-batch input[type="checkbox"], div.sonata-ba-list-field-batch input[type="checkbox"]')
  122. ;
  123. if (window.SONATA_CONFIG.USE_ICHECK) {
  124. checkboxes.iCheck($(this).is(':checked') ? 'check' : 'uncheck');
  125. } else {
  126. checkboxes.prop('checked', this.checked);
  127. }
  128. });
  129. // Add a CSS class to rows when they are selected
  130. $('td.sonata-ba-list-field-batch input[type="checkbox"], div.sonata-ba-list-field-batch input[type="checkbox"]')
  131. .on('ifChanged change', function () {
  132. $(this)
  133. .closest('tr, div.sonata-ba-list-field-batch')
  134. .toggleClass('sonata-ba-list-row-selected', $(this).is(':checked'))
  135. ;
  136. })
  137. .trigger('ifChanged')
  138. ;
  139. });
  140. {% endblock %}
  141. </script>
  142. {% block batch_actions %}
  143. <label class="checkbox" for="{{ admin.uniqid }}_all_elements">
  144. <input type="checkbox" name="all_elements" id="{{ admin.uniqid }}_all_elements">
  145. {{ 'all_elements'|trans({}, 'SonataAdminBundle') }}
  146. ({{ admin.datagrid.pager.nbresults }})
  147. </label>
  148. <select name="action" style="width: auto; height: auto" class="form-control">
  149. {% for action, options in batchactions %}
  150. <option value="{{ action }}">{{ options.label|trans({}, options.translation_domain|default(admin.translationDomain)) }}</option>
  151. {% endfor %}
  152. </select>
  153. {% endblock %}
  154. <input type="submit" class="btn btn-small btn-primary" value="{{ 'btn_batch'|trans({}, 'SonataAdminBundle') }}">
  155. {% endblock %}
  156. {% endif %}
  157. </div>
  158. {# NEXT_MAJOR : remove this assignment #}
  159. {% set export_formats = export_formats|default(admin.exportFormats) %}
  160. <div class="pull-right">
  161. {% if admin.hasRoute('export') and admin.hasAccess('export') and export_formats|length %}
  162. <div class="btn-group">
  163. <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
  164. <i class="fa fa-share-square-o" aria-hidden="true"></i>
  165. {{ "label_export_download"|trans({}, "SonataAdminBundle") }}
  166. <span class="caret"></span>
  167. </button>
  168. <ul class="dropdown-menu">
  169. {% for format in export_formats %}
  170. <li>
  171. <a href="{{ admin.generateUrl('export', admin.modelmanager.paginationparameters(admin.datagrid, 0) + {'format' : format}) }}">
  172. <i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i>
  173. {{ ("export_format_" ~ format)|trans({}, 'SonataAdminBundle') }}
  174. </a>
  175. <li>
  176. {% endfor %}
  177. </ul>
  178. </div>
  179. &nbsp;-&nbsp;
  180. {% endif %}
  181. {% block pager_results %}
  182. {% include admin.getTemplate('pager_results') %}
  183. {% endblock %}
  184. </div>
  185. {% endif %}
  186. </div>
  187. {% block pager_links %}
  188. {% if admin.datagrid.pager.haveToPaginate() %}
  189. <hr/>
  190. {% include admin.getTemplate('pager_links') %}
  191. {% endif %}
  192. {% endblock %}
  193. </div>
  194. {% endif %}
  195. {% endblock %}
  196. </div>
  197. {% if admin.hasRoute('batch') and batchactions|length %}
  198. </form>
  199. {% endif %}
  200. </div>
  201. {% endblock %}
  202. {% block list_filters_actions %}
  203. {%- if admin.datagrid.filters|length %}
  204. <ul class="nav navbar-nav navbar-right">
  205. <li class="dropdown sonata-actions">
  206. <a href="#" class="dropdown-toggle sonata-ba-action" data-toggle="dropdown">
  207. <i class="fa fa-filter" aria-hidden="true"></i>
  208. {{ 'link_filters'|trans({}, 'SonataAdminBundle') }} <b class="caret"></b>
  209. </a>
  210. <ul class="dropdown-menu" role="menu">
  211. {% for filter in admin.datagrid.filters if (filter.options['show_filter'] is same as(true) or filter.options['show_filter'] is null) %}
  212. {% set filterActive = ((filter.isActive() or filter.options['show_filter']) and not admin.isDefaultFilter(filter.formName)) %}
  213. <li>
  214. <a href="#" class="sonata-toggle-filter sonata-ba-action" filter-target="filter-{{ admin.uniqid }}-{{ filter.name }}" filter-container="filter-container-{{ admin.uniqid() }}">
  215. <i class="fa {{ (filter.isActive() or filter.options['show_filter']) ? 'fa-check-square-o' : 'fa-square-o' }}"></i>{{ filter.label|trans({}, filter.translationDomain ?: admin.translationDomain) }}
  216. </a>
  217. </li>
  218. {% endfor %}
  219. </ul>
  220. </li>
  221. </ul>
  222. {% endif -%}
  223. {% endblock %}
  224. {% block list_filters %}
  225. {% if admin.datagrid.filters %}
  226. {% form_theme form admin.getTemplate('filter') %}
  227. <div class="col-xs-12 col-md-12 sonata-filters-box" style="display: {{ admin.datagrid.hasDisplayableFilters ? 'block' : 'none' }}" id="filter-container-{{ admin.uniqid() }}">
  228. <div class="box box-primary" >
  229. <div class="box-body">
  230. <form class="sonata-filter-form form-horizontal {{ admin.isChild and 1 == admin.datagrid.filters|length ? 'hide' : '' }}" action="{{ admin.generateUrl('list') }}" method="GET" role="form">
  231. {{ form_errors(form) }}
  232. <div class="row">
  233. <div class="col-sm-9">
  234. {% set withAdvancedFilter = false %}
  235. {% for filter in admin.datagrid.filters %}
  236. {% set filterActive = ((filter.isActive() and filter.options['show_filter'] is null) or (filter.options['show_filter'] is same as(true))) and not admin.isDefaultFilter(filter.formName) %}
  237. {% set filterVisible = filter.options['show_filter'] is same as(true) or filter.options['show_filter'] is null %}
  238. <div class="form-group {% block sonata_list_filter_group_class %}{% endblock %}" id="filter-{{ admin.uniqid }}-{{ filter.name }}" sonata-filter="{{ filterVisible ? 'true' : 'false' }}" style="display: {% if filterActive %}block{% else %}none{% endif %}">
  239. {% if filter.label is not same as(false) %}
  240. <label for="{{ form.children[filter.formName].children['value'].vars.id }}" class="col-sm-3 control-label">{{ filter.label|trans({}, filter.translationDomain ?: admin.translationDomain) }}</label>
  241. {% endif %}
  242. {% set attr = form.children[filter.formName].children['type'].vars.attr|default({}) %}
  243. <div class="col-sm-4 advanced-filter">
  244. {{ form_widget(form.children[filter.formName].children['type'], {'attr': attr}) }}
  245. </div>
  246. <div class="col-sm-4">
  247. {{ form_widget(form.children[filter.formName].children['value']) }}
  248. </div>
  249. <div class="col-sm-1">
  250. <label class="control-label">
  251. <a href="#" class="sonata-toggle-filter sonata-ba-action" filter-target="filter-{{ admin.uniqid }}-{{ filter.name }}" filter-container="filter-container-{{ admin.uniqid() }}">
  252. <i class="fa fa-minus-circle" aria-hidden="true"></i>
  253. </a>
  254. </label>
  255. </div>
  256. </div>
  257. {% if filter.options['advanced_filter'] %}
  258. {% set withAdvancedFilter = true %}
  259. {% endif %}
  260. {% endfor %}
  261. </div>
  262. <div class="col-sm-3 text-center">
  263. <input type="hidden" name="filter[_page]" id="filter__page" value="1">
  264. {% set foo = form.children['_page'].setRendered() %}
  265. {{ form_rest(form) }}
  266. <div class="form-group">
  267. <button type="submit" class="btn btn-primary">
  268. <i class="fa fa-filter" aria-hidden="true"></i> {{ 'btn_filter'|trans({}, 'SonataAdminBundle') }}
  269. </button>
  270. <a class="btn btn-default" href="{{ admin.generateUrl('list', {filters: 'reset'}) }}">
  271. {{ 'link_reset_filter'|trans({}, 'SonataAdminBundle') }}
  272. </a>
  273. </div>
  274. {% if withAdvancedFilter %}
  275. <div class="form-group">
  276. <a href="#" data-toggle="advanced-filter">
  277. <i class="fa fa-cogs" aria-hidden="true"></i>
  278. {{ 'btn_advanced_filters'|trans({}, 'SonataAdminBundle') }}
  279. </a>
  280. </div>
  281. {% endif %}
  282. </div>
  283. </div>
  284. {% for paramKey, paramValue in admin.persistentParameters %}
  285. <input type="hidden" name="{{ paramKey }}" value="{{ paramValue }}">
  286. {% endfor %}
  287. </form>
  288. </div>
  289. </div>
  290. </div>
  291. {% endif %}
  292. {% endblock %}