Move optional twig form macro attributes to opt

This commit is contained in:
Michael Weimann 2023-04-19 22:34:08 +02:00 committed by Igor Scheller
parent c0957955fd
commit dc216a0464
19 changed files with 541 additions and 299 deletions

View File

@ -14,7 +14,10 @@
<form method="post" action="{{ url('/admin/logs') }}" class="form-inline">
{{ csrf() }}
{{ f.input('search', __('form.search'), 'text', {'value': search, 'hide_label': true}) }}
{{ f.input('search', __('form.search'), {
'value': search,
'hide_label': true,
}) }}
{{ f.submit(__('form.search')) }}
</form>

View File

@ -11,26 +11,26 @@
<div class="row">
<div class="col-lg-6">
{{ f.input(
'name',
__('room.name'),
null,
{'required': true, 'entry_required_icon': true, 'value': f.formData('room', room ? room.name : '')}
) }}
{{ f.input('name', __('room.name'), {
'required': true,
'required_icon': true,
'value': f.formData('room', room ? room.name : ''),
}) }}
{{ f.input('dect', __('room.dect'), null, {'value': f.formData('dect', room ? room.dect : '')}) }}
{{ f.input(
'map_url',
__('room.map_url'),
'url',
{'value': f.formData('map_url', room ? room.map_url : ''), 'info': __('room.map_url.info')}
) }}
{{ f.input('dect', __('room.dect'), {
'value': f.formData('dect', room ? room.dect : ''),
}) }}
{{ f.input('map_url', __('room.map_url'), {
'type': 'url',
'value': f.formData('map_url', room ? room.map_url : ''),
'info': __('room.map_url.info'),
}) }}
{{ f.textarea(
'description',
__('room.description'),
{'value': f.formData('description', room ? room.description : ''), 'rows': 5, 'info': __('form.markdown')}
) }}
{{ f.textarea('description', __('room.description'), {
'value': f.formData('description', room ? room.description : ''),
'rows': 5,
'info': __('form.markdown')
}) }}
</div>
<div class="col-lg-6">
@ -41,11 +41,11 @@
{% set needed = needed_angel_types ? needed_angel_types.where('angel_type_id', angel_type.id).first() : null %}
{% set name = 'angel_type_' ~ angel_type.id %}
<div class="col-md-4">
{{ f.number(
name,
angel_type.name,
{'value': f.formData(name, needed ? needed.count : 0), 'min': 0, 'step': 1}
) }}
{{ f.number(name, angel_type.name, {
'value': f.formData(name, needed ? needed.count : 0),
'min': 0,
'step': 1,
}) }}
</div>
{% endfor %}
</div>

View File

@ -15,13 +15,30 @@
{{ csrf() }}
<div class="col-lg-12">
{{ f.input('name', __('schedule.name'), null, {'required': true, 'value': schedule ? schedule.name : ''}) }}
{{ f.input('url', __('schedule.url'), 'url', {'required': true, 'value': schedule ? schedule.url : ''}) }}
{{ f.input('name', __('schedule.name'), {
'required': true,
'value': schedule ? schedule.name : '',
}) }}
{{ f.input('url', __('schedule.url'), {
'type': 'url',
'required': true,
'value': schedule ? schedule.url : ''
}) }}
{{ f.select('shift_type', shift_types|default([]), __('schedule.shift-type'), schedule ? schedule.shift_type : '') }}
{{ f.select('shift_type', __('schedule.shift-type'), shift_types|default([]), {
'selected': schedule ? schedule.shift_type : '',
}) }}
{{ f.input('minutes_before', __('schedule.minutes-before'), 'number', {'required': true, 'value': schedule ? schedule.minutes_before : 15}) }}
{{ f.input('minutes_after', __('schedule.minutes-after'), 'number', {'required': true, 'value': schedule ? schedule.minutes_after : 15}) }}
{{ f.input('minutes_before', __('schedule.minutes-before'), {
'type': 'number',
'required': true,
'value': schedule ? schedule.minutes_before : 15
}) }}
{{ f.input('minutes_after', __('schedule.minutes-after'), {
'type': 'number',
'required': true,
'value': schedule ? schedule.minutes_after : 15
}) }}
{{ f.submit(__('form.save')) }}
</div>

View File

@ -18,19 +18,31 @@
<div class="row">
{% if is_tshirt %}
<div class="col-md-6">
{{ f.select('shirt_size', config('tshirt_sizes'), __('user.shirt_size'), userdata.personalData.shirt_size) }}
{{ f.select('shirt_size', __('user.shirt_size'), config('tshirt_sizes'), {
'selected': userdata.personalData.shirt_size,
}) }}
</div>
{% endif %}
<div class="col-md-6">
{{ f.switch('arrived', __('user.arrived'), userdata.state.arrived, {'disabled': not has_permission_to('admin_arrive')}) }}
{{ f.switch('arrived', __('user.arrived'), {
'checked': userdata.state.arrived,
'disabled': not has_permission_to('admin_arrive'),
}) }}
{% if userdata.state.force_active %}
{{ f.switch('force_active', __('user.force_active'), true, {'disabled': true}) }}
{{ f.switch('force_active', __('user.force_active'), {
'checked': true,
'disabled': true,
}) }}
{% endif %}
{{ f.switch('active', __('user.active'), userdata.state.active) }}
{{ f.switch('active', __('user.active'), {
'checked': userdata.state.active,
}) }}
{{ f.switch('got_shirt', is_tshirt ? __('user.got_shirt') : __('user.got_goodie'), userdata.state.got_shirt) }}
{{ f.switch('got_shirt', is_tshirt ? __('user.got_shirt') : __('user.got_goodie'), {
'checked': userdata.state.got_shirt,
}) }}
</div>
<div class="col-md-12">
{{ f.submit(__('form.save')) }}

View File

@ -23,24 +23,23 @@
{{ m.user(user, {'pronoun': true}) }}
</div>
<div class="col-12">
{{ f.input(
'work_date',
__('worklog.date'),
'date',
{'value': work_date.format('Y-m-d'), 'required': true}
) }}
{{ f.input(
'work_hours',
__('worklog.hours'),
'number',
{'value': work_hours, 'required': true, 'step': '0.01', 'min': 0}
) }}
{{ f.input(
'comment',
__('worklog.comment'),
'text',
{'value': comment, 'required': true, 'max_length': 200}
) }}
{{ f.input('work_date', __('worklog.date'), {
'type': 'date',
'value': work_date.format('Y-m-d'),
'required': true,
}) }}
{{ f.input('work_hours', __('worklog.hours'), {
'type': 'number',
'value': work_hours,
'required': true,
'step': '0.01',
'min': 0,
}) }}
{{ f.input('comment', __('worklog.comment'), {
'value': comment,
'required': true,
'max_length': 200,
}) }}
{{ f.submit(__('form.save')) }}
</div>
</div>

View File

@ -6,12 +6,36 @@
<span class="bi bi-info-circle-fill text-info" data-bs-toggle="tooltip" title="{{ text | e('html_attr') }}"></span>
{%- endmacro %}
{% macro input(name, label, type, opt) %}
{#
Renders an input field wrapped in a DIV with mb-3.
@param {string} name - Will be used as value for "id" and "name" attributes.
@param {string} label - If not empty a "label" element with this text will be rendered.
@param {string} [opt.type="text"] - Optional type of the input field. Defaults to "text".
@param {bool} [opt.hide_label=false] - If true the label will be hidden. This could be useful for screenreders.
Defaults to false.
@param {bool} [opt.required_icon=false] - Whether an asterisk should be displayed after the label
to indicate that this field is mandatory.
Won't be displayed without a label. Defaults to false.
@param {string} [opt.info] - If set an additional info icon will be added to the label with the text as tooltip.
Won't be displayed without a label.
@param {string} [opt.value=""] - Optional value to set. Defaults to empty string.
@param {int} [opt.min_length] - Optional "minlength" attribute value.
@param {int} [opt.max_length] - Optional "maxlength" attribute value.
@param {int|float|string} [opt.min] - Optional "min" attribute value.
@param {int|float|string} [opt.max] - Optional "max" attribute value.
@param {int|float} [opt.step] - Optional "step" attribute value.
@param {string} [opt.autocomplete] - Optional "autocomplete" attribute value.
@param {bool} [opt.required=false] - Whether to add the "required" attribute. Defaults to false.
@param {bool} [opt.disabled=false] - Whether to add the "disabled" attribute. Defaults to false.
@param {bool} [opt.readonly=false] - Whether to add the "readonly" attribute. Defaults to false.
#}
{% macro input(name, label, opt) %}
<div class="mb-3">
{% if label -%}
<label for="{{ name }}" class="form-label {% if opt.hide_label|default(false) %}sr-only{% endif %}">
{{ label }}
{% if opt.entry_required_icon|default(false) %}
{% if opt.required_icon|default(false) %}
{{ _self.entry_required() }}
{% endif %}
{% if opt.info is defined %}
@ -20,7 +44,7 @@
</label>
{%- endif %}
<input
type="{{ type|default('text') }}" class="form-control"
type="{{ opt.type|default('text') }}" class="form-control"
id="{{ name }}" name="{{ name }}"
value="{{ opt.value|default('')|escape('html_attr') }}"
{%- if opt.min_length is defined %} minlength="{{ opt.min_length }}"{% endif %}
@ -42,11 +66,30 @@
</div>
{%- endmacro %}
{#
Renders a "number" type input field wrapped in a DIV with mb-3.
Also adds buttons to increment / decrement the value.
@param {string} name - Will be used as value for "id" and "name" attributes.
@param {string} label - If not empty a "label" element with this text will be rendered.
@param {bool} [opt.required_icon=false] - Whether an asterisk should be displayed after the label
to indicate that this field is mandatory.
Won't be displayed without a label. Defaults to false.
@param {string} [opt.info] - If set an additional info icon will be added to the label with the text as tooltip.
Won't be displayed without a label.
@param {string} [opt.value=""] - Optional value to set. Defaults to empty string.
@param {int|float|string} [opt.min] - Optional "min" attribute value.
@param {int|float|string} [opt.max] - Optional "max" attribute value.
@param {int|float} [opt.step] - Optional "step" attribute value.
@param {bool} [opt.required=false] - Whether to add the "required" attribute. Defaults to false.
@param {bool} [opt.disabled=false] - Whether to add the "disabled" attribute. Defaults to false.
@param {bool} [opt.readonly=false] - Whether to add the "readonly" attribute. Defaults to false.
#}
{% macro number(name, label, opt) %}
<div class="mb-3">
{% if label -%}
{% if label is defined -%}
<label class="form-label" for="{{ name }}">{{ label }}</label>
{% if opt.entry_required_icon|default(false) %}
{% if opt.required_icon|default(false) %}
{{ _self.entry_required() }}
{% endif %}
{% if opt.info is defined %}
@ -84,11 +127,24 @@
</div>
{% endmacro %}
{#
Renders a "textarea" element wrapped in a DIV with mb-3.
Also adds buttons to increment / decrement the value.
@param {string} name - Will be used as value for "id" and "name" attributes.
@param {string} label - If not empty a "label" element with this text will be rendered.
@param {bool} [opt.required_icon=false] - Whether an asterisk should be displayed after the label
to indicate that this field is mandatory.
Won't be displayed without a label. Defaults to false.
@param {bool} [opt.required] - Whether to add the "required" attribute. Defaults to false.
@param {int} [opt.rows=0] - Optional value of the "rows" attriute. Defaults to 0.
@param {string} [opt.value=""] - Optional value to set. Defaults to empty string.
#}
{% macro textarea(name, label, opt) %}
<div class="mb-3">
{% if label -%}
{% if label is defined -%}
<label class="form-label" for="{{ name }}">{{ label }}</label>
{% if opt.entry_required_icon|default(false) %}
{% if opt.required_icon|default(false) %}
{{ _self.entry_required() }}
{% endif %}
{% if opt.info is defined %}
@ -106,12 +162,28 @@
</div>
{%- endmacro %}
{% macro select(name, data, label, selected, opt) %}
{#
Renders a select element wrapped in a DIV with mb-3.
@param {string} name - Will be used as value for "id" and "name" attributes.
@param {string} label - If not empty a "label" element with this text will be rendered.
@param {{value, description}} data - Select options. "value" will be the option value, "description" the label.
@param {string} [opt.selected] - Optional value of an option to initially set as "selected".
@param {bool} [opt.required_icon=false] - Whether an asterisk should be displayed after the label
to indicate that this field is mandatory.
Won't be displayed without a label. Defaults to false.
@param {string} [opt.info] - If set an additional info icon will be added to the label with the text as tooltip.
Won't be displayed without a label.
@param {string} [opt.class] - Optional additional CSS classes to be added to the actual "select" element.
@param {bool} [opt.required=false] - Whether to add the "required" attribute. Defaults to false.
@param {bool} [opt.default_option] - If set a default option with the param as label and an empty value will be added.
#}
{% macro select(name, label, data, opt) %}
<div class="mb-3">
{% if label -%}
{% if label is defined -%}
<label class="form-label" for="{{ name }}">
{{ label }}
{% if opt.entry_required_icon|default(false) %}
{% if opt.required_icon|default(false) %}
{{ _self.entry_required() }}
{% endif %}
{% if opt.info is defined %}
@ -126,21 +198,32 @@
<option value="">{{ opt.default_option }}</option>
{% endif %}
{% for value,decription in data -%}
<option value="{{ value }}"{% if value == selected %} selected{% endif %}>{{ decription }}</option>
<option value="{{ value }}"{% if opt.selected is defined and value == opt.selected %} selected{% endif %}>{{ decription }}</option>
{% endfor %}
</select>
</div>
{%- endmacro %}
{% macro checkbox(name, label, checked, value, disabled, raw_label, opt) %}
{#
Renders a Bootstrap checkbox element with mb-3.
@param {string} name - Will be used as value for "id" and "name" attributes.
@param {string} label - Checkbox label
@param {string} [opt.value="1"] - Optional value to set. Defaults to "1".
@param {bool} [opt.checked=false] - Whether to add the "checked" attribute. Defaults to false.
@param {bool} [opt.disabled=false] - Whether to add the "disabled" attribute. Defaults to false.
@param {bool} [opt.raw_label=false] - Whether to use the raw label value (=do not escape). Defaults to false.
@param {string} [opt.info] - If set an additional info icon will be added to the label with the text as tooltip.
#}
{% macro checkbox(name, label, opt) %}
<div class="form-check mb-3">
<input class="form-check-input" type="checkbox" id="{{ name }}" name="{{ name }}"
value="{{ value|default('1') }}"
{%- if checked|default(false) %} checked{% endif %}
{%- if disabled|default(false) %} disabled{% endif %}
value="{{ opt.value|default('1') }}"
{%- if opt.checked|default(false) %} checked{% endif %}
{%- if opt.disabled|default(false) %} disabled{% endif %}
>
<label class="form-check-label" for="{{ name }}">
{%- if raw_label|default(false) -%}
{%- if opt.raw_label|default(false) -%}
{{ label|raw }}
{%- else -%}
{{ label }}
@ -152,10 +235,32 @@
</div>
{%- endmacro %}
{#
Renders a "hidden" type input field.
@param {string} name - Will be used as value for "id" and "name" attributes.
@param {string} value - Field value
#}
{% macro hidden(name, value) %}
<input type="hidden" id="{{ name }}" name="{{ name }}" value="{{ value|escape('html_attr') }}">
{%- endmacro %}
{#
Renders a button.
@param {string} label - Button label
@param {string} [opt.btn_type="secondary"] - Bootstrap button type. Defaults to "secondary".
@param {string} [opt.size] - Optional Bootstrap button size to apply, such as "sm", "lg".
@param {string} [opt.type] - Optional value for the "type" attribute.
@param {string} [opt.name] - Optional value for the "name" attribute.
@param {string} [opt.title] - Optional value for the "title" attribute.
@param {string} [opt.value] - Optional value for the "value" attribute.
Defaults to "1" if only opt.name is provided.
@param {string} [opt.icon_left] - Optional icon to be added before the button label.
Must be a Bootstrap icon class without prefix, such as "info" or "check".
@param {string} [opt.icon_right] - Optional icon to be added after the button label.
Must be a Bootstrap icon class without prefix, such as "info" or "check".
#}
{% macro button(label, opt) %}
<button
class="btn btn-{{ opt.btn_type|default('secondary') }}
@ -175,11 +280,20 @@
{{ _self.button(label|default(__('form.submit')), {'type': 'submit', 'btn_type': 'primary'}|merge(opt|default({}))) }}
{%- endmacro %}
{% macro switch(name, label, checked, opt) %}
{#
Renders a "checkbox" element that will be styled as switch.
@param {string} name - Will be used as value for "id" and "name" attributes.
@param {string} label - Switch label
@param {string} [opt.value="1"] - Optional value to set. Defaults to "1".
@param {bool} [opt.checked=false] - Whether to add the "checked" attribute. Defaults to false.
@param {bool} [opt.disabled=false] - Whether to add the "disabled" attribute. Defaults to false.
#}
{% macro switch(name, label, opt) %}
<div class="form-check form-switch mb-3">
<input class="form-check-input" type="checkbox" id="{{ name }}" name="{{ name }}"
value="{{ opt.value|default('1') }}"
{%- if checked|default(false) %} checked{% endif %}
{%- if opt.checked|default(false) %} checked{% endif %}
{%- if opt.disabled|default(false) %} disabled{% endif %}
>
<label class="form-check-label" for="{{ name }}">{{ label }}</label>

View File

@ -217,51 +217,147 @@
<div class="row">
<div class="col-md-3 col-lg-2">
{{ f.input('form-input-text', 'Text', 'text', {'value': 'Value'}) }}
<h5>Text</h5>
<code>f.input(id, label, opt)</code>
{{ f.input('form-input-text', 'Text field', {
'value': 'Value',
}) }}
{{ f.input('form-input-text-label-icons', 'Text field with required and info icon', {
'value': 'Value',
'required_icon': true,
'info': 'Very important field info!',
}) }}
{{ f.input('form-input-text-hidden-label', 'Hidden label', {
'value': 'Hidden label',
'hide_label': true,
}) }}
{{ f.input('form-input-text-disabled', 'Disabled', {
'disabled': true,
'value': 'Value',
}) }}
{{ f.input('form-input-text-readonly', null, {
'type': 'Readonly',
'readonly': true,
'value': 'w/o label',
}) }}
</div>
<div class="col-md-3 col-lg-2">
{{ f.input('form-input-text-hidden-label', 'Hidden label', 'text', {'value': 'Hidden label', 'hide_label': true}) }}
<h5>Password</h5>
<code>f.password(id, label, opt)</code>
{{ f.input('form-input-password', 'Password', {
'type': 'password',
'value': 'Value',
}) }}
</div>
<div class="col-md-3 col-lg-2">
{{ f.input('form-input-text-disabled', 'Disabled', 'text', {'disabled': true, 'value': 'Value'}) }}
<h5>Number</h5>
<code>f.number(id, label, opt)</code>
{{ f.number('form-input-number', 'Number field', {
'type': 'number',
'value': 42,
}) }}
{{ f.number('form-input-number-label-icons', 'Number field with required and info icon', {
'type': 'number',
'value': 42,
'required_icon': true,
'info': 'Very important field info!',
}) }}
{{ f.number('form-input-number-disabled', 'Disabled', {
'disabled': true,
'value': 42,
}) }}
{{ f.number('form-input-number-readonly', 'Readonly', {
'readonly': true,
'value': 42,
}) }}
{{ f.number('form-input-number-wo-label', null, {
'type': 'number',
'value': 42,
}) }}
</div>
<div class="col-md-3 col-lg-2">
{{ f.input('form-input-text-readonly', 'Readonly', 'text', {'readonly': true, 'value': 'Value'}) }}
<h5>Textarea</h5>
<code>f.textarea(id, label, opt)</code>
{{ f.textarea('form-input-textarea', 'Textarea', {
'rows': 2,
'value': lipsum,
}) }}
{{ f.textarea('form-input-textarea-label-icons', 'Textarea with required and info icon', {
'required_icon': true,
'info': 'Very important field info!',
'rows': 2,
'value': lipsum,
}) }}
{{ f.textarea('form-input-textarea-wo-label', null, {
'required_icon': true,
'rows': 2,
'value': 'w/o label',
}) }}
</div>
<div class="col-md-3 col-lg-2">
{{ f.input('form-input-password', 'Password', 'password', {'value': 'Value'}) }}
<h5>Select</h5>
<code>f.textarea(id, label, data, opt)</code>
{{ f.select('form-input-select-1', 'Select 1', {
'opt1': 'Option 1',
'opt2': 'Option 2',
'opt3': 'Another option',
'opt4': 'A looooooooong item item item item',
}) }}
{{ f.select(
'form-input-select-2',
'Select 2',
{
'sh': 'Bash',
'js': 'JavaScript',
'p': 'PHP',
'py': 'Python',
},
{
'selected': 'js',
},
) }}
{{ f.select('form-input-select-2', 'Select 3', selectOptions, {
'selected': 'option_7',
}) }}
{{ f.select('date-select', 'Date select', dateSelectOptions) }}
</div>
<div class="col-md-3 col-lg-2">
{{ f.input('form-input-number', 'Number', 'number', {'value': 42}) }}
</div>
</div>
<div class="row">
<div class="col-md-3 col-lg-2">
{{ f.textarea('form-input-textarea', 'Textarea', {'rows': 2, 'value': lipsum}) }}
</div>
<div class="col-md-3 col-lg-2">
{{ f.select('form-input-select-1', {'opt1': 'Option 1', 'opt2': 'Option 2', 'opt3': 'Another option', 'opt4': 'A looooooooong item item item item'}, 'Select 1', 'opt1') }}
{{ f.select('form-input-select-2', {'sh': 'Bash', 'js': 'JavaScript', 'p': 'PHP', 'py': 'Python'}, 'Select 2', 'js') }}
{{ f.select('form-input-select-2', selectOptions, 'Select 3', 'Option 7') }}
{{ f.select('date-select', dateSelectOptions, 'Date select') }}
</div>
<div class="col-md-3 col-lg-2">
<label class="form-label">Button</label>
<div>
<h5>Buttons</h5>
<code>f.button(label, opt)</code>
<div class="mb-3">
{{ f.button('Button') }}
</div>
</div>
<div class="col-md-3 col-lg-2">
Form submit
<div class="mb-3">
{{ f.button('Small button with icons', {
'size': 'sm',
'icon_left': 'check',
'icon_right': 'info',
'title': 'Click me!',
}) }}
</div>
<code>f.submit(label)</code>
<form id="form">
{{ f.submit() }}
{{ f.submit('Go!') }}
</form>
</div>
<div id="checkboxes" class="col-md-3 col-lg-2">
Checkbox<br>
{{ f.checkbox('form-input-checkbox', 'Checkbox 1', true, '1') }}
{{ f.checkbox('form-input-checkbox-2', 'Checkbox 2', false, '2') }}
{{ f.checkbox('form-input-checkbox-3', 'Checkbox 3', false, '3') }}
<h5>Checkbox</h5>
<code>f.checkbox(id, label, opt)</code>
{{ f.checkbox('form-input-checkbox', 'Checkbox 1', {
'checked': true, 'value': '1',
}) }}
{{ f.checkbox('form-input-checkbox-2', 'Checkbox 2', {
'checked': false, 'value': '2',
}) }}
{{ f.checkbox('form-input-checkbox-3', 'Checkbox 3', {
'checked': false, 'value': '3',
}) }}
<div class="d-grid gap-2">
<button type="button" class="btn btn-secondary d-print-none checkbox-selection" data-id="checkboxes" data-value="true">
Select all
@ -273,9 +369,37 @@
Unselect all
</button>
</div>
<hr>
{{ f.checkbox('form-input-checkbox-disabled', 'Disabled', {
'disabled': true,
}) }}
{{ f.checkbox('form-input-checkbox-raw-label', '<i>Raw label</i>', {
'raw_label': true,
}) }}
</div>
<div id="checkboxes" class="col-md-3 col-lg-2">
<h5>Switch</h5>
<code>f.switch(id, label, opt)</code>
{{ f.switch('form-switch', 'Switch') }}
{{ f.switch('form-switch-checked', 'Switch (checked)', {
'checked': true,
}) }}
{{ f.switch('form-switch-disabled', 'Switch (disabled)', {
'disabled': true,
}) }}
</div>
<div class="col-md-3 col-lg-2">
<h5>Hidden</h5>
<code>hidden(name, value)</code>
<p>
{{ f.hidden('hidden-name', 'hidden value') | escape }}
</p>
</div>
<div class="col-md-3 col-lg-2 checkbox-inline">
Radio<br>
<h5>Radio</h5>
<div class="form-check form-check-inline">
<input class="form-check-input" type="radio" id="yey" checked="checked" name="form-input-radio" value="1">
<label class="form-check-label" for="yey">Yey</label>
@ -285,19 +409,21 @@
<label class="form-check-label" for="nay">Nay</label>
</div>
</div>
</div>
<div class="row">
<div class="col-md-3 col-lg-2">
<label class="form-label" for="input_date">Date</label>
<input id="input_date" type="date" placeholder="YYYY-MM-DD" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}" name="design-date" class="form-control" value="2021-09-15">
</div>
<div class="col-md-3 col-lg-2">
<label class="form-label" for="input_datetime_local">Datetime</label>
<input id="input_datetime_local" type="datetime-local" placeholder="YYYY-MM-DD HH:MM" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2} ([01][0-9]|2[0-3]):[0-5][0-9]" name="design-datetime" class="form-control" value="2021-09-15T13:37">
</div>
<div class="col-md-3 col-lg-2">
<label class="form-label" for="input_time">Time</label>
<input type="time" class="form-control" id="input_time" name="input_time" size="5" pattern="^\d{1,2}:\d{2}$" placeholder="HH:MM" maxlength="5" value="13:37">
<h5>Date / time</h5>
<div class="mb-3">
<label class="form-label" for="input_date">Date</label>
<input id="input_date" type="date" placeholder="YYYY-MM-DD" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2}" name="design-date" class="form-control" value="2021-09-15">
</div>
<div class="mb-3">
<label class="form-label" for="input_datetime_local">Datetime</label>
<input id="input_datetime_local" type="datetime-local" placeholder="YYYY-MM-DD HH:MM" pattern="[0-9]{4}-[0-9]{2}-[0-9]{2} ([01][0-9]|2[0-3]):[0-5][0-9]" name="design-datetime" class="form-control" value="2021-09-15T13:37">
</div>
<div class="mb-3">
<label class="form-label" for="input_time">Time</label>
<input type="time" class="form-control" id="input_time" name="input_time" size="5" pattern="^\d{1,2}:\d{2}$" placeholder="HH:MM" maxlength="5" value="13:37">
</div>
</div>
</div>
</div>
@ -380,52 +506,6 @@
</div>
</div>
<h3>form.twig</h3>
<div class="row mb-4">
<div class="col-md-3">
<h4><code>input(name, label, type, opt)</code></h4>
<p>{{ f.input('input-name', 'Label', 'text', {'required': true, 'value': 'Value'}) }}</p>
</div>
<div class="col-md-3">
<h4><code>textarea(name, label, opt)</code></h4>
<p>{{ f.textarea('textarea-name', 'Label', {'required': true, 'rows': 2, 'value': lipsum}) }}</p>
</div>
<div class="col-md-3">
<h4><code>select(name, data, label, selected)</code></h4>
<p>{{ f.select('select-name', {'foo': 'Foo', 'bar': 'Bar'}, 'Label', 'bar') }}</p>
</div>
<div class="col-md-3">
<h4><code>checkbox(name, label, checked, value)</code></h4>
<p>
{{ f.checkbox('checkbox-name', 'Label', false) }}<br>
{{ f.checkbox('checkbox-name', 'Label', true, 'on') }}
</p>
</div>
<div class="col-md-3">
<h4><code>hidden(name, value)</code></h4>
<p>
{{ f.hidden('hidden-name', 'hidden value') | escape }}
</p>
</div>
<div class="col-md-3">
<h4><code>button(label, opt)</code></h4>
<p>
{{ f.button('Label', {'name': 'button-name', 'value': 'buton-value'}) }}
</p>
</div>
<div class="col-md-3">
<h4><code>submit(label, opt)</code></h4>
<p>
{{ f.submit() }}
</p>
</div>
</div>
<span id="bar_chart" class="ref-id"></span>
<h3>Bar Chart <a href="#bar_chart" class="ref-link">{{ m.icon('link') }}</a></h3>
{{ bar_chart | raw }}

View File

@ -31,10 +31,17 @@
<div class="row mb-4">
<div class="col-md-12">
{{ f.input('question', __('faq.question'), null, {'required': true, 'value': faq ? faq.question : ''}) }}
{{ f.input('question', __('faq.question'), {
'required': true,
'value': faq ? faq.question : '',
}) }}
</div>
<div class="col-md-12">
{{ f.textarea('text', __('faq.message'), {'required': true, 'rows': 10, 'value': faq ? faq.text : ''}) }}
{{ f.textarea('text', __('faq.message'), {
'required': true,
'rows': 10,
'value': faq ? faq.text : '',
}) }}
{{ f.submit() }}

View File

@ -71,7 +71,10 @@
{{ csrf() }}
<div class="col-md-12">
<h4>{{ __('question.add') }}</h4>
{{ f.textarea('text', __('question.question'), {'required': true, 'rows': 5}) }}
{{ f.textarea('text', __('question.question'), {
'required': true,
'rows': 5,
}) }}
{{ f.submit() }}
</div>
</form>

View File

@ -15,8 +15,11 @@
{{ csrf() }}
<div class="row gx-2 mb-3">
<div class="col-auto">
{{ f.select('user_id', users, null, null,
{ 'class': 'pe-5', 'required': true, 'default_option': __('message.choose_angel') }) }}
{{ f.select('user_id', null, users, {
'class': 'pe-5',
'required': true,
'default_option': __('message.choose_angel'),
}) }}
</div>
<div class="col">
{{ f.submit(__('message.to_conversation'), {'btn_type': 'secondary'}) }}

View File

@ -36,20 +36,34 @@
{{ f.input(
'title',
__('news.edit.subject'),
null,
{'required': true, 'value': news ? news.title : ''}
{
'required': true,
'value': news ? news.title : '',
}
) }}
</div>
<div class="col-md-6">
{{ f.checkbox('is_meeting', __('news.edit.is_meeting'), is_meeting) }}
{{ f.checkbox('is_pinned', __('news.edit.is_pinned'), is_pinned) }}
{% if has_permission_to('news.important') %} {{ f.checkbox('is_important', __('news.edit.is_important'), is_important) }}{% endif %}
{{ f.checkbox('is_meeting', __('news.edit.is_meeting'), {
'checked': is_meeting,
}) }}
{{ f.checkbox('is_pinned', __('news.edit.is_pinned'), {
'checked': is_pinned,
}) }}
{% if has_permission_to('news.important') %}
{{ f.checkbox('is_important', __('news.edit.is_important'), {
'checked': is_important,
}) }}
{% endif %}
</div>
</div>
<div class="row mb-4">
<div class="col-md-12">
{{ f.textarea('text', __('news.edit.message'), {'required': true, 'rows': 10, 'value': news ? news.text : ''}) }}
{{ f.textarea('text', __('news.edit.message'), {
'required': true,
'rows': 10,
'value': news ? news.text : '',
}) }}
<p>{{ m.info(__('news.edit.hint')) }}</p>

View File

@ -47,7 +47,9 @@
<form action="" enctype="multipart/form-data" method="post">
{{ csrf() }}
{{ f.textarea('comment', __('news.comments.message'), {'required': true}) }}
{{ f.textarea('comment', __('news.comments.message'), {
'required': true,
}) }}
{{ f.submit() }}
</form>
</div>

View File

@ -7,8 +7,16 @@
<form action="" enctype="multipart/form-data" method="post">
{{ csrf() }}
{{ f.input('password', __('Password'), 'password', {'min_length': min_length, 'required': true}) }}
{{ f.input('password_confirmation', __('Confirm password'), 'password', {'min_length': min_length, 'required': true}) }}
{{ f.input('password', __('Password'), {
'type': 'password',
'min_length': min_length,
'required': true,
}) }}
{{ f.input('password_confirmation', __('Confirm password'), {
'type': 'password',
'min_length': min_length,
'required': true,
}) }}
{{ f.submit(__('Save')) }}
</form>

View File

@ -17,7 +17,10 @@
{{ csrf() }}
{{ __('We will send you an e-mail with a password recovery link. Please use the email address you used for registration.') }}
{{ f.input('email', __('E-Mail'), 'email', {'required': true}) }}
{{ f.input('email', __('E-Mail'), {
'type': 'email',
'required': true,
}) }}
{{ f.submit(__('Recover')) }}
</form>

View File

@ -31,11 +31,18 @@
<div class="row">
<div class="col-md-12">
{{ f.textarea('text', __('question.question'), {'required': true, 'rows': 10, 'value': question ? question.text : ''}) }}
{{ f.textarea('text', __('question.question'), {
'required': true,
'rows': 10,
'value': question ? question.text : '',
}) }}
</div>
<div class="col-md-12">
{% if is_admin|default(false) %}
{{ f.textarea('answer', __('question.answer'), {'required': true, 'rows': 10, 'value': question ? question.answer : ''}) }}
{{ f.textarea('answer', __('question.answer'), {
'required': true,
'rows': 10, 'value': question ? question.answer : '',
}) }}
{% endif %}
{{ f.submit() }}

View File

@ -11,7 +11,9 @@
<div class="row">
<div class="col-md-12">
{{ m.info(__('settings.language.info')) }}
{{ f.select('select_language', languages, __('settings.language'), current_language) }}
{{ f.select('select_language', __('settings.language'), languages, {
'selected': current_language,
}) }}
{{ f.submit(__('form.save')) }}
</div>
</div>

View File

@ -13,25 +13,24 @@
{{ m.info(__('settings.password.info')) }}
{% if user.password %}
{{ f.input(
'password',
__('settings.password.password'),
'password',
{'required': true, 'autocomplete': 'current-password'}
) }}
{{ f.input('password', __('settings.password.password'), {
'type': 'password',
'required': true,
'autocomplete': 'current-password',
}) }}
{% endif %}
{{ f.input(
'new_password',
__('settings.password.new_password'),
'password',
{'min_length': min_length, 'required': true, 'autocomplete': 'new-password'}
) }}
{{ f.input(
'new_password2',
__('settings.password.new_password2'),
'password',
{'min_length': min_length, 'required': true, 'autocomplete': 'new-password'}
) }}
{{ f.input('new_password', __('settings.password.new_password'), {
'type': 'password',
'min_length': min_length,
'required': true,
'autocomplete': 'new-password',
}) }}
{{ f.input('new_password2', __('settings.password.new_password2'), {
'type': 'password',
'min_length': min_length,
'required': true,
'autocomplete': 'new-password',
}) }}
{{ f.submit(__('form.save')) }}
</div>
</div>

View File

@ -18,21 +18,17 @@
<div class="row g-4">
<div class="col-lg-6">
{{ f.input(
'nick',
__('settings.profile.nick'),
'text',
{'value': user.name, 'disabled': true}
) }}
{{ f.input('nick', __('settings.profile.nick'), {
'value': user.name,
'disabled': true,
}) }}
</div>
{% if config('enable_pronoun') %}
<div class="col-lg-6">
{{ f.input(
'pronoun',
__('settings.profile.pronoun'),
'text',
{'value': user.personalData.pronoun ,'max_length': 15}
) }}
{{ f.input('pronoun', __('settings.profile.pronoun'), {
'value': user.personalData.pronoun,
'max_length': 15,
}) }}
{{ m.info(__('settings.profile.pronoun.info')) }}
</div>
{% endif %}
@ -41,20 +37,16 @@
{% if config('enable_user_name') %}
<div class="row g-4">
<div class="col-sm-6">
{{ f.input(
'first_name',
__('settings.profile.firstname'),
'text',
{'value': user.personalData.first_name, 'max_length': 64}
) }}
{{ f.input('first_name', __('settings.profile.firstname'), {
'value': user.personalData.first_name,
'max_length': 64,
}) }}
</div>
<div class="col-sm-6">
{{ f.input(
'last_name',
__('settings.profile.lastname'),
'text',
{'value': user.personalData.last_name, 'max_length': 64}
) }}
{{ f.input('last_name', __('settings.profile.lastname'), {
'value': user.personalData.last_name,
'max_length': 64,
}) }}
</div>
</div>
{% endif %}
@ -62,31 +54,23 @@
{% if config('enable_planned_arrival') %}
<div class="row g-4">
<div class="col-sm-6">
{{ f.input(
'planned_arrival_date',
__('settings.profile.planned_arrival_date'),
'date',
{
'value': user.personalData.planned_arrival_date.format('Y-m-d'),
'required': true,
'entry_required_icon': true,
'min': config('buildup_start') ? config('buildup_start').format('Y-m-d') : '',
'max': config('teardown_end') ? config('teardown_end').format('Y-m-d') : '',
}
) }}
{{ f.input('planned_arrival_date', __('settings.profile.planned_arrival_date'), {
'type': 'date',
'value': user.personalData.planned_arrival_date.format('Y-m-d'),
'required': true,
'required_icon': true,
'min': config('buildup_start') ? config('buildup_start').format('Y-m-d') : '',
'max': config('teardown_end') ? config('teardown_end').format('Y-m-d') : '',
}) }}
</div>
<div class="col-sm-6">
{% set planned_departure_date = user.personalData.planned_departure_date %}
{{ f.input(
'planned_departure_date',
__('settings.profile.planned_departure_date'),
'date',
{
'value': planned_departure_date ? planned_departure_date.format('Y-m-d') : '',
'min': config('buildup_start') ? config('buildup_start').format('Y-m-d') : '',
'max': config('teardown_end') ? config('teardown_end').format('Y-m-d') : '',
}
) }}
{{ f.input('planned_departure_date', __('settings.profile.planned_departure_date'), {
'type': 'date',
'value': planned_departure_date ? planned_departure_date.format('Y-m-d') : '',
'min': config('buildup_start') ? config('buildup_start').format('Y-m-d') : '',
'max': config('teardown_end') ? config('teardown_end').format('Y-m-d') : '',
}) }}
</div>
</div>
{% endif %}
@ -94,75 +78,60 @@
<div class="row g-4">
{% if config('enable_dect') %}
<div class="col-md-6">
{{ f.input(
'dect',
__('settings.profile.dect'),
'text',
{'value': user.contact.dect, 'max_length': 40}
) }}
{{ f.input('dect', __('settings.profile.dect'), {
'value': user.contact.dect,
'max_length': 40,
}) }}
</div>
{% endif %}
<div class="col-md-6">
{{ f.input(
'mobile',
__('settings.profile.mobile'),
'text',
{'value': user.contact.mobile, 'max_length': 40}
) }}
{{ f.input('mobile', __('settings.profile.mobile'), {
'value': user.contact.mobile,
'max_length': 40,
}) }}
{% if config('enable_mobile_show') %}
{{ f.checkbox(
'mobile_show',
__('settings.profile.mobile_show'),
user.settings.mobile_show
) }}
{{ f.checkbox('mobile_show', __('settings.profile.mobile_show'), {
'checked': user.settings.mobile_show,
}) }}
{% endif %}
</div>
</div>
<div class="row g-4">
<div class="col-md-6">
{{ f.input(
'email',
__('settings.profile.email'),
'email',
{'value': user.email, 'max_length': 254, 'required': true, 'entry_required_icon': true}
) }}
{{ f.input('email', __('settings.profile.email'), {
'type': 'email',
'value': user.email,
'max_length': 254,
'required': true,
'required_icon': true,
}) }}
</div>
<div class="col-md-6">
{{ f.checkbox(
'email_shiftinfo',
__('settings.profile.email_shiftinfo', [config('app_name')]),
user.settings.email_shiftinfo
) }}
{{ f.checkbox(
'email_news',
__('settings.profile.email_news'),
user.settings.email_news
) }}
{{ f.checkbox(
'email_messages',
__('settings.profile.email_messages'),
user.settings.email_messages
) }}
{{ f.checkbox(
'email_human',
__('settings.profile.email_by_human_allowed'),
user.settings.email_human
) }}
{{ f.checkbox('email_shiftinfo', __('settings.profile.email_shiftinfo'), {
'checked': [config('app_name')],
'value': user.settings.email_shiftinfo,
}) }}
{{ f.checkbox('email_news', __('settings.profile.email_news'), {
'checked': user.settings.email_news,
}) }}
{{ f.checkbox('email_messages', __('settings.profile.email_messages'), {
'checked': user.settings.email_messages,
}) }}
{{ f.checkbox('email_human', __('settings.profile.email_by_human_allowed'), {
'checked': user.settings.email_human,
}) }}
{% if goodie_enabled %}
{% set privacy_email = config('privacy_email') %}
{% set email_goody_label = __('settings.profile.email_goody') ~
(privacy_email ? ' ' ~ __('settings.profile.privacy', [privacy_email]) : '')
%}
{{ f.checkbox(
'email_goody',
email_goody_label,
user.settings.email_goody,
user.settings.email_goody,
false,
true
) }}
{{ f.checkbox('email_goody', email_goody_label, {
'checked': user.settings.email_goody,
'value': user.settings.email_goody,
'raw_label': true,
}) }}
{% endif %}
</div>
</div>
@ -170,13 +139,11 @@
<div class="row g-4">
{% if goodie_tshirt %}
<div class="col-12">
{{ f.select(
'shirt_size',
config('tshirt_sizes'),
__('settings.profile.shirt_size'),
user.personalData.shirt_size,
{'required': true, 'entry_required_icon': true}
) }}
{{ f.select('shirt_size', __('settings.profile.shirt_size'), config('tshirt_sizes'), {
'selected': user.personalData.shirt_size,
'required': true,
'required_icon': true,
}) }}
</div>
{% endif %}

View File

@ -11,7 +11,9 @@
<div class="row">
<div class="col-md-12">
{{ m.info(__('settings.theme.info')) }}
{{ f.select('select_theme', themes, __('settings.theme'), current_theme) }}
{{ f.select('select_theme', __('settings.theme'), themes, {
'selected': current_theme,
}) }}
{{ f.submit(__('form.save')) }}
</div>
</div>