This commit is contained in:
Xes
2025-08-14 22:41:49 +02:00
parent 2de81ccc46
commit 8ce45119b6
39774 changed files with 4309466 additions and 0 deletions

View File

@@ -0,0 +1,244 @@
{#
This file is part of the Sonata package.
(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% spaceless %}
<input type="text" id="{{ id }}_autocomplete_input" value=""
{%- if read_only is defined and read_only %} readonly="readonly"{% endif -%}
{%- if disabled %} disabled="disabled"{% endif -%}
{%- if required %} required="required"{% endif %}
/>
<select id="{{ id }}_autocomplete_input_v4" data-sonata-select2="false"
{%- if read_only is defined and read_only %} readonly="readonly"{% endif -%}
{%- if disabled %} disabled="disabled"{% endif -%}
{%- if required %} required="required"{% endif %}
>
{%- for idx, val in value if idx~'' != '_labels' -%}
<option value="{{ val }}" selected>{{ value['_labels'][idx] }}</option>
{%- endfor -%}
</select>
<div id="{{ id }}_hidden_inputs_wrap">
{% if multiple -%}
{%- for idx, val in value if idx~'' != '_labels' -%}
<input type="hidden" name="{{ full_name }}[]" {%- if disabled %} disabled="disabled"{% endif %} value="{{ val }}">
{%- endfor -%}
{% else -%}
<input type="hidden" name="{{ full_name }}" {%- if disabled %} disabled="disabled"{% endif %} value="{{ value[0]|default('') }}">
{% endif -%}
</div>
<script>
{% autoescape 'js' %}
jQuery(function ($) {
// Select2 v3 does not used same input as v4.
// NEXT_MAJOR: Remove this BC layer while upgrading to v4.
var usedInputRef = window.Select2 ? '#{{ id }}_autocomplete_input' : '#{{ id }}_autocomplete_input_v4';
var unusedInputRef = window.Select2 ? '#{{ id }}_autocomplete_input_v4' : '#{{ id }}_autocomplete_input';
$(unusedInputRef).remove();
var autocompleteInput = $(usedInputRef);
var select2Options = {
{%- set allowClearPlaceholder = (not multiple and not required) ? ' ' : '' -%}
placeholder: '{{ placeholder ?: allowClearPlaceholder }}', // allowClear needs placeholder to work properly
allowClear: {{ required ? 'false' : 'true' }},
enable: {{ disabled ? 'false' : 'true' }},
readonly: {{ read_only is defined and read_only or attr.readonly is defined and attr.readonly ? 'true' : 'false' }},
minimumInputLength: {{ minimum_input_length }},
multiple: {{ multiple ? 'true' : 'false' }},
width: function() {
// Select2 v3 and v4 BC. If window.Select2 is defined, then the v3 is installed.
// NEXT_MAJOR: Remove Select2 v3 support.
return Admin.get_select2_width(window.Select2 ? this.element : jQuery(this));
},
dropdownAutoWidth: {{ dropdown_auto_width ? 'true' : 'false' }},
containerCssClass: '{{ container_css_class ~ ' form-control' }}',
dropdownCssClass: '{{ dropdown_css_class }}',
ajax: {
url: '{{ url ?: path(route.name, route.parameters|default([])) }}',
dataType: 'json',
quietMillis: {{ quiet_millis }},
cache: {{ cache ? 'true' : 'false' }},
data: function (term, page) { // page is the one-based page number tracked by Select2
// Select2 v4 got a "params" unique argument
// NEXT_MAJOR: Remove this BC layer.
if (typeof page === 'undefined') {
page = typeof term.page !== 'undefined' ? term.page : 1;
term = term.term;
}
{% block sonata_type_model_autocomplete_ajax_request_parameters %}
return {
//search term
'{{ req_param_name_search }}': term,
// page size
'{{ req_param_name_items_per_page }}': {{ items_per_page }},
// page number
'{{ req_param_name_page_number }}': page,
// admin
{% if sonata_admin.admin is not null %}
'uniqid': '{{ sonata_admin.admin.uniqid }}',
'admin_code': '{{ sonata_admin.admin.code }}',
{% elseif admin_code %}
'admin_code': '{{ admin_code }}',
{% endif %}
// subclass
{% if app.request.query.get('subclass') %}
'subclass': '{{ app.request.query.get('subclass') }}',
{% endif %}
{% if context == 'filter' %}
'field': '{{ full_name|replace({'filter[': '', '][value]': '', '__':'.'}) }}',
'_context': 'filter'
{% else %}
'field': '{{ name }}'
{% endif %}
// other parameters
{% if req_params is not empty %},
{%- for key, value in req_params -%}
'{{- key -}}': '{{- value -}}'
{%- if not loop.last -%}, {% endif -%}
{%- endfor -%}
{% endif %}
};
{% endblock %}
},
},
escapeMarkup: function (m) { return m; } // we do not want to escape markup since we are displaying html in results
};
// Select2 v3/v4 special options.
// NEXT_MAJOR: Remove this BC layer while upgrading to v4.
var templateResult = function (item) {
return {% block sonata_type_model_autocomplete_dropdown_item_format %}'<div class="{{ dropdown_item_css_class }}">'+item.label+'<\/div>'{% endblock %};// format of one dropdown item
};
var templateSelection = function (item) {
// Select2 v4 BC select pre-selection.
if (typeof item.label === 'undefined') {
item.label = item.text;
}
return {% block sonata_type_model_autocomplete_selection_format %}item.label{% endblock %};// format selected item '<b>'+item.label+'</b>';
};
if (window.Select2) {
select2Options.initSelection = function (element, callback) {
callback(element.val());
};
select2Options.ajax.results = function (data, page) {
// notice we return the value of more so Select2 knows if more results can be loaded
return {results: data.items, more: data.more};
};
select2Options.formatResult = templateResult;
select2Options.formatSelection = templateSelection;
} else {
select2Options.ajax.processResults = function (data, params) {
return {
results: data.items,
pagination: {
more: data.more
}
};
};
select2Options.templateResult = templateResult;
select2Options.templateSelection = templateSelection;
}
// END Select2 v3/v4 special options
autocompleteInput.select2(select2Options);
// Events structure is different between v3 and v4
// NEXT_MAJOR: Remove BC layer.
var boundEvents = window.Select2 ? 'change' : 'select2:select select2:unselect';
autocompleteInput.on(boundEvents, function(e) {
if (e.type === 'select2:select') {
e.added = e.params.data;
}
if (e.type === 'select2:unselect') {
e.removed = e.params.data;
}
// console.log('change '+JSON.stringify({val:e.val, added:e.added, removed:e.removed}));
// remove input
if (undefined !== e.removed && null !== e.removed) {
var removedItems = e.removed;
{% if multiple %}
if(!$.isArray(removedItems)) {
removedItems = [removedItems];
}
var length = removedItems.length;
for (var i = 0; i < length; i++) {
el = removedItems[i];
$('#{{ id }}_hidden_inputs_wrap input:hidden[value="'+el.id+'"]').remove();
}
{%- else -%}
$('#{{ id }}_hidden_inputs_wrap input:hidden').val('');
{%- endif %}
}
// add new input
var el = null;
if (undefined !== e.added) {
var addedItems = e.added;
{% if multiple %}
if(!$.isArray(addedItems)) {
addedItems = [addedItems];
}
var length = addedItems.length;
for (var i = 0; i < length; i++) {
el = addedItems[i];
$('#{{ id }}_hidden_inputs_wrap').append('<input type="hidden" name="{{ full_name }}[]" value="'+el.id+'" />');
}
{%- else -%}
$('#{{ id }}_hidden_inputs_wrap input:hidden').val(addedItems.id);
{%- endif %}
}
});
// Initialise the autocomplete
var data = [];
{%- if value is not empty -%}
data = {%- if multiple -%}[ {%- endif -%}
{%- for idx, val in value if idx~'' != '_labels' -%}
{%- if not loop.first -%}, {% endif -%}
{id: '{{ val }}', label:'{{ value['_labels'][idx] }}'}
{%- endfor -%}
{%- if multiple -%} ] {%- endif -%};
{% endif -%}
// Select2 v3 data populate.
// NEXT_MAJOR: Remove while dropping v3 support.
if (window.Select2 && (undefined==data.length || 0<data.length)) { // Leave placeholder if no data set
autocompleteInput.select2('data', data);
}
// remove unneeded autocomplete text input before form submit
$(usedInputRef).closest('form').submit(function()
{
$(usedInputRef).remove();
return true;
});
});
{% endautoescape %}
</script>
{% endspaceless %}

View File

@@ -0,0 +1,93 @@
{#
This file is part of the Sonata package.
(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% extends 'form_div_layout.html.twig' %}
{#
Inspired from MopaBootstrapBundle: https://github.com/phiamo/MopaBootstrapBundle
#}
{% block choice_widget_collapsed %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
{{ parent() }}
{% endblock choice_widget_collapsed %}
{% block textarea_widget %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
{{ parent() }}
{% endblock textarea_widget %}
{% block form_widget_simple %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
{{ parent() }}
{% endblock form_widget_simple %}
{% block choice_widget_expanded %}
{% spaceless %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default(''))}) %}
{% set label_attr = label_attr|merge({'class': (label_attr.class ~ ' ' ~ (widget_type is defined and widget_type != '' ? (multiple ? 'checkbox' : 'radio') ~ '-' ~ widget_type : ''))}) %}
{% if expanded %}
{% set attr = attr|merge({'class': attr.class|default('')}) %}
<div {{ block('widget_container_attributes') }}>
{% endif %}
{% for child in form %}
{% if widget_type is defined and widget_type != 'inline' %}
<div class="{{ multiple ? 'checkbox' : 'radio' }}">
{% endif %}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
{{ form_widget(child, {'attr': {'class': attr.widget_class|default('')}}) }}
{{ child.vars.label|trans({}, translation_domain) }}
</label>
{% if widget_type is defined and widget_type != 'inline' %}
</div>
{% endif %}
{% endfor %}
{% if block('form_message') is defined %}
{{ block('form_message') }}
{% endif %}
{% if expanded %}
</div>
{% endif %}
{% endspaceless %}
{% endblock choice_widget_expanded %}
{% block checkbox_widget %}
{% spaceless %}
{% if label is not same as(false) and label is empty %}
{% set label = name|humanize %}
{% endif %}
{% if form.parent != null and 'choice' not in form.parent.vars.block_prefixes %}
<div class="checkbox">
{% endif %}
{% if form.parent != null and 'choice' not in form.parent.vars.block_prefixes and label_render is defined %}
<label class="{% if inline is defined and inline %}checkbox-inline{% endif %}">
{% endif %}
<input type="checkbox" {{ block('widget_attributes') }}{% if value is defined %} value="{{ value }}"{% endif %}{% if checked %} checked="checked"{% endif %}/>
{% if form.parent != null and 'choice' not in form.parent.vars.block_prefixes %}
{% if label_render is defined and widget_checkbox_label in ['both', 'widget'] %}
{{ label|trans({}, translation_domain) }}
</label>
{% endif %}
{% endif %}
{% if form.parent != null and 'choice' not in form.parent.vars.block_prefixes %}
</div>
{% if block('form_message') is defined %}
{{ block('form_message') }}
{% endif %}
{% endif %}
{% endspaceless %}
{% endblock checkbox_widget %}
{% block sonata_type_model_autocomplete_widget %}
{% include template %}
{% endblock sonata_type_model_autocomplete_widget %}

View File

@@ -0,0 +1,520 @@
{#
This file is part of the Sonata package.
(c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{% extends 'form_div_layout.html.twig' %}
{% block form_errors -%}
{% if errors|length > 0 %}
{% if not form.parent %}<div class="alert alert-danger">{% endif %}
<ul class="list-unstyled">
{% for error in errors %}
<li><i class="fa fa-exclamation-circle" aria-hidden="true"></i> {{ error.message }}</li>
{% endfor %}
</ul>
{% if not form.parent %}</div>{% endif %}
{% endif %}
{%- endblock form_errors %}
{% block sonata_help %}
{% spaceless %}
{% if sonata_help is defined and sonata_help %}
<span class="help-block sonata-ba-field-widget-help">{{ sonata_help|raw }}</span>
{% endif %}
{% endspaceless %}
{% endblock %}
{% block form_widget -%}
{{ parent() }}
{{ block('sonata_help') }}
{%- endblock form_widget %}
{% block form_widget_simple %}
{% set type = type|default('text') %}
{% if type != 'file' %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
{% endif %}
{{ parent() }}
{% endblock form_widget_simple %}
{% block textarea_widget %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
{{ parent() }}
{% endblock textarea_widget %}
{% block money_widget -%}
{% if money_pattern == '{{ widget }}' %}
{{- block('form_widget_simple') -}}
{% else %}
{% set currencySymbol = money_pattern|replace({'{{ widget }}': ''})|trim %}
{% if money_pattern matches '/^{{ widget }}/' %}
<div class="input-group">
{{- block('form_widget_simple') -}}
<span class="input-group-addon">{{ currencySymbol }}</span>
</div>
{% elseif money_pattern matches '/{{ widget }}$/' %}
<div class="input-group">
<span class="input-group-addon">{{ currencySymbol }}</span>
{{- block('form_widget_simple') -}}
</div>
{% endif %}
{% endif %}
{%- endblock money_widget %}
{% block percent_widget %}
{% spaceless %}
{% set type = type|default('text') %}
<div class="input-group">
{{ block('form_widget_simple') }}
<span class="input-group-addon">%</span>
</div>
{% endspaceless %}
{% endblock percent_widget %}
{% block checkbox_widget -%}
{% set parent_label_class = parent_label_class|default('') -%}
{% if 'checkbox-inline' in parent_label_class %}
{{- form_label(form, null, { widget: parent() }) -}}
{% else -%}
<div class="checkbox">
{{- form_label(form, null, { widget: parent() }) -}}
</div>
{%- endif %}
{%- endblock checkbox_widget %}
{% block radio_widget -%}
{%- set parent_label_class = parent_label_class|default('') -%}
{% if 'radio-inline' in parent_label_class %}
{{- form_label(form, null, { widget: parent() }) -}}
{% else -%}
<div class="radio">
{{- form_label(form, null, { widget: parent() }) -}}
</div>
{%- endif %}
{%- endblock radio_widget %}
{# Labels #}
{% block form_label %}
{% spaceless %}
{% if label is not same as(false) and sonata_admin.options['form_type'] == 'horizontal' %}
{% set label_class = 'col-sm-3' %}
{% endif %}
{% set label_class = label_class|default('') ~ ' control-label' %}
{% if label is not same as(false) %}
{% set label_attr = label_attr|merge({'class': label_attr.class|default('') ~ ' ' ~ label_class }) %}
{% if not compound %}
{% set label_attr = label_attr|merge({'for': id}) %}
{% endif %}
{% if required %}
{% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %}
{% endif %}
{% if label is empty %}
{%- if label_format is defined and label_format is not empty -%}
{% set label = label_format|replace({
'%name%': name,
'%id%': id,
}) %}
{%- else -%}
{% set label = name|humanize %}
{%- endif -%}
{% endif %}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
{% if translation_domain is same as(false) %}
{{- label -}}
{% elseif not sonata_admin.admin %}
{{- label|trans({}, translation_domain) -}}
{% else %}
{{ label|trans({}, sonata_admin.field_description.translationDomain ?: admin.translationDomain) }}
{% endif %}
</label>
{% endif %}
{% endspaceless %}
{% endblock form_label %}
{% block checkbox_label -%}
{{- block('checkbox_radio_label') -}}
{%- endblock checkbox_label %}
{% block radio_label -%}
{{- block('checkbox_radio_label') -}}
{%- endblock radio_label %}
{% block checkbox_radio_label %}
{% if sonata_admin.admin %}
{% set translation_domain = sonata_admin.field_description.translationDomain %}
{% endif %}
{# Do not display the label if widget is not defined in order to prevent double label rendering #}
{% if widget is defined %}
{% if required %}
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' required')|trim}) %}
{% endif %}
{% if parent_label_class is defined %}
{% set label_attr = label_attr|merge({class: (label_attr.class|default('') ~ ' ' ~ parent_label_class)|trim}) %}
{% endif %}
{% if label is not same as(false) and label is empty %}
{% set label = name|humanize %}
{% endif %}
<label{% for attrname, attrvalue in label_attr %} {{ attrname }}="{{ attrvalue }}"{% endfor %}>
{{- widget|raw -}}
{%- if label is not same as(false) -%}
<span class="control-label__text">
{{- label|trans({}, translation_domain) -}}
</span>
{%- endif -%}
</label>
{% endif %}
{% endblock checkbox_radio_label %}
{% block choice_widget_expanded %}
{% spaceless %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' list-unstyled'}) %}
<ul {{ block('widget_container_attributes') }}>
{% for child in form %}
<li>
{{ form_widget(child, {'horizontal': false, 'horizontal_input_wrapper_class': ''}) }} {# {'horizontal': false, 'horizontal_input_wrapper_class': ''} needed to avoid MopaBootstrapBundle messing with the DOM #}
</li>
{% endfor %}
</ul>
{% endspaceless %}
{% endblock choice_widget_expanded %}
{% block choice_widget_collapsed %}
{% spaceless %}
{% if required and placeholder is defined and placeholder is none %}
{% set required = false %}
{% elseif required and empty_value is defined and empty_value_in_choices is defined and empty_value is none and not empty_value_in_choices and not multiple %}
{% set required = false %}
{% endif %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' form-control'}) %}
{% if (sortable is defined) and sortable and multiple %}
{{ block('sonata_type_choice_multiple_sortable') }}
{% else %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %} >
{% if empty_value is defined and empty_value is not none %}
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>
{% if not sonata_admin.admin %}
{{- empty_value|trans({}, translation_domain) -}}
{% else %}
{{- empty_value|trans({}, sonata_admin.field_description.translationDomain) -}}
{% endif%}
</option>
{% elseif placeholder is defined and placeholder is not none %}
<option value=""{% if required and value is empty %} selected="selected"{% endif %}>
{% if not sonata_admin.admin %}
{{- placeholder|trans({}, translation_domain) -}}
{% else %}
{{- placeholder|trans({}, sonata_admin.field_description.translationDomain) -}}
{% endif%}
</option>
{% endif %}
{% if preferred_choices|length > 0 %}
{% set options = preferred_choices %}
{{ block('choice_widget_options') }}
{% if choices|length > 0 %}
<option disabled="disabled">{{ separator }}</option>
{% endif %}
{% endif %}
{% set options = choices %}
{{ block('choice_widget_options') }}
</select>
{% endif %}
{% endspaceless %}
{% endblock choice_widget_collapsed %}
{% block date_widget %}
{% spaceless %}
{% if widget == 'single_text' %}
{{ block('form_widget_simple') }}
{% else %}
{% if row is not defined or row == true %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' row' }) %}
{% endif %}
{% set input_wrapper_class = input_wrapper_class|default('col-sm-4') %}
<div {{ block('widget_container_attributes') }}>
{{ date_pattern|replace({
'{{ year }}': '<div class="'~ input_wrapper_class ~ '">' ~ form_widget(form.year) ~ '</div>',
'{{ month }}': '<div class="'~ input_wrapper_class ~ '">' ~ form_widget(form.month) ~ '</div>',
'{{ day }}': '<div class="'~ input_wrapper_class ~ '">' ~ form_widget(form.day) ~ '</div>',
})|raw }}
</div>
{% endif %}
{% endspaceless %}
{% endblock date_widget %}
{% block time_widget %}
{% spaceless %}
{% if widget == 'single_text' %}
{{ block('form_widget_simple') }}
{% else %}
{% if row is not defined or row == true %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' row' }) %}
{% endif %}
{% set input_wrapper_class = input_wrapper_class|default('col-sm-6') %}
<div {{ block('widget_container_attributes') }}>
<div class="{{ input_wrapper_class }}">
{{ form_widget(form.hour) }}
</div>
{% if with_minutes %}
<div class="{{ input_wrapper_class }}">
{{ form_widget(form.minute) }}
</div>
{% endif %}
{% if with_seconds %}
<div class="{{ input_wrapper_class }}">
{{ form_widget(form.second) }}
</div>
{% endif %}
</div>
{% endif %}
{% endspaceless %}
{% endblock time_widget %}
{% block datetime_widget %}
{% spaceless %}
{% if widget == 'single_text' %}
{{ block('form_widget_simple') }}
{% else %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' row' }) %}
<div {{ block('widget_container_attributes') }}>
{{ form_errors(form.date) }}
{{ form_errors(form.time) }}
{% if form.date.vars.widget == 'single_text' %}
<div class="col-sm-2">
{{ form_widget(form.date) }}
</div>
{% else %}
{{ form_widget(form.date, {'row': false, 'input_wrapper_class': 'col-sm-2'}) }}
{% endif %}
{% if form.time.vars.widget == 'single_text' %}
<div class="col-sm-2">
{{ form_widget(form.time) }}
</div>
{% else %}
{{ form_widget(form.time, {'row': false, 'input_wrapper_class': 'col-sm-2'}) }}
{% endif %}
</div>
{% endif %}
{% endspaceless %}
{% endblock datetime_widget %}
{% block form_row %}
{% set show_label = show_label|default(true) %}
<div class="form-group{% if errors|length > 0 %} has-error{% endif %}" id="sonata-ba-field-container-{{ id }}">
{% if sonata_admin.field_description.options is defined %}
{% set label = sonata_admin.field_description.options.name|default(label) %}
{% endif %}
{% set div_class = 'sonata-ba-field' %}
{% if label is same as(false) %}
{% set div_class = div_class ~ ' sonata-collection-row-without-label' %}
{% endif %}
{% if sonata_admin is defined and sonata_admin.options['form_type'] == 'horizontal' %}
{# Add an offset if no label or is a checkbox/radio #}
{% if label is same as(false) or form.vars.checked is defined %}
{% if 'collection' in form.parent.vars.block_prefixes %}
{% set div_class = div_class ~ ' col-sm-12' %}
{% else %}
{% set div_class = div_class ~ ' col-sm-9 col-sm-offset-3' %}
{% endif %}
{% else %}
{% set div_class = div_class ~ ' col-sm-9' %}
{% endif %}
{% endif %}
{% if show_label %}
{{ form_label(form, label|default(null)) }}
{% endif %}
{% if sonata_admin is defined and sonata_admin_enabled %}
{% set div_class = div_class ~ ' sonata-ba-field-' ~ sonata_admin.edit ~ '-' ~ sonata_admin.inline %}
{% endif %}
{% if errors|length > 0 %}
{% set div_class = div_class ~ ' sonata-ba-field-error' %}
{% endif %}
<div class="{{ div_class }}">
{{ form_widget(form, {'horizontal': false, 'horizontal_input_wrapper_class': ''}) }} {# {'horizontal': false, 'horizontal_input_wrapper_class': ''} needed to avoid MopaBootstrapBundle messing with the DOM #}
{% if errors|length > 0 %}
<div class="help-block sonata-ba-field-error-messages">
{{ form_errors(form) }}
</div>
{% endif %}
{% if sonata_admin is defined and sonata_admin_enabled and sonata_admin.field_description.help|default(false) %}
<span class="help-block sonata-ba-field-help">{{ sonata_admin.field_description.help|trans({}, sonata_admin.field_description.translationDomain ?: admin.translationDomain)|raw }}</span>
{% endif %}
</div>
</div>
{% endblock form_row %}
{% block checkbox_row -%}
{% set show_label = false %}
{{ block('form_row') }}
{%- endblock checkbox_row %}
{% block radio_row -%}
{% set show_label = false %}
{{ block('form_row') }}
{%- endblock radio_row %}
{% block sonata_type_native_collection_widget_row %}
{% spaceless %}
<div class="sonata-collection-row">
{% if allow_delete %}
<div class="row">
<div class="col-xs-1">
<a href="#" class="btn btn-link sonata-collection-delete">
<i class="fa fa-minus-circle" aria-hidden="true"></i>
</a>
</div>
<div class="col-xs-11">
{% endif %}
{{ form_row(child, { label: false }) }}
{% if allow_delete %}
</div>
</div>
{% endif %}
</div>
{% endspaceless %}
{% endblock sonata_type_native_collection_widget_row %}
{% block sonata_type_native_collection_widget %}
{% spaceless %}
{% if prototype is defined %}
{% set child = prototype %}
{% set allow_delete_backup = allow_delete %}
{% set allow_delete = true %}
{% set attr = attr|merge({'data-prototype': block('sonata_type_native_collection_widget_row'), 'data-prototype-name': prototype.vars.name, 'class': attr.class|default('') }) %}
{% set allow_delete = allow_delete_backup %}
{% endif %}
<div {{ block('widget_container_attributes') }}>
{{ form_errors(form) }}
{% for child in form %}
{{ block('sonata_type_native_collection_widget_row') }}
{% endfor %}
{{ form_rest(form) }}
{% if allow_add %}
<div><a href="#" class="btn btn-link sonata-collection-add"><i class="fa fa-plus-circle" aria-hidden="true"></i></a></div>
{% endif %}
</div>
{% endspaceless %}
{% endblock sonata_type_native_collection_widget %}
{% block sonata_type_immutable_array_widget %}
{% spaceless %}
<div {{ block('widget_container_attributes') }}>
{{ block('sonata_help') }}
{{ form_errors(form) }}
{% for key, child in form %}
{{ block('sonata_type_immutable_array_widget_row') }}
{% endfor %}
{{ form_rest(form) }}
</div>
{% endspaceless %}
{% endblock sonata_type_immutable_array_widget %}
{% block sonata_type_immutable_array_widget_row %}
{% spaceless %}
<div class="form-group{% if child.vars.errors|length > 0%} has-error{%endif%}" id="sonata-ba-field-container-{{ id }}-{{ key }}">
{{ form_label(child) }}
{% set div_class = "" %}
{% if sonata_admin.options['form_type'] == 'horizontal' %}
{% set div_class = 'col-sm-9' %}
{% endif%}
<div class="{{ div_class }} sonata-ba-field sonata-ba-field-{{ sonata_admin.edit }}-{{ sonata_admin.inline }} {% if child.vars.errors|length > 0 %}sonata-ba-field-error{% endif %}">
{{ form_widget(child, {'horizontal': false, 'horizontal_input_wrapper_class': ''}) }} {# {'horizontal': false, 'horizontal_input_wrapper_class': ''} needed to avoid MopaBootstrapBundle messing with the DOM #}
{% set sonata_help = child.vars.sonata_help %}
{{ block('sonata_help') }}
</div>
{% if child.vars.errors|length > 0 %}
<div class="help-block sonata-ba-field-error-messages">
{{ form_errors(child) }}
</div>
{% endif %}
</div>
{% endspaceless %}
{% endblock %}
{% block sonata_type_model_autocomplete_widget %}
{% include template %}
{% endblock sonata_type_model_autocomplete_widget %}
{% block sonata_type_choice_field_mask_widget %}
{{ block('choice_widget') }}
{# Taking the form name excluding ending field glue character #}
{% set main_form_name = id|slice(0, (id|length - name|length)-1) %}
<script>
jQuery(document).ready(function() {
var allFields = {{ all_fields|json_encode|raw }};
var map = {{ map|json_encode|raw }};
var showMaskChoiceEl = jQuery('#{{ main_form_name }}_{{ name }}');
showMaskChoiceEl.on('change', function () {
choice_field_mask_show(jQuery(this).val());
});
function choice_field_mask_show(val) {
var controlGroupIdFunc = function (field) {
// Most of fields are named with an underscore
var defaultFieldId = '#sonata-ba-field-container-{{ main_form_name }}_' + field;
// Some fields may be named with a dash (like keys of immutable array form type)
if (jQuery(defaultFieldId).length === 0) {
return '#sonata-ba-field-container-{{ main_form_name }}-' + field;
}
return defaultFieldId;
};
jQuery.each(allFields, function (i, field) {
jQuery(controlGroupIdFunc(field)).hide();
});
if (map[val]) {
jQuery.each(map[val], function (i, field) {
jQuery(controlGroupIdFunc(field)).show();
});
}
}
choice_field_mask_show(showMaskChoiceEl.val());
});
</script>
{% endblock %}
{% block sonata_type_choice_multiple_sortable %}
<input type="hidden" name="{{ full_name }}" id="{{ id }}" value="{{ value|join(',') }}" />
<script>
jQuery(document).ready(function() {
Admin.setup_sortable_select2(jQuery('#{{ id }}'), {{ form.vars.choices|json_encode|raw }});
});
</script>
{% endblock %}

View File

@@ -0,0 +1,106 @@
{# Widgets #}
{#
This file doesn't seem to be used anymore ; commenting it for now in order not to mess with user's configurations.
TODO: Remove it and all of its references
#}
{#
{% block choice_widget %}
{% spaceless %}
{% if expanded %}
<ul {{ block('widget_container_attributes') }} class="inputs-list">
{% for child in form %}
<li>
{% set form_widget_content %}
{{ form_widget(child) }}
{% endset %}
{{ form_label(child, null, { 'in_list_checkbox' : true, 'widget' : form_widget_content } ) }}
</li>
{% endfor %}
</ul>
{% else %}
<select {{ block('widget_attributes') }}{% if multiple %} multiple="multiple"{% endif %}>
{% if empty_value is not none %}
<option value="">{{ empty_value|trans({}, translation_domain) }}</option>
{% endif %}
{% if preferred_choices|length > 0 %}
{% set options = preferred_choices %}
{{ block('choice_widget_options') }}
{% if choices|length > 0 and separator is not none %}
<option disabled="disabled">{{ separator }}</option>
{% endif %}
{% endif %}
{% set options = choices %}
{{ block('choice_widget_options') }}
</select>
{% endif %}
{% endspaceless %}
{% endblock choice_widget %}
{% block form_widget_simple %}
{% spaceless %}
{% set type = type|default('text') %}
<input type="{{ type }}" {{ block('widget_attributes') }} value="{{ value }}">
{% endspaceless %}
{% endblock form_widget_simple %}
&#123;&#35; Labels &#35;&#125;
{% block form_label %}
{% spaceless %}
{% if not compound %}
{% set attr = attr|merge({'for': id}) %}
{% endif %}
{% if required %}
{% set attr = attr|merge({'class': attr.class|default('') ~ ' required'}) %}
{% endif %}
{% if in_list_checkbox is defined and in_list_checkbox and widget is defined %}
<label{% for attrname,attrvalue in attr %} {{attrname}}="{{attrvalue}}"{% endfor %}>
{{ widget|raw }}
<span>
{{ label|trans({}, translation_domain) }}
</span>
</label>
{% else %}
<label{% for attrname,attrvalue in attr %} {{attrname}}="{{attrvalue}}"{% endfor %}>{{ label|trans({}, translation_domain) }}</label>
{% endif %}
{% endspaceless %}
{% endblock %}
&#123;&#35; Rows &#35;&#125;
{% block form_row %}
{% spaceless %}
<div class="form-group {{ (0 < form_errors(form)|length)? 'has-error':'' }} ">
{{ form_label(form, label|default(null)) }}
<div class="col-sm-10 col-md-5">
{{ form_widget(form) }}
{{ form_errors(form) }}
</div>
</div>
{% endspaceless %}
{% endblock form_row %}
&#123;&#35; Misc &#35;&#125;
{% block form_errors %}
{% spaceless %}
{% if errors|length > 0 %}
{% if not form.parent or 'repeated' in form.vars['block_prefixes'] %}
<div class="form-group has-error">
{% endif %}
<span class="help-block">
{% for error in errors %}
{% if loop.first %}
{{ error.messageTemplate|trans(error.messageParameters, 'validators') }}
{% endif %}
{% endfor %}
</span>
{% if not form.parent or 'repeated' in form.vars['block_prefixes'] %}
</div>
{% endif %}
{% endif %}
{% endspaceless %}
{% endblock form_errors %}
#}