mirror of
https://github.com/lucaspalomodevelop/eventcally.git
synced 2026-03-13 00:07:22 +00:00
1709 lines
63 KiB
HTML
1709 lines
63 KiB
HTML
{% macro render_field_with_errors(field) %}
|
||
{% set is_collapsible = kwargs['is_collapsible'] if 'is_collapsible' in kwargs else False %}
|
||
{% if is_collapsible %}
|
||
<div class="mb-3" id="{{ field.id }}-show-container"{% if field.data %} style="display: none;"{% endif %}>
|
||
<a href="#" class="show-link" data-container="{{ field.id }}-container" data-show-container="{{ field.id }}-show-container"><i class="fa fa-plus"></i> {{ field.label.text }}</a>
|
||
</div>
|
||
<div id="{{ field.id }}-container"{% if not field.data %} style="display: none;"{% endif %}>
|
||
{% endif %}
|
||
|
||
{% set is_required = kwargs['is_required'] if 'is_required' in kwargs else field.flags.required %}
|
||
{% set label_text = field.label.text + ' *' if is_required else field.label.text %}
|
||
<div class="form-group {% if field.errors %} has-error{% endif -%}">
|
||
{% if 'label_hidden' in kwargs or ('ri' in kwargs and kwargs['ri'] == 'checkbox') %}
|
||
{% else %}
|
||
{{ field.label(text=label_text, class="mb-0") }}
|
||
{% endif %}
|
||
|
||
{% if field.description %}
|
||
<div class="form-text mt-0 text-muted w-100">
|
||
{{ field.description }}
|
||
</div>
|
||
{% endif %}
|
||
|
||
<div class="input-group">
|
||
{% set field_class = kwargs['class'] if 'class' in kwargs else '' %}
|
||
{% set field_class = field_class + ' form-control' %}
|
||
{% if field.errors %}
|
||
{% set field_class = field_class + ' is-invalid' %}
|
||
{% endif %}
|
||
|
||
{% if 'ri' in kwargs and kwargs['ri'] == 'multicheckbox' %}
|
||
<fieldset class="form-group">
|
||
{% for choice in field %}
|
||
<div class="form-check">
|
||
{{ choice(class="form-check-input") }}
|
||
{{ choice.label(class="form-check-label") }}
|
||
</div>
|
||
{% endfor %}
|
||
</fieldset>
|
||
{% elif 'ri' in kwargs and kwargs['ri'] == 'multicheckbox-inline' %}
|
||
<fieldset class="form-group my-auto">
|
||
{% for choice in field %}
|
||
<div class="form-check form-check-inline">
|
||
{{ choice(class="form-check-input") }}
|
||
{{ choice.label(class="form-check-label") }}
|
||
</div>
|
||
{% endfor %}
|
||
</fieldset>
|
||
{% elif 'ri' in kwargs and kwargs['ri'] == 'checkbox' %}
|
||
<div class="form-check">
|
||
{{ field(class="form-check-input") }}
|
||
{{ field.label(class="form-check-label") }}
|
||
</div>
|
||
{% elif 'ri' in kwargs and kwargs['ri'] == 'switch' %}
|
||
<div class="custom-control custom-switch">
|
||
{{ field(class="custom-control-input") }}
|
||
<label class="custom-control-label" for="{{ field.id }}"></label>
|
||
</div>
|
||
{% elif 'ri' in kwargs and kwargs['ri'] == 'radio-buttons' %}
|
||
<div class="btn-group btn-group-toggle" data-toggle="buttons">
|
||
{% for choice in field %}
|
||
{% set color = kwargs['colors'][loop.index0] if 'colors' in kwargs else 'secondary' %}
|
||
<label class="btn btn-outline-{{ color }}">
|
||
<input type="radio" id="{{ choice.id }}" name="{{ field.id }}" value="{{ choice.id[-1] }}" {% if choice.checked %}checked {% endif %}> {{ choice.label.text }}
|
||
</label>
|
||
{% endfor %}
|
||
</div>
|
||
{% else %}
|
||
{% if 'class' in kwargs %}
|
||
{% set _dummy=kwargs.pop('class') %}
|
||
{% endif %}
|
||
{{ field(class=field_class, **kwargs)|safe }}
|
||
{% endif %}
|
||
|
||
{% if 'ri' in kwargs %}
|
||
{% if kwargs['ri'] == 'rrule' %}
|
||
<script type="text/javascript">
|
||
$( function() {
|
||
$("textarea[name=recurrence_rule]").recurrenceinput({lang:'de', startField: "start", ajaxURL: "{{ url_for('event_rrule') }}", firstDay: 1});
|
||
});
|
||
</script>
|
||
{% endif %}
|
||
{% endif %}
|
||
</div>
|
||
|
||
{% if field.errors %}
|
||
<div class="invalid-feedback d-block">
|
||
{% for error in field.errors %}
|
||
<div>{{ error }}</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
|
||
{% if is_collapsible %}
|
||
<div class="mb-3" id="{{ field.id }}-hide-container">
|
||
<a href="#" class="hide-link" data-container="{{ field.id }}-container" data-show-container="{{ field.id }}-show-container"><i class="fa fa-minus"></i> {{ field.label.text }}</a>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_field(field) %}
|
||
<p>{{ field(class="btn btn-primary", **kwargs)|safe }}</p>
|
||
{% endmacro %}
|
||
|
||
{% macro render_field_errors(field) %}
|
||
<p>
|
||
{% if field and field.errors %}
|
||
<ul>
|
||
{% for error in field.errors %}
|
||
<li>{{ error }}</li>
|
||
{% endfor %}
|
||
</ul>
|
||
{% endif %}
|
||
</p>
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_organizer(organizer) %}
|
||
{{ organizer.name }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_location(location) %}{{ location | location_str }}{% endmacro %}
|
||
{% macro render_place(place) %}{{ place | place_str }}{% endmacro %}
|
||
|
||
{% macro render_events_sub_menu() %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_location_card(location, place=None) %}
|
||
{% if location %}
|
||
<div class="card card-body">
|
||
<p>
|
||
{{ location.street }}<br />
|
||
{{ location.postalCode }} {{ location.city }}
|
||
</p>
|
||
|
||
<p>
|
||
<a href="http://www.google.com/maps?q={% if place %}{{ render_place(place) | quote_plus }}{% else %}{{ render_location(location) | quote_plus }}{% endif %}">{{ _('Show on Google Maps') }}</a>
|
||
</p>
|
||
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_kv_begin() %}
|
||
<dl class="row">
|
||
{% endmacro %}
|
||
|
||
{% macro render_kv_end() %}
|
||
</dl>
|
||
{% endmacro %}
|
||
|
||
{% macro render_kv_prop(prop, label_key = None) %}
|
||
{% if prop %}
|
||
<dt class="col-sm-3">{{ _(label_key) }}</dt>
|
||
<dd class="col-sm-9">{% if prop|is_list %}{{ prop|join(', ') }}{% else %}{{ prop }}{% endif %}</dd>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_string_prop(prop, icon = None, label_key = None) %}
|
||
{% if prop %}
|
||
<div>
|
||
{% if icon %}<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>{% endif %}
|
||
{{ prop }}
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_int_prop(prop, icon = None, label_key = None) %}
|
||
{% if prop %}
|
||
<div>
|
||
{% if icon %}<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>{% endif %}
|
||
{{ prop }}
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_bool_prop(prop, icon, label_key) %}
|
||
{% if prop %}
|
||
<div>
|
||
<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>
|
||
{{ _(label_key) }}
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_enum_prop(prop, icon, label_key, ignore=0) %}
|
||
{% if prop and prop.value > 0 and prop.value != ignore %}
|
||
<div>
|
||
<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>
|
||
{{ prop | loc_enum }}
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_range_prop(from, to, icon, label_key) %}
|
||
{% if from or to %}
|
||
<div>
|
||
<i class="fa fa-fw {{ icon }}" data-toggle="tooltip" title="{{ _(label_key) }}"></i>
|
||
{{ from if from }} - {{ to if to }}
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_tag_prop(tags) %}
|
||
{% if tags %}
|
||
<div>
|
||
<i class="fa fa-fw fa-tags" data-toggle="tooltip" title="{{ _('Tags') }}"></i>
|
||
{{ tags }}
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_link_prop(link) %}
|
||
{% if link %}
|
||
<div>
|
||
<i class="fa fa-fw fa-link" data-toggle="tooltip" title="{{ _('Link') }}"></i>
|
||
<a href="{{ link | ensure_link_scheme }}" target="_blank" rel="noopener noreferrer" style="word-break: break-all;">{{ link }}</a>
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_email_prop(email) %}
|
||
{% if email %}
|
||
<div>
|
||
<i class="fa fa-fw fa-envelope" data-toggle="tooltip" title="{{ _('Email') }}"></i>
|
||
<a href="mailto:{{ email }}">{{ email }}</a>
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_status_pill(event) %}
|
||
{% if event.status and event.status != 1 %}
|
||
<span class="badge badge-pill badge-warning">{{ event.status | loc_enum }}</span>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_booked_up_pill(event) %}
|
||
{% if event.booked_up %}
|
||
<span class="badge badge-pill badge-warning">{{ _('Booked up') }}</span>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_public_status_pill(event) %}
|
||
{% if event.public_status and event.public_status == 1 %}
|
||
<span class="badge badge-pill badge-dark">{{ _('PublicStatus.draft') }}</span>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_attendance_mode_pill(event) %}
|
||
{% if event.attendance_mode and event.attendance_mode.value != 1 %}
|
||
<span class="badge badge-pill badge-info">{{ event.attendance_mode | loc_enum }}</span>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_warning_pills(event) %}
|
||
{{ render_public_status_pill(event) }} {{ render_event_status_pill(event) }} {{ render_booked_up_pill(event) }} {{ render_attendance_mode_pill(event) }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_review_status_pill(event) %}
|
||
{% if event.review_status %}
|
||
<span class="badge badge-pill {% if event.review_status == 2 %}badge-success{% elif event.review_status == 1 %}badge-info{% else %}badge-danger{% endif %}">{{ event.review_status | loc_enum }}</span>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_reference_request_review_status_pill(reference_request) %}
|
||
{% if reference_request.review_status %}
|
||
<span class="badge badge-pill {% if reference_request.review_status == 1 %}badge-info{% elif reference_request.review_status == 2 %}badge-success{% else %}badge-danger{% endif %}">{{ reference_request.review_status | loc_enum }}</span>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_admin_unit_badges(admin_unit) %}
|
||
{% if admin_unit.is_verified %}<i class="fa fa-check-circle text-primary" data-toggle="tooltip" title="{{ _('Verified') }}"></i>{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_phone_prop(phone) %}
|
||
{% if phone %}
|
||
<div>
|
||
<i class="fa fa-fw fa-phone" data-toggle="tooltip" title="{{ _('Phone') }}"></i>
|
||
<a href="tel:{{ phone }}">{{ phone }}</a>
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_fax_prop(fax) %}
|
||
{% if fax %}
|
||
<div><i class="fa fa-fw fa-fax" data-toggle="tooltip" title="{{ _('Fax') }}"></i> {{ fax }}</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_location_prop(location) %}
|
||
{% if location and location.street or location.postalCode or location.city %}
|
||
<div>
|
||
<i class="fa fa-fw fa-map-marker" data-toggle="tooltip" title="{{ _('Location') }}"></i>
|
||
{{ render_location(location) }}
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_img_src(image, size=500) %}
|
||
<img src="{{ url_for_image(image, s=size) }}" class="{{ kwargs['class'] or 'img-fluid' }}" style="{{ kwargs['style'] or 'max-width:100%;' }}" alt="{{ kwargs['alt'] or 'image' }}" />
|
||
{% endmacro %}
|
||
|
||
{% macro render_image(image, size=500) %}
|
||
{% if image %}
|
||
{% set img_class = kwargs.pop('class', '') %}
|
||
{% set img_style = kwargs.pop('style', '') %}
|
||
{% set img_class = img_class + ' figure-img img-fluid' %}
|
||
<figure class="figure mx-auto">
|
||
{{ render_img_src(image, size, class=img_class, style=img_style, **kwargs) }}
|
||
{% if image.copyright_text %}
|
||
<figcaption class="figure-caption">© {{ image.copyright_text }}</figcaption>
|
||
{% endif %}
|
||
</figure>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_logo(image) %}
|
||
{{ render_image(image, 120, style="max-width:120px;", alt="Logo") }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_review_status(event) %}
|
||
{{ render_enum_prop(event.review_status, 'fa-certificate', 'Review status') }}
|
||
{{ render_enum_prop(event.rejection_resaon, 'fa-search-minus', 'Rejection reason') }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_reference_request_review_status(reference_request) %}
|
||
{{ render_enum_prop(reference_request.review_status, 'fa-certificate', 'Review status') }}
|
||
{{ render_enum_prop(reference_request.rejection_reason, 'fa-search-minus', 'Rejection reason') }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_audit(tracking_mixing, show_user=False) %}
|
||
{% set created_at = tracking_mixing.created_at | datetimeformat('short') %}
|
||
{% set updated_at = tracking_mixing.updated_at | datetimeformat('short') %}
|
||
|
||
{% if show_user %}
|
||
{{ _('Created at %(created_at)s by %(created_by)s.', created_at=created_at, created_by=tracking_mixing.created_by.email) }}
|
||
{% else %}
|
||
{{ _('Created at %(created_at)s.', created_at=created_at) }}
|
||
{% endif %}
|
||
|
||
{% if created_at != updated_at %}
|
||
{% if show_user %}
|
||
{{ _('Last updated at %(updated_at)s by %(updated_by)s.', updated_at=updated_at, updated_by=tracking_mixing.updated_by.email) }}
|
||
{% else %}
|
||
{{ _('Last updated at %(updated_at)s.', updated_at=updated_at) }}
|
||
{% endif %}
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_audit_container(tracking_mixing, show_user=False) %}
|
||
<div class="my-4 small">{{ render_audit(tracking_mixing, show_user) }}</div>
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_add_props(event) %}
|
||
{{ render_string_prop(event.price_info, 'fa-euro-sign', 'Price info') }}
|
||
{{ render_link_prop(event.external_link) }}
|
||
{{ render_link_prop(event.ticket_link) }}
|
||
{% if event.category %}
|
||
<div><i class="fa fa-fw fa-archive" data-toggle="tooltip" title="{{ _('Category') }}"></i> {% for category in event.categories %}{{ category | event_category_name }}{%if not loop.last %}, {% endif %}{% endfor %}</div>
|
||
{% endif %}
|
||
{{ render_tag_prop(event.tags) }}
|
||
{{ render_bool_prop(event.kid_friendly, 'fa-child', 'Kid friendly') }}
|
||
{{ render_bool_prop(event.accessible_for_free, 'fa-door-open', 'Accessible for free') }}
|
||
{{ render_range_prop(event.age_from, event.age_to, 'fa-people-arrows', 'Typical Age range') }}
|
||
{{ render_enum_prop(event.target_group_origin, 'fa-users', 'Target group origin', 1) }}
|
||
{{ render_enum_prop(event.attendance_mode, 'fa-mouse-pointer', 'Attendance mode', 1) }}
|
||
{{ render_bool_prop(event.registration_required, 'fa-list', 'Registration required') }}
|
||
{{ render_bool_prop(event.booked_up, 'fa-square-full', 'Booked up') }}
|
||
{{ render_int_prop(event.expected_participants, 'fa-users', 'Expected number of participants') }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_props(event, start, end, allday, dates = None, show_rating = False, show_admin_unit = True, share_links=None, calendar_links=None) %}
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
{{ _('Event') }}
|
||
</div>
|
||
|
||
<div class="card-body">
|
||
<h5 class="card-title">{{ event.name }}{{ render_event_warning_pills(event) }}</h5>
|
||
<div>
|
||
<i class="fa fa-fw fa-calendar" data-toggle="tooltip" title="{{ _('Date') }}"></i>
|
||
{{ render_event_date_with_dates_link(start, end, allday) }}
|
||
</div>
|
||
{{ render_enum_prop(event.status, 'fa-info-circle', 'Status', 1) }}
|
||
{% if event.previous_start_date %}
|
||
<div><i class="fa fa-fw fa-calendar-times" data-toggle="tooltip" title="{{ _('Previous start date') }}"></i> {{ event.previous_start_date | datetimeformat('short') }}</div>
|
||
{% endif %}
|
||
|
||
{% if show_rating and event.rating and event.rating != 50 %}
|
||
{{ render_string_prop("%d/10" % (event.rating/10), 'fa-adjust', 'Rating') }}
|
||
{% endif %}
|
||
|
||
{% if event.photo_id %}
|
||
<div class="my-4">{{ render_image(event.photo, 700) }}</div>
|
||
{% endif %}
|
||
|
||
{% if event.description %}
|
||
<div class="my-4" style="white-space:pre-wrap;">{{ event.description|urlize(nofollow=True, target='_blank', rel="nofollow") }}</div>
|
||
{% endif %}
|
||
|
||
<div class="mt-4">
|
||
{{ render_event_add_props(event) }}
|
||
</div>
|
||
|
||
{% if share_links or calendar_links %}
|
||
<div class="mt-4">
|
||
{% if share_links %}
|
||
<button type="button" class="btn btn-outline-secondary mr-1 mb-1" data-toggle="modal" data-target="#shareModal"><i class="fa fa-share-alt"></i> {{ _('Share') }}</button>
|
||
{{ render_share_modal(share_links) }}
|
||
{% endif %}
|
||
{% if calendar_links %}
|
||
<button type="button" class="btn btn-outline-secondary mb-1" data-toggle="modal" data-target="#calendarExportModal"><i class="fa fa-calendar"></i> {{ _('Add to calendar') }}</button>
|
||
{{ render_calendar_export_modal(calendar_links) }}
|
||
{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
<div class="card-footer small">
|
||
{{ render_audit(event, show_rating) }}
|
||
<a href="{{ url_for('event_report', event_id=event.id) }}" class="text-dark" target="_blank" rel="noopener noreferrer">{{ _('Report event') }}</a>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
{{ _('Place') }}
|
||
</div>
|
||
<div class="card-body">
|
||
{% if event.event_place %}
|
||
<h5 class="card-title">{{ event.event_place.name }}</h5>
|
||
|
||
{% if event.event_place.photo_id %}
|
||
<div class="my-4">{{ render_image(event.event_place.photo, 300) }}</div>
|
||
{% endif %}
|
||
|
||
{% if event.event_place.description %}
|
||
<div class="my-4">{{ event.event_place.description }}</div>
|
||
{% endif %}
|
||
|
||
<div class="my-4">
|
||
{{ render_link_prop(event.event_place.url) }}
|
||
{{ render_location_prop(event.event_place.location) }}
|
||
</div>
|
||
|
||
{% if event.attendance_mode and event.attendance_mode.value != 1 %}
|
||
<p>
|
||
<a href="http://www.google.com/maps?q={{ render_place(event.event_place) | quote_plus }}" class="btn btn-secondary" target="_blank" rel="noopener noreferrer">{{ _('Show directions') }}</a>
|
||
</p>
|
||
{% endif %}
|
||
|
||
{% if event.attendance_mode and event.attendance_mode.value == 2 %}
|
||
<p>{{ _('The event takes place online.') }}</p>
|
||
{% elif event.attendance_mode and event.attendance_mode.value == 3 %}
|
||
<p>{{ _('The event takes place both offline and online.') }}</p>
|
||
{% endif %}
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
{% if event.organizer %}
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
{{ _('Organizer') }}
|
||
</div>
|
||
<div class="card-body">
|
||
{{ render_event_props_organizer(event.organizer) }}
|
||
{% for co_organizer in event.co_organizers %}
|
||
<div{% if loop.index > 0 %} class="mt-4"{% endif %}>
|
||
{{ render_event_props_organizer(co_organizer) }}
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
{% if show_admin_unit %}
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
{{ _('Organization') }}
|
||
</div>
|
||
<div class="card-body">
|
||
|
||
<h5 class="card-title">{{ event.admin_unit.name }}{{ render_admin_unit_badges(event.admin_unit) }}</h5>
|
||
|
||
{% if event.admin_unit.logo_id %}
|
||
<div class="my-4">{{ render_logo(event.admin_unit.logo) }}</div>
|
||
{% endif %}
|
||
|
||
<div class="my-4">
|
||
{{ render_link_prop(event.admin_unit.url) }}
|
||
{{ render_email_prop(event.admin_unit.email) }}
|
||
{{ render_phone_prop(event.admin_unit.phone) }}
|
||
{{ render_fax_prop(event.admin_unit.fax) }}
|
||
{{ render_location_prop(event.admin_unit.location) }}
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_props_organizer(organizer) %}
|
||
<h5 class="card-title">{{ render_string_prop(organizer.name) }}</h5>
|
||
|
||
{% if organizer.logo_id %}
|
||
<div class="my-4">{{ render_logo(organizer.logo) }}</div>
|
||
{% endif %}
|
||
|
||
{{ render_link_prop(organizer.url) }}
|
||
{{ render_email_prop(organizer.email) }}
|
||
{{ render_phone_prop(organizer.phone) }}
|
||
{{ render_fax_prop(organizer.fax) }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_props_seo(event, start, end, allday, dates = None, show_rating = False, show_admin_unit = True, user_rights=None, share_links=None, calendar_links=None) %}
|
||
<div class="w-normal mx-auto">
|
||
|
||
{% if event.photo_id %}
|
||
<div class="d-flex">{{ render_image(event.photo, 700, class="mx-auto") }}</div>
|
||
{% endif %}
|
||
|
||
<div class="p-3 clearfix">
|
||
|
||
{% if user_rights %}
|
||
<div class="float-sm-right">
|
||
{{ render_event_menu(user_rights, event) }}
|
||
</div>
|
||
{% endif %}
|
||
|
||
<div class="font-weight-bold text-uppercase">
|
||
{{ render_event_date_with_dates_link(start, end, allday) }}
|
||
</div>
|
||
|
||
<h1 class="font-weight-bold my-1">{{ event.name }}{{ render_event_warning_pills(event) }}</h1>
|
||
<div class="text-muted">{{ event.event_place.name }}{% if event.event_place.location and event.event_place.location.city %}, {{ event.event_place.location.city }}{% endif %}</div>
|
||
</div>
|
||
|
||
</div>
|
||
|
||
<div class="d-flex bg-light p-3"><div class="mx-auto" style="width:40rem;">
|
||
|
||
<div class="card mb-3">
|
||
<div class="card-body">
|
||
<h2 class="mt-0">{{ _('Event') }}</h2>
|
||
|
||
{{ render_enum_prop(event.status, 'fa-info-circle', 'Status', 1) }}
|
||
{% if event.previous_start_date %}
|
||
<div><i class="fa fa-fw fa-calendar-times" data-toggle="tooltip" title="{{ _('Previous start date') }}"></i> {{ event.previous_start_date | datetimeformat('short') }}</div>
|
||
{% endif %}
|
||
|
||
{% if show_rating and event.rating and event.rating != 50 %}
|
||
{{ render_string_prop("%d/10" % (event.rating/10), 'fa-adjust', 'Rating') }}
|
||
{% endif %}
|
||
|
||
<div>
|
||
{{ render_event_add_props(event) }}
|
||
</div>
|
||
|
||
{% if event.description %}
|
||
<div class="mt-4" style="white-space:pre-wrap;">{{ event.description|urlize(nofollow=True, target='_blank', rel="nofollow") }}</div>
|
||
{% endif %}
|
||
|
||
{% if share_links or calendar_links %}
|
||
<div class="mt-4">
|
||
{% if share_links %}
|
||
<button type="button" class="btn btn-outline-secondary mr-1 mb-1" data-toggle="modal" data-target="#shareModal"><i class="fa fa-share-alt"></i> {{ _('Share') }}</button>
|
||
{{ render_share_modal(share_links) }}
|
||
{% endif %}
|
||
{% if calendar_links %}
|
||
<button type="button" class="btn btn-outline-secondary mb-1" data-toggle="modal" data-target="#calendarExportModal"><i class="fa fa-calendar"></i> {{ _('Add to calendar') }}</button>
|
||
{{ render_calendar_export_modal(calendar_links) }}
|
||
{% endif %}
|
||
</div>
|
||
{% endif %}
|
||
|
||
<div class="small mt-2">
|
||
{{ render_audit(event, show_rating) }}
|
||
<a href="{{ url_for('event_report', event_id=event.id) }}" class="text-dark">{{ _('Report event') }}</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-3">
|
||
<div class="card-body">
|
||
<h2 class="mt-0">{{ _('Place') }}</h2>
|
||
|
||
<div class="row">
|
||
{% if event.event_place.photo_id %}
|
||
<div class="col-12 col-sm-auto order-sm-last">{{ render_image(event.event_place.photo, 240, class="img-thumbnail") }}</div>
|
||
{% endif %}
|
||
|
||
<div class="col-12 col-sm">
|
||
<div class="font-weight-bold">{{ event.event_place.name }}</div>
|
||
|
||
{% if event.event_place.description %}
|
||
<div class="my-4">{{ event.event_place.description }}</div>
|
||
{% endif %}
|
||
|
||
{{ render_link_prop(event.event_place.url) }}
|
||
{{ render_location_prop(event.event_place.location) }}
|
||
|
||
{% if event.attendance_mode and event.attendance_mode.value != 2 %}
|
||
<div class="mt-2">
|
||
<a href="http://www.google.com/maps?q={{ render_place(event.event_place) | quote_plus }}" class="btn btn-outline-secondary" target="_blank" rel="noopener noreferrer"><i class="fa fa-directions"></i> {{ _('Show directions') }}</a>
|
||
</div>
|
||
{% endif %}
|
||
|
||
{% if event.attendance_mode and event.attendance_mode.value == 2 %}
|
||
<div class="mt-2">{{ _('The event takes place online.') }}</div>
|
||
{% elif event.attendance_mode and event.attendance_mode.value == 3 %}
|
||
<div class="mt-2">{{ _('The event takes place both offline and online.') }}</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{% if event.organizer %}
|
||
|
||
<div class="card mb-3">
|
||
<div class="card-body">
|
||
<h2 class="mt-0">{{ _('Organizer') }}</h2>
|
||
|
||
{{ render_event_props_seo_organizer(event.organizer) }}
|
||
{% for co_organizer in event.co_organizers %}
|
||
<div{% if loop.index > 0 %} class="mt-4"{% endif %}>
|
||
{{ render_event_props_seo_organizer(co_organizer) }}
|
||
</div>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
|
||
{% endif %}
|
||
|
||
{% if show_admin_unit %}
|
||
<div class="card mb-3">
|
||
<div class="card-body">
|
||
<h2 class="mt-0">{{ _('Organization') }}</h2>
|
||
|
||
<div class="row">
|
||
{% if event.admin_unit.logo_id %}
|
||
<div class="col-12 col-sm-auto order-sm-last">{{ render_logo(event.admin_unit.logo) }}</div>
|
||
{% endif %}
|
||
|
||
<div class="col-12 col-sm">
|
||
<div class="font-weight-bold">
|
||
<a href="{{ url_for('organizations', path=event.admin_unit.id) }}">{{ event.admin_unit.name }}</a>
|
||
{{ render_admin_unit_badges(event.admin_unit) }}
|
||
</div>
|
||
|
||
{{ render_link_prop(event.admin_unit.url) }}
|
||
{{ render_email_prop(event.admin_unit.email) }}
|
||
{{ render_phone_prop(event.admin_unit.phone) }}
|
||
{{ render_fax_prop(event.admin_unit.fax) }}
|
||
{{ render_location_prop(event.admin_unit.location) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
{% if dates and dates|length > 0 %}
|
||
<div class="card mb-3">
|
||
<div class="card-body pb-0">
|
||
<h2 class="mt-0"><a name="event-dates">{{ _('Event Dates') }}</a></div>
|
||
<div class="list-group list-group-flush mb-4" style="max-height: 30vh; overflow: scroll; overflow-y: auto;">
|
||
{% for date in dates %}
|
||
<a href="{{ url_for('event_date', id=date.id) }}" class="list-group-item">{{ render_event_date(date.start, date.end, date.allday) }}</a>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
|
||
</div>
|
||
</div>
|
||
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_props_seo_organizer(organizer) %}
|
||
<div class="row">
|
||
{% if organizer.logo_id %}
|
||
<div class="col-12 col-sm-auto order-sm-last">{{ render_logo(organizer.logo) }}</div>
|
||
{% endif %}
|
||
|
||
<div class="col-12 col-sm">
|
||
<div class="font-weight-bold">
|
||
{{ render_string_prop(organizer.name) }}
|
||
</div>
|
||
|
||
{{ render_link_prop(organizer.url) }}
|
||
{{ render_email_prop(organizer.email) }}
|
||
{{ render_phone_prop(organizer.phone) }}
|
||
{{ render_fax_prop(organizer.fax) }}
|
||
</div>
|
||
</div>
|
||
{% endmacro %}
|
||
|
||
{% macro render_google_place_autocomplete_header() %}
|
||
<script>
|
||
$( function() {
|
||
|
||
$('#location_search').select2({
|
||
theme: 'bootstrap4',
|
||
ajax: {
|
||
url: "{{ url_for('js_autocomplete_place') }}",
|
||
dataType: 'json',
|
||
delay: 250,
|
||
cache: true,
|
||
data: function (params) {
|
||
return {
|
||
keyword: params.term
|
||
};
|
||
}
|
||
},
|
||
placeholder: $('#location_search').attr("placeholder"),
|
||
minimumInputLength: 1,
|
||
templateResult: select2TemplateResult
|
||
}).on('select2:close', function (e) {
|
||
var data = select2GetData(e);
|
||
|
||
if ("gmaps_id" in data) {
|
||
$(this).val(null).trigger('change');
|
||
var location_only = $(this).attr("data-location-only");
|
||
if (location_only) {
|
||
reset_location_form();
|
||
} else {
|
||
reset_place_form();
|
||
$('#place-name').val(data.main_text);
|
||
}
|
||
|
||
get_gmaps_place_details(data.gmaps_id, location_only);
|
||
}
|
||
});
|
||
|
||
function get_gmaps_place_details(place_id, location_only) {
|
||
$.ajax({
|
||
url: "{{ url_for('js_autocomplete_gmaps_place') }}",
|
||
type: "get",
|
||
dataType: "json",
|
||
data: "gmaps_id=" + place_id,
|
||
success: function (data) {
|
||
fill_place_form_with_gmaps_place(data, "", location_only);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
</script>
|
||
{% endmacro %}
|
||
|
||
{% macro render_google_place_autocomplete_field(location_only = False) %}
|
||
<div class="form-group row">
|
||
<div class="col-sm-12">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text"><span><i class="fab fa-google"></i></span></span>
|
||
</div>
|
||
<select id="location_search" class="form-control" placeholder="{{ _('Search location on Google') }}" {% if location_only %}data-location-only="1"{% endif %}></select>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endmacro %}
|
||
|
||
{% macro render_google_filter_autocomplete_header() %}
|
||
<script>
|
||
$( function() {
|
||
|
||
$('#location').select2({
|
||
theme: 'bootstrap4',
|
||
ajax: {
|
||
url: "{{ url_for('js_autocomplete_place') }}",
|
||
dataType: 'json',
|
||
delay: 250,
|
||
cache: true,
|
||
data: function (params) {
|
||
return {
|
||
keyword: params.term
|
||
};
|
||
}
|
||
},
|
||
placeholder: $('#location').attr("placeholder"),
|
||
minimumInputLength: 1,
|
||
templateResult: select2TemplateResult
|
||
}).on('select2:close', function (e) {
|
||
var data = select2GetData(e);
|
||
|
||
if ("gmaps_id" in data) {
|
||
get_gmaps_place_details(data.gmaps_id);
|
||
}
|
||
});
|
||
|
||
function get_gmaps_place_details(place_id) {
|
||
$.ajax({
|
||
url: "{{ url_for('js_autocomplete_gmaps_place') }}",
|
||
type: "get",
|
||
dataType: "json",
|
||
data: "gmaps_id=" + place_id,
|
||
success: function (data) {
|
||
$('#coordinate').val('' + data.geometry.location.lat + ',' + data.geometry.location.lng);
|
||
}
|
||
});
|
||
}
|
||
});
|
||
</script>
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_date_instance(instance, allday, dateModifier = 'short', timeModifier = 'short') %}
|
||
{{ instance | dateformat(dateModifier) }}{% if not allday %} {{ instance | timeformat(timeModifier) }}{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_date(start, end, allday) %}
|
||
{% set start_date_str = start|dateformat('full') %}
|
||
{{ start_date_str }}{% if not allday %} {{ start | timeformat('short') }}{% endif %}
|
||
{% if end %}
|
||
{% set end_date_str = end|dateformat('full') %}
|
||
{% if end_date_str != start_date_str or not allday %} - {% endif %}
|
||
{% if end_date_str != start_date_str %}{{ end_date_str }}{% endif %}{% if not allday %} {{ end | timeformat('short') }}{% endif %}
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_date_with_dates_link(start, end, allday) %}
|
||
{{ render_event_date(start, end, allday) }}
|
||
{% if dates and dates|length > 1 %}
|
||
| <a href="#event-dates">{{ _('%(count)d event dates', count=dates|length) }}</a>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_date_in_list(event_date) %}
|
||
{{ render_event_date_instance(event_date.start, event_date.allday) }}
|
||
{% if event_date.recurrence_rule %}
|
||
<i class="fas fa-history"></i>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_in_list(event) %}
|
||
{{ render_event_date_instance(event.min_start_definition.start, event.min_start_definition.allday) }}
|
||
{% if event.is_recurring %}
|
||
<i class="fas fa-history"></i>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_pagination(pagination) %}
|
||
{% if pagination['prev_url'] or pagination['next_url'] %}
|
||
<nav aria-label="Page navigation">
|
||
<ul class="pagination">
|
||
{% if pagination['first_url'] %}
|
||
<li class="page-item"> <a class="page-link" href="{{ pagination['first_url'] }}" title="{{ _('First') }}"><i class="fa fa-angle-double-left"></i></a></li>
|
||
{% else %}
|
||
<li class="page-item disabled"><a class="page-link" href="#" title="{{ _('First') }}"><i class="fa fa-angle-double-left"></i></a></li>
|
||
{% endif %}
|
||
{% if pagination['prev_url'] %}
|
||
<li class="page-item"> <a class="page-link" href="{{ pagination['prev_url'] }}" title="{{ _('Previous') }}"><i class="fa fa-angle-left"></i></a></li>
|
||
{% else %}
|
||
<li class="page-item disabled"><a class="page-link" href="#" title="{{ _('Previous') }}"><i class="fa fa-angle-left"></i></a></li>
|
||
{% endif %}
|
||
<li class="page-item disabled d-none d-sm-inline"><span class="page-link">{{ _('Page %(page)d of %(pages)d (%(total)d total)', page=pagination["page"], pages=pagination["pages"], total=pagination["total"]) }}</span></li>
|
||
{% if pagination['next_url'] %}
|
||
<li class="page-item"> <a class="page-link" href="{{ pagination['next_url'] }}" title="{{ _('Next') }}"><i class="fa fa-angle-right"></i></a></li>
|
||
{% else %}
|
||
<li class="page-item disabled"><a class="page-link" href="#" title="{{ _('Next') }}"><i class="fa fa-angle-right"></i></a></li>
|
||
{% endif %}
|
||
{% if pagination['last_url'] %}
|
||
<li class="page-item"> <a class="page-link" href="{{ pagination['last_url'] }}" title="{{ _('Last') }}"><i class="fa fa-angle-double-right"></i></a></li>
|
||
{% else %}
|
||
<li class="page-item disabled"><a class="page-link" href="#" title="{{ _('Last') }}"><i class="fa fa-angle-double-right"></i></a></li>
|
||
{% endif %}
|
||
</ul>
|
||
</nav>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_roles(roles) %}
|
||
{% if roles %}
|
||
{% for role in roles %}{{ _(role.title) }}{%if not loop.last %}, {% endif %}{% endfor %}
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_email_button(url, title) %}
|
||
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
|
||
<tbody>
|
||
<tr>
|
||
<td align="left">
|
||
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
||
<tbody>
|
||
<tr>
|
||
<td> <a href="{{ url }}" target="_blank" rel="noopener noreferrer">{{ title }}</a> </td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
{% endmacro %}
|
||
|
||
{% macro render_radio_buttons(field) %}
|
||
{% for subfield in field %}
|
||
<div class="form-check form-check-inline">
|
||
<td>{{ subfield(class="form-check-input") }}</td>
|
||
<td>{{ subfield.label(class="form-check-label") }}</td>
|
||
</div>
|
||
{% endfor %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_dates_date_field(from_field, to_field) %}
|
||
<div class="form-group row">
|
||
<label class="col-sm-2 col-form-label">{{ _('Date') }}</label>
|
||
<div class="col-sm-5 mb-1">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text">{{ from_field.label.text }}</span>
|
||
</div>
|
||
{{ from_field(**{"class":"form-control datepicker", "data-range-to":"#date_to"})|safe }}
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-5">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text">{{ to_field.label.text }}</span>
|
||
</div>
|
||
{{ to_field(class="form-control datepicker")|safe }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_dates_location_field(location_field, distance_field) %}
|
||
{% if location_field %}
|
||
<div class="form-group row">
|
||
<label for="location" class="col-sm-2 col-form-label">{{ _('Radius') }}</label>
|
||
<div class="col-sm-7 mb-1">
|
||
<div class="input-group">
|
||
{{ location_field(class="form-control", placeholder='Ort', autocomplete="off")|safe }}
|
||
<div class="input-group-append">
|
||
<button class="btn btn-outline-secondary" type="button" id="clear_location_btn">
|
||
<i class="fa fa-times"></i>
|
||
</button>
|
||
<button class="btn btn-outline-primary" type="button" id="geolocation_btn">
|
||
<i class="fa fa-location-arrow"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="col-sm-3">
|
||
<div class="input-group">
|
||
<div class="input-group-prepend">
|
||
<span class="input-group-text">{{ distance_field.label.text }}</span>
|
||
</div>
|
||
{{ distance_field(class="form-control")|safe }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_dates_filter_form(form) %}
|
||
<form action="" id="filter_form" class="form" method="GET" autocomplete="off">
|
||
{{ form.hidden_tag() }}
|
||
|
||
{% if form.keyword %}
|
||
{{ render_field_with_errors(form.keyword) }}
|
||
{% endif %}
|
||
|
||
{% if form.category_id %}
|
||
{{ render_field_with_errors(form.category_id) }}
|
||
{% endif %}
|
||
|
||
{% if form.organizer_id %}
|
||
{{ render_field_with_errors(form.organizer_id) }}
|
||
{% endif %}
|
||
|
||
{{ render_event_dates_date_field(form.date_from, form.date_to) }}
|
||
|
||
{% if form.weekday and form.weekday.choices|length > 0 %}
|
||
{{ render_field_with_errors(form.weekday, ri="multicheckbox") }}
|
||
{% endif %}
|
||
|
||
{{ render_event_dates_location_field(form.location, form.distance) }}
|
||
|
||
{{ render_field(form.submit) }}
|
||
</form>
|
||
{% endmacro %}
|
||
|
||
{% macro render_cropper_code(field_id = "photo", min_width=320, min_height=160) %}
|
||
var field_id = "#{{ field_id }}-image_base64";
|
||
var inputImage = document.getElementById('photo-image_file');
|
||
var Cropper = window.Cropper;
|
||
var URL = window.URL || window.webkitURL;
|
||
var image = document.getElementById('photo-image');
|
||
var cropper = null;
|
||
var crop_data = null;
|
||
var minCroppedWidth = {{ min_width }};
|
||
var minCroppedHeight = {{ min_height }};
|
||
var uploadedImageURL;
|
||
var photo_modal = $('#photo_modal');
|
||
|
||
if (URL) {
|
||
inputImage.onchange = function () {
|
||
$('.dropzone-wrapper').removeClass('dragover');
|
||
|
||
var files = this.files;
|
||
var file;
|
||
|
||
if (files && files.length) {
|
||
file = files[0];
|
||
|
||
if (/^image\/\w+/.test(file.type)) {
|
||
if (uploadedImageURL) {
|
||
URL.revokeObjectURL(uploadedImageURL);
|
||
}
|
||
|
||
image.src = uploadedImageURL = URL.createObjectURL(file);
|
||
inputImage.value = null;
|
||
crop_data = null;
|
||
photo_modal.modal();
|
||
} else {
|
||
window.alert('Please choose an image file.');
|
||
}
|
||
}
|
||
};
|
||
|
||
photo_modal.on('shown.bs.modal', function () {
|
||
cropper = new Cropper(image, {
|
||
viewMode: 1,
|
||
autoCropArea: 1.0,
|
||
data: crop_data,
|
||
ready() {
|
||
var image_data = cropper.getImageData();
|
||
if (image_data.naturalWidth < minCroppedWidth || image_data.naturalHeight < minCroppedHeight) {
|
||
window.alert('Die Auflösung ist zu gering. Mindestens ' + minCroppedWidth + 'x' + minCroppedHeight + 'px.');
|
||
photo_modal.modal('hide');
|
||
}
|
||
},
|
||
crop: function (event) {
|
||
var width = event.detail.width;
|
||
var height = event.detail.height;
|
||
|
||
if (width < minCroppedWidth || height < minCroppedHeight) {
|
||
cropper.setData({
|
||
width: Math.max(minCroppedWidth, width),
|
||
height: Math.max(minCroppedHeight, height),
|
||
});
|
||
}
|
||
}
|
||
});
|
||
}).on('hidden.bs.modal', function () {
|
||
cropper.destroy();
|
||
cropper = null;
|
||
});
|
||
|
||
if ($('#photo_preview').attr("src")) {
|
||
image.src = uploadedImageURL = $('#photo_preview').attr("src");
|
||
$('.hide-if-photo-exists').hide();
|
||
} else {
|
||
$('.show-if-photo-exists').hide();
|
||
}
|
||
$('#photo-edit-btn').click(function(e){
|
||
e.preventDefault();
|
||
photo_modal.modal();
|
||
});
|
||
$('#photo-delete-btn').click(function(e){
|
||
e.preventDefault();
|
||
$(field_id).val('');
|
||
$('#photo_preview').attr("src", '');
|
||
$('.show-if-photo-exists').hide();
|
||
$('.hide-if-photo-exists').show();
|
||
});
|
||
|
||
$('#photo-zoom-in').click(function(e){
|
||
e.preventDefault();
|
||
cropper.zoom(0.1);
|
||
});
|
||
|
||
$('#photo-zoom-out').click(function(e){
|
||
e.preventDefault();
|
||
cropper.zoom(-0.1);
|
||
});
|
||
|
||
$('#photo-rotate-left').click(function(e){
|
||
e.preventDefault();
|
||
cropper.rotate(-90);
|
||
});
|
||
|
||
$('#photo-rotate-right').click(function(e){
|
||
e.preventDefault();
|
||
cropper.rotate(90);
|
||
});
|
||
|
||
$('#photo-save-btn').click(function(e){
|
||
e.preventDefault();
|
||
photo_modal.modal('hide');
|
||
|
||
if (cropper) {
|
||
var canvas = cropper.getCroppedCanvas({
|
||
maxWidth: 1200,
|
||
maxHeight: 1200,
|
||
fillColor: 'transparent'
|
||
});
|
||
var data_url = canvas.toDataURL();
|
||
crop_data = cropper.getData();
|
||
|
||
$(field_id).val(data_url);
|
||
$('#photo_preview').attr("src", data_url);
|
||
$('.show-if-photo-exists').show();
|
||
$('.hide-if-photo-exists').hide();
|
||
}
|
||
});
|
||
|
||
} else {
|
||
inputImage.disabled = true;
|
||
inputImage.parentNode.className += ' disabled';
|
||
}
|
||
{% endmacro %}
|
||
|
||
{% macro render_cropper_script(field_id = "photo", min_width=320, min_height=320) %}
|
||
<script>
|
||
$( function() {
|
||
{{ render_cropper_code(field_id, min_width, min_height) }}
|
||
});
|
||
</script>
|
||
{% endmacro %}
|
||
|
||
{% macro render_cropper_block(field_id = "photo", min_width=320, min_height=320) %}
|
||
{{ render_cropper_header() }}
|
||
{{ render_cropper_script(field_id, min_width, min_height) }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_cropper_logo_block() %}
|
||
{{ render_cropper_block("logo") }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_crop_image_form(form_field) %}
|
||
{{ form_field.hidden_tag() }}
|
||
|
||
<div class="mb-3">
|
||
<div id="photo_modal" class="modal fade" tabindex="-1" role="dialog">
|
||
<div class="modal-dialog" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">{{ _('Edit image') }}</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div style="height: 40vh;">
|
||
<img class="w-100" id="photo-image" />
|
||
</div>
|
||
<div class="my-3">
|
||
<div class="btn-group">
|
||
<button id="photo-zoom-in" type="button" class="btn btn-outline-secondary"><i class="fa fa-search-plus"></i></button>
|
||
<button id="photo-zoom-out" type="button" class="btn btn-outline-secondary"><i class="fa fa-search-minus"></i></button>
|
||
</div>
|
||
<div class="btn-group">
|
||
<button id="photo-rotate-left" type="button" class="btn btn-outline-secondary"><i class="fa fa-undo-alt"></i></button>
|
||
<button id="photo-rotate-right" type="button" class="btn btn-outline-secondary"><i class="fa fa-redo-alt"></i></button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-dismiss="modal">{{ _('Close') }}</button>
|
||
<button type="button" class="btn btn-primary" id="photo-save-btn">{{ _('Okay') }}</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-1 show-if-photo-exists"><img id="photo_preview" style="max-height: 20vh; max-width:100%;" {% if form_field.image_base64.data %}src="{{ form_field.image_base64.data }}"{% endif %} /></div>
|
||
|
||
<div class="py-1">
|
||
<div class="dropzone-wrapper mb-2 hide-if-photo-exists">
|
||
<div class="dropzone-desc">
|
||
<i class="fa fa-upload"></i>
|
||
<p>{{ _('Choose image file') }}…</p>
|
||
</div>
|
||
<input type="file" id="photo-image_file" name="photo" accept="image/*" class="dropzone" />
|
||
</div>
|
||
<button type="button" id="photo-edit-btn" class="btn btn-outline-secondary show-if-photo-exists"><i class="fa fa-edit"></i></button>
|
||
<button type="button" id="photo-delete-btn" class="btn btn-outline-secondary show-if-photo-exists"><i class="fa fa-trash"></i></button>
|
||
</div>
|
||
</div>
|
||
|
||
{{ render_field_with_errors(form_field.copyright_text) }}
|
||
{% endmacro %}
|
||
|
||
{% macro render_crop_image_form_section(form_field) %}
|
||
<div class="card mb-4">
|
||
<div class="card-header">
|
||
{{ form_field.label() }}
|
||
</div>
|
||
<div class="card-body">
|
||
{% if form_field.description %}
|
||
<div class="form-text mt-0 mb-2 text-muted w-100">
|
||
{{ form_field.description }}
|
||
</div>
|
||
{% endif %}
|
||
{{ render_crop_image_form(form_field) }}
|
||
</div>
|
||
</div>
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_menu(user_rights, event) %}
|
||
{% if user_rights|any_dict_value_true %}
|
||
<div class="dropdown my-1">
|
||
<button class="btn btn-outline-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
||
<i class="fa fa-cog"></i>
|
||
</button>
|
||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdownMenuButton">
|
||
{% if user_rights['can_update_event'] %}
|
||
<a class="dropdown-item" href="{{ url_for('event_update', event_id=event.id) }}"><i class="fa fa-edit"></i> {{ _('Edit event') }}</a>
|
||
<a class="dropdown-item" href="{{ url_for('event_delete', event_id=event.id) }}"><i class="fa fa-trash"></i> {{ _('Delete event') }}…</a>
|
||
{% endif %}
|
||
<a class="dropdown-item" href="{{ url_for('event_actions', event_id=event.id) }}">{{ _('More') }}…</a>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_jquery_steps_header() %}
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-steps/1.1.0/jquery.steps.min.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/jquery.validate.min.js" integrity="sha512-UdIMMlVx0HEynClOIFSyOrPggomfhBKJE28LKl8yR3ghkgugPnG6iLfRfHwushZl1MOPSY6TsuBDGPK2X4zYKg==" crossorigin="anonymous"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/additional-methods.min.js" integrity="sha512-6Uv+497AWTmj/6V14BsQioPrm3kgwmK9HYIyWP+vClykX52b0zrDGP7lajZoIY1nNlX4oQuh7zsGjmF7D0VZYA==" crossorigin="anonymous"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/localization/messages_de.min.js" integrity="sha512-CZoLR7uTljYchtaY9SbWetTDxZ7bW3h6YALF4orf6k+WTvZhr4zu+a9XqhHkK+zsKbQL5HNXTNrd21TE3M6eUg==" crossorigin="anonymous"></script>
|
||
<script>
|
||
jQuery.validator.addMethod("dateRange", function(value, element, params) {
|
||
var start_id = params[0];
|
||
var end_id = params[1];
|
||
|
||
var start_val = $(start_id).val();
|
||
var end_val = $(end_id).val();
|
||
|
||
if (start_val == '' || end_val == '') {
|
||
return true;
|
||
}
|
||
|
||
var start = get_moment_with_time(start_id);
|
||
var end = get_moment_with_time(end_id);
|
||
return end >= start;
|
||
}, jQuery.validator.format("{{ _('The start must be before the end.') }}"));
|
||
|
||
jQuery.validator.addMethod("dateRangeDay", function(value, element, params) {
|
||
var start_id = params[0];
|
||
var end_id = params[1];
|
||
|
||
var start_val = $(start_id).val();
|
||
var end_val = $(end_id).val();
|
||
|
||
if (start_val == '' || end_val == '') {
|
||
return true;
|
||
}
|
||
|
||
var start = get_moment_with_time(start_id);
|
||
var end = get_moment_with_time(end_id);
|
||
var max = start.add(14, 'day');
|
||
return end <= max;
|
||
}, jQuery.validator.format("{{ _('An event can last a maximum of 14 days.') }}"));
|
||
|
||
$.validator.addMethod( "time", function( value, element ) {
|
||
return this.optional( element ) || /^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test( value );
|
||
}, jQuery.validator.format("{{ _('Please enter a valid time, between 00:00 and 23:59.') }}"));
|
||
|
||
jQuery.validator.setDefaults({
|
||
errorElement: 'div',
|
||
errorClass: 'invalid-feedback',
|
||
errorPlacement: function (error, element) {
|
||
element.closest('.input-group').after(error);
|
||
},
|
||
highlight: function (element, errorClass, validClass) {
|
||
$(element).closest('.input-group').find(':input').removeClass('is-valid').addClass('is-invalid');
|
||
},
|
||
unhighlight: function (element, errorClass, validClass) {
|
||
$(element).closest('.input-group').find(':input').removeClass('is-invalid').addClass('is-valid');
|
||
},
|
||
onclick: function (element, event) {
|
||
return true;
|
||
}
|
||
});
|
||
|
||
function createSelect2Tag(params) {
|
||
var term = $.trim(params.term);
|
||
|
||
if (term === '') {
|
||
return null;
|
||
}
|
||
|
||
return {
|
||
id: term,
|
||
tag_text: "{{ _('Just use %(term)s', term='%(term)s') }}".replace("%(term)s", '"' + term + '"'),
|
||
term: term,
|
||
text: term,
|
||
is_new_tag: true
|
||
}
|
||
}
|
||
|
||
function insertSelect2Tag(data, tag) {
|
||
data.push(tag);
|
||
}
|
||
|
||
function select2TemplateResult(state) {
|
||
if ("is_new_tag" in state) {
|
||
return $("<strong>" + state.tag_text + "</strong>");
|
||
}
|
||
return state.text;
|
||
}
|
||
|
||
function select2GetData(e) {
|
||
var dataArray = $(e.target).select2('data');
|
||
var data = {};
|
||
|
||
if (dataArray.length > 0) {
|
||
data = dataArray[0];
|
||
}
|
||
|
||
return data;
|
||
}
|
||
|
||
</script>
|
||
{% endmacro %}
|
||
|
||
{% macro render_end_container_handling() %}
|
||
$('#end-container').on('shown', function() {
|
||
var end_moment = get_moment_with_time('#start');
|
||
|
||
if ($('#allday').is(':checked')) {
|
||
end_moment = end_moment.endOf('day');
|
||
} else {
|
||
end_moment = end_moment.add(3, 'hours');
|
||
}
|
||
|
||
set_picker_date($('#end-user'), end_moment.toDate());
|
||
});
|
||
|
||
$('#end-container').on('hidden', function() {
|
||
set_picker_date($('#end-user'), null);
|
||
$('#allday').prop('checked', false).trigger("change");
|
||
});
|
||
|
||
$('#allday').on('change', function() {
|
||
if (this.checked && !$("#end-container").is(":visible")) {
|
||
showLink(null, $("#end-show-container a.show-link"));
|
||
}
|
||
});
|
||
{% endmacro %}
|
||
|
||
{% macro render_cropper_header() %}
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.9/cropper.min.js" integrity="sha512-9pGiHYK23sqK5Zm0oF45sNBAX/JqbZEP7bSDHyt+nT3GddF+VFIcYNqREt0GDpmFVZI3LZ17Zu9nMMc9iktkCw==" crossorigin="anonymous"></script>
|
||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.9/cropper.min.css" integrity="sha512-w+u2vZqMNUVngx+0GVZYM21Qm093kAexjueWOv9e9nIeYJb1iEfiHC7Y+VvmP/tviQyA5IR32mwN/5hTEJx6Ng==" crossorigin="anonymous" />
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-cropper/1.0.1/jquery-cropper.min.js" integrity="sha512-V8cSoC5qfk40d43a+VhrTEPf8G9dfWlEJgvLSiq2T2BmgGRmZzB8dGe7XAABQrWj3sEfrR5xjYICTY4eJr76QQ==" crossorigin="anonymous"></script>
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_suggestion(event_suggestion, hide_review_status=False) %}
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
{{ _('Event suggestion') }}
|
||
</div>
|
||
<div class="card-body">
|
||
|
||
{% if event_suggestion.photo_id %}
|
||
<div class="">
|
||
{{ render_image(event_suggestion.photo, class='rounded', style='object-fit: cover; height: 20vh;') }}
|
||
</div>
|
||
{% elif event_suggestion.photo and event_suggestion.photo.image_base64 %}
|
||
<div class="mb-1"><img class="rounded" style="object-fit: cover; height: 20vh;" src="{{ event_suggestion.photo.image_base64 }}" /></div>
|
||
{% endif %}
|
||
|
||
<div class="text-highlight text-uppercase font-weight-bold">{{ render_event_date(event_suggestion.start, event_suggestion.end, event_suggestion.allday) }}</div>
|
||
<div class="font-weight-bold" style="font-size: 1.8rem;">{{ event_suggestion.name }}</div>
|
||
<div class="text-muted">{{ event_suggestion.event_place.name or event_suggestion.event_place_text }}</div>
|
||
|
||
<div class="mt-3"><i class="fa fa-fw fa-sitemap"></i> {{ event_suggestion.organizer.name or event_suggestion.organizer_text }}</div>
|
||
{{ render_link_prop(event_suggestion.external_link) }}
|
||
<div class="my-2">{{ event_suggestion.description }}</div>
|
||
|
||
<div class="mt-4">
|
||
{{ render_event_add_props(event_suggestion) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
{{ _('Contact') }}
|
||
</div>
|
||
<div class="card-body">
|
||
{{ render_string_prop(event_suggestion.contact_name, 'fa-user') }}
|
||
{{ render_email_prop(event_suggestion.contact_email) }}
|
||
{{ render_phone_prop(event_suggestion.contact_phone) }}
|
||
</div>
|
||
</div>
|
||
|
||
{% if not hide_review_status %}
|
||
<div class="card mb-3">
|
||
<div class="card-header">
|
||
{{ _('Review status') }}
|
||
</div>
|
||
<div class="card-body">
|
||
{{ render_event_review_status(event_suggestion) }}
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
{% endmacro %}
|
||
|
||
{% macro render_widget_styles(styles) %}
|
||
<style>
|
||
body {
|
||
{% if 'background' in styles %}
|
||
background-color: {{ styles['background'] }};
|
||
{% endif %}
|
||
{% if 'font' in styles %}
|
||
font-family: {{ styles['font'] }};
|
||
{% endif %}
|
||
}
|
||
|
||
{% if 'background' in styles %}
|
||
.page-link, .page-item.disabled .page-link {
|
||
background-color: {{ styles['background'] }};
|
||
}
|
||
{% endif %}
|
||
|
||
{% if 'primary' in styles %}
|
||
.btn-primary,
|
||
.btn-primary:hover,
|
||
.btn-primary:active,
|
||
.btn-primary:not(:disabled):not(.disabled):active,
|
||
.btn-primary:focus {
|
||
background-color: {{ styles['primary'] }};
|
||
border-color: {{ styles['primary'] }};
|
||
}
|
||
{% endif %}
|
||
|
||
{% if 'link' in styles %}
|
||
.card-title, .page-link, .page-link:hover, a, a:hover {
|
||
color: {{ styles['link'] }};
|
||
}
|
||
{% endif %}
|
||
|
||
{% if 'primary' in styles %}
|
||
.wizard > .steps .current a,
|
||
.wizard > .steps .current a:hover,
|
||
.wizard > .steps .current a:active,
|
||
.wizard > .steps .current a,
|
||
.wizard > .steps .current a:hover,
|
||
.wizard > .steps .current a:active,
|
||
.wizard > .steps .done a,
|
||
.wizard > .steps .done a:hover,
|
||
.wizard > .steps .done a:active,
|
||
.wizard > .actions a,
|
||
.wizard > .actions a:hover,
|
||
.wizard > .actions a:active
|
||
{
|
||
background-color: {{ styles['primary'] }};
|
||
}
|
||
{% endif %}
|
||
|
||
</style>
|
||
{% endmacro %}
|
||
|
||
{% macro render_share_modal(share_links) %}
|
||
<div class="modal fade" id="shareModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">{{ _('Share') }}</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="input-group mb-3">
|
||
<input id="copy_input" type="text" class="form-control" value="{{ share_links["url"] }}" />
|
||
<div class="input-group-append">
|
||
<button id="copy_input_button" class="btn btn-outline-secondary" type="button" data-toggle="tooltip" data-trigger="manual" data-title="{{ _('Link copied') }}">{{ _('Copy link') }}</button>
|
||
</div>
|
||
</div>
|
||
<div class="list-group">
|
||
<a class="list-group-item list-group-item-action" href="{{ share_links["facebook"] }}" target="_blank" rel="noopener noreferrer"><i class="fab fa-facebook"></i> Facebook</a>
|
||
<a class="list-group-item list-group-item-action" href="{{ share_links["twitter"] }}" target="_blank" rel="noopener noreferrer"><i class="fab fa-twitter"></i> Twitter</a>
|
||
<a class="list-group-item list-group-item-action" href="{{ share_links["email"] }}" target="_blank" rel="noopener noreferrer"><i class="fa fa-envelope"></i> {{ _('Email') }}</a>
|
||
<a class="list-group-item list-group-item-action" href="{{ share_links["whatsapp"] }}" target="_blank" rel="noopener noreferrer" data-action="share/whatsapp/share"><i class="fab fa-whatsapp"></i> Whatsapp</a>
|
||
<a class="list-group-item list-group-item-action" href="{{ share_links["telegram"] }}" target="_blank" rel="noopener noreferrer"><i class="fab fa-telegram"></i> Telegram</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endmacro %}
|
||
|
||
{% macro render_calendar_export_modal(calendar_links) %}
|
||
<div class="modal fade" id="calendarExportModal" tabindex="-1" role="dialog" aria-hidden="true">
|
||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">{{ _('Add to calendar') }}</h5>
|
||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||
<span aria-hidden="true">×</span>
|
||
</button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="list-group">
|
||
<a class="list-group-item list-group-item-action" href="{{ calendar_links["ics"] }}"><i class="fab fa-microsoft"></i> Outlook</a>
|
||
<a class="list-group-item list-group-item-action" href="{{ calendar_links["google"] }}" target="_blank" rel="noopener noreferrer"><i class="fab fa-google"></i> {{ _('Google calendar') }}</a>
|
||
<a class="list-group-item list-group-item-action" href="{{ calendar_links["ics"] }}"><i class="fab fa-apple"></i> {{ _('Apple calendar') }}</a>
|
||
<a class="list-group-item list-group-item-action" href="{{ calendar_links["ics"] }}"><i class="fab fa-yahoo"></i> {{ _('Yahoo calendar') }}</a>
|
||
<a class="list-group-item list-group-item-action" href="{{ calendar_links["ics"] }}"><i class="fa fa-calendar"></i> {{ _('Other calendar') }}</a>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endmacro %}
|
||
|
||
{% macro render_admin_unit_form_script(admin_unit=None) %}
|
||
<script>
|
||
|
||
$( function() {
|
||
jQuery.validator.addMethod("shortName", function(value, element) {
|
||
return this.optional(element) || /^\w+$/i.test(value);
|
||
}, jQuery.validator.format("{{ _('Short name must contain only letters numbers or underscore') }}"));
|
||
|
||
var form = $("#main-form");
|
||
var validator = form.validate({
|
||
rules: {
|
||
}
|
||
});
|
||
|
||
$("#name").rules("add", {
|
||
remote: {
|
||
param: {
|
||
url: "{{ url_for('js_check_org_name') }}",
|
||
type: "post"
|
||
{% if admin_unit %}
|
||
,data: {
|
||
admin_unit_id: function() {
|
||
return "{{ admin_unit.id }}";
|
||
}
|
||
}
|
||
{% endif %}
|
||
}
|
||
{% if admin_unit and admin_unit.name %}
|
||
,depends: function(element) {
|
||
return $('#name').val() !== '{{ admin_unit.name }}';
|
||
}
|
||
{% endif %}
|
||
}
|
||
});
|
||
|
||
$("#short_name").rules("add", "shortName");
|
||
$("#short_name").rules("add", {
|
||
remote: {
|
||
param: {
|
||
url: "{{ url_for('js_check_org_short_name') }}",
|
||
type: "post"
|
||
{% if admin_unit %}
|
||
,data: {
|
||
admin_unit_id: function() {
|
||
return "{{ admin_unit.id }}";
|
||
}
|
||
}
|
||
{% endif %}
|
||
}
|
||
{% if admin_unit.short_name %}
|
||
,depends: function(element) {
|
||
return $('#short_name').val() !== '{{ admin_unit.short_name }}';
|
||
}
|
||
{% endif %}
|
||
}
|
||
});
|
||
|
||
function suggest_short_name() {
|
||
if ($("#short_name").val().length == 0) {
|
||
var name = $("#name").val().toLowerCase().replace(/ä/g, 'ae').replace(/ö/g, 'oe').replace(/ü/g, 'ue').replace(/ß/g, 'ss');
|
||
var re = /\w/g;
|
||
var suggestion = (name.match(re) || []).join('');
|
||
|
||
$("#short_name").val(suggestion);
|
||
$("#short_name").valid();
|
||
}
|
||
}
|
||
|
||
$("#name").blur(function() {
|
||
suggest_short_name();
|
||
});
|
||
|
||
if ($("#name").val().length > 0) {
|
||
$("#name").valid();
|
||
suggest_short_name();
|
||
}
|
||
|
||
$('#location_search').on('place_changed', function() {
|
||
$('#location_search').closest('.card-body').find(':input').valid();
|
||
$('#location_search').removeClass('is-valid');
|
||
});
|
||
});
|
||
</script>
|
||
{% endmacro %}
|
||
|
||
{% macro render_form_scripts() %}
|
||
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/i18n/jquery-ui-i18n.min.js" integrity="sha256-pIEbIH2QxTg2nHVPn1HLn1asQIDxqtbZn12/kAkAZkY=" crossorigin="anonymous"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/select2.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/js/i18n/de.min.js"></script>
|
||
<script src="https://cdn.jsdelivr.net/npm/timepicker@1.13.18/jquery.timepicker.min.js"></script>
|
||
<script type="text/javascript">
|
||
var csrf_token = "{{ csrf_token() }}";
|
||
|
||
$.ajaxSetup({
|
||
beforeSend: function(xhr, settings) {
|
||
if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) {
|
||
xhr.setRequestHeader("X-CSRFToken", csrf_token);
|
||
}
|
||
}
|
||
});
|
||
|
||
$.datepicker.setDefaults($.datepicker.regional["de"]);
|
||
$.fn.select2.defaults.set("language", "de");
|
||
|
||
$(function () {
|
||
$(".autocomplete").select2({
|
||
width: "100%",
|
||
theme: "bootstrap4",
|
||
});
|
||
$(".autocomplete-multi").select2({
|
||
width: "100%",
|
||
});
|
||
});
|
||
</script>
|
||
{% endmacro %}
|
||
|
||
{% macro render_manage_form_scripts() %}
|
||
{{ render_form_scripts() }}
|
||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsrender/1.0.6/jsrender.min.js" integrity="sha512-Bh8Z8kuMiQKW0jO+zvR2I2lbRhN0eGOn3u8hxOOIU44IZZjwvNfLyzdXxQ9PtoTK68j5hQIqc9sycQnbwRlVCQ==" crossorigin="anonymous"></script>
|
||
<script src="{{ url_for('static', filename='jquery.recurrenceinput.js')}}"></script>
|
||
{% endmacro %}
|
||
|
||
{% macro render_form_styles() %}
|
||
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.min.css">
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/select2@4.1.0-beta.1/dist/css/select2.min.css" />
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@ttskch/select2-bootstrap4-theme@1.5.2/dist/select2-bootstrap4.min.css" >
|
||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/timepicker@1.13.18/jquery.timepicker.min.css" />
|
||
{% endmacro %}
|
||
|
||
{% macro render_manage_form_styles() %}
|
||
{{ render_form_styles() }}
|
||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='jquery.recurrenceinput.css')}}" />
|
||
{% endmacro %}
|
||
|
||
{% macro render_event_date_defintion_code() %}
|
||
$('.date-definition-container').ovedaDateDefinition();
|
||
var min_date_definition_index = $(".date-definition-container").length;
|
||
if (min_date_definition_index > 1) {
|
||
$('.date-definition-container button.remove-date-defintion-btn').removeClass("d-none");
|
||
}
|
||
|
||
$("#add-date-defintion-btn").click(function () {
|
||
var template = $(".date-definition-template");
|
||
var template_prefix = template.attr('data-prefix');
|
||
|
||
var last_container = $(".date-definition-container:last");
|
||
var last_prefix = last_container.attr('data-prefix');
|
||
var new_index = Math.max(min_date_definition_index, $(".date-definition-container").length);
|
||
min_date_definition_index++;
|
||
|
||
var new_prefix = last_prefix.replace(/-(\d+)-$/g, function(match, number) {
|
||
return '-' + new_index + '-';
|
||
});
|
||
|
||
var new_container = template.clone();
|
||
new_container.removeClass('date-definition-template');
|
||
new_container.removeClass('d-none');
|
||
new_container.addClass('date-definition-container');
|
||
new_container.attr('data-prefix', new_prefix);
|
||
new_container.find("*").each(function() {
|
||
var subelement = $(this);
|
||
$.each(this.attributes, function(i, attrib) {
|
||
subelement.attr(attrib.name, attrib.value.replace(template_prefix, new_prefix));
|
||
});
|
||
});
|
||
|
||
last_container.after(new_container);
|
||
new_container.ovedaDateDefinition();
|
||
|
||
if ($.find(".date-definition-container").length > 1) {
|
||
$('.date-definition-container button.remove-date-defintion-btn').removeClass("d-none");
|
||
}
|
||
return false;
|
||
});
|
||
{% endmacro %}
|
||
|
||
{% macro render_date_definition_container(date_definition, container_class="date-definition-container") %}
|
||
<div class="{{ container_class }} card mb-3 bg-light" data-prefix="{{ date_definition.id }}-">
|
||
<div class="card-body">
|
||
<div id="{{ date_definition.id }}-single-event-container">
|
||
{{ date_definition.form.hidden_tag() }}
|
||
{{ render_field_with_errors(date_definition.form.start, **{"data-range-to":"#"+date_definition.form.end.id, "data-range-max-days": "14", "data-allday": "#"+date_definition.form.allday.id}) }}
|
||
{{ render_field_with_errors(date_definition.form.end, is_collapsible=1) }}
|
||
{{ render_field_with_errors(date_definition.form.allday, ri="checkbox") }}
|
||
|
||
<button type="button" id="{{ date_definition.id }}-recc-button" class="btn btn-outline-secondary"><i class="fas fa-history"></i> {{ _('Recurring event') }}</button>
|
||
<button type="button" class="btn btn-outline-secondary remove-date-defintion-btn d-none"><i class="fa fa-calendar-minus"></i> {{ _('Remove event date') }}</button>
|
||
</div>
|
||
<div id="{{ date_definition.id }}-recc-event-container" class="recc-event-container">
|
||
{{ render_field_with_errors(date_definition.form.recurrence_rule, label_hidden=True) }}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endmacro %}
|
||
|