add plugins
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
{% if form_json_response %}
|
||||
{{ form_json_response|json_encode|raw }}
|
||||
{% else %}
|
||||
{}
|
||||
{% endif %}
|
||||
@@ -0,0 +1 @@
|
||||
{% extends "forms/default/data.html.twig" %}
|
||||
@@ -0,0 +1 @@
|
||||
{% extends "forms/default/data.txt.twig" %}
|
||||
@@ -0,0 +1,48 @@
|
||||
{% macro render_field(form, fields, scope) %}
|
||||
{% import _self as self %}
|
||||
|
||||
{% for index, field in fields %}
|
||||
{% set input = attribute(field, "input@") %}
|
||||
|
||||
{% if input is null or input == true %}
|
||||
|
||||
{% if form.value(scope ~ field.name) %}
|
||||
{% block field %}
|
||||
<div>
|
||||
{% block field_label %}
|
||||
<strong>{{ field.label|t|e }}</strong>:
|
||||
{% endblock %}
|
||||
|
||||
{% block field_value %}
|
||||
{% if field.type == 'checkboxes' %}
|
||||
<ul>
|
||||
{% set use_keys = field.use is defined and field.use == 'keys' %}
|
||||
{% for key,value in form.value(scope ~ field.name) %}
|
||||
{% set index = (use_keys ? key : value) %}
|
||||
<li>{{ field.options[index]|e }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% elseif field.type == 'checkbox' %}
|
||||
{{ (form.value(scope ~ field.name) == 1) ? "GRAV.YES"|t|e : "GRAV.NO"|t|e }}
|
||||
{% elseif field.type == 'select' %}
|
||||
{{ field.options[form.value(scope ~ field.name)]|e }}
|
||||
{% else %}
|
||||
{{ string(form.value(scope ~ field.name))|nl2br }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if field.fields %}
|
||||
{% set new_scope = field.nest_id ? scope ~ field.name ~ '.' : scope %}
|
||||
{{ self.render_field(form, field.fields, new_scope) }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% import _self as macro %}
|
||||
|
||||
{{ macro.render_field(form, form.fields, '') }}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{%- macro render_field(form, fields, scope) %}
|
||||
{%- import _self as self %}
|
||||
{%- for index, field in fields %}
|
||||
{%- set input = attribute(field, "input@") %}
|
||||
{%- if input is null or input == true %}
|
||||
{%- set value = form.value(scope ~ (field.name ?? index)) %}
|
||||
{{- scope ~ (field.name ?? index) }}: {{ string(value is iterable ? value|json_encode : value|escape('yaml')) ~ "\r\n" }}
|
||||
{%- else %}
|
||||
{%- if field.fields %}
|
||||
{%- set new_scope = field.nest_id ? scope ~ field.name ~ '.' : scope -%}
|
||||
{{- self.render_field(form, field.fields, new_scope) }}
|
||||
{%- endif %}
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
{%- endmacro %}
|
||||
{%- import _self as macro %}
|
||||
{%- autoescape false %}
|
||||
{{- macro.render_field(form, form.fields, '') ~ "\r\n" }}
|
||||
{%- endautoescape %}
|
||||
@@ -0,0 +1,139 @@
|
||||
{% if not field.validate.ignore %}
|
||||
|
||||
{% set field_name = (scope ~ field.name)|fieldName %}
|
||||
{% set vertical = field.style == 'vertical' %}
|
||||
|
||||
{% if not blueprints or (blueprints.schema.type(field.type)['input@'] ?? true) is same as(true) %}
|
||||
{% set toggleable = field.toggleable ?? false %}
|
||||
{% if toggleable %}
|
||||
{% set originalValue = originalValue is defined ? originalValue : value %}
|
||||
{% set toggleableChecked = originalValue is not null and originalValue is not empty %}
|
||||
{% elseif field.overridable %}
|
||||
{% set toggleable = true %}
|
||||
{% set default = form.getDefaultValue(field.name) ?? field.default %}
|
||||
{% set toggleableChecked = value != default %}
|
||||
{% endif %}
|
||||
|
||||
{% set cookie_name = 'forms-' ~ form.name ~ '-' ~ field.name %}
|
||||
{% set value = value ?? (get_cookie(cookie_name) is not null ? get_cookie(cookie_name) : field.default) %}
|
||||
|
||||
{% if (field.yaml or field.validate.type == 'yaml') and value is iterable %}
|
||||
{% set value = value|toYaml %}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% set toggleable = false %}
|
||||
{% endif %}
|
||||
|
||||
{# DEPRECATED: Needed by old form fields; remove when backwards compatibility breaks are allowed #}
|
||||
{% set isDisabledToggleable = toggleable and not toggleableChecked %}
|
||||
|
||||
{% set errors = attribute(form.messages, field.name) %}
|
||||
{% set required = client_side_validation and field.validate.required in ['on', 'true', 1] %}
|
||||
{% set autofocus = (inline_errors == false) and field.autofocus in ['on', 'true', 1] %}
|
||||
|
||||
{% if inline_errors and errors %}
|
||||
{% set autofocus = true %}
|
||||
{% endif %}
|
||||
|
||||
{% block field %}
|
||||
<div class="form-field {{ form_field_outer_classes }} {{ field.outerclasses }} {% if errors %} has-errors{% endif %} {% block outer_field_classes %}{% endblock %} {% if toggleable %} form-field-toggleable{% endif %}">
|
||||
{% block contents %}
|
||||
{% if field.label is not same as(false) and field.display_label is not same as(false) %}
|
||||
<div class="{{ form_field_outer_label_classes ?: 'form-label' }} {{ field.labelclasses }}">
|
||||
{% if toggleable %}
|
||||
{% include 'forms/default/toggleable.html.twig' with {field_name: field_name, field: field, checked: toggleableChecked} %}
|
||||
{% endif %}
|
||||
<label class="{{ form_field_label_classes ?: 'inline' }} {{ toggleable ? 'toggleable' }}" {% if field.id is defined %}for="{{ toggleable ? 'toggleable_' ~ field.name : field.id|e }}" {% endif %} >
|
||||
{% block label %}
|
||||
{% if field.help %}
|
||||
{% if field.markdown %}
|
||||
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|t|markdown(false)|e }}">{{ field.label|markdown(false)|default(field.name|capitalize)|t }}</span>
|
||||
{% else %}
|
||||
<span class="tooltip" data-asTooltip-position="w" title="{{ field.help|t|e }}">{{ field.label|default(field.name|capitalize)|t }}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if field.markdown %}
|
||||
{{ field.label|markdown(false)|default(field.name|capitalize)|t }}
|
||||
{% else %}
|
||||
{{ field.label|default(field.name|capitalize)|t|e('html_attr') }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
|
||||
{% endblock %}
|
||||
</label>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="{{ form_field_outer_data_classes ?: 'form-data' }} {{ field.dataclasses }}"
|
||||
{% block global_attributes %}
|
||||
data-grav-field="{{ field.type }}"
|
||||
data-grav-disabled="{{ toggleable and toggleableChecked }}"
|
||||
data-grav-default="{{ field.default|json_encode()|e('html_attr') }}"
|
||||
{% endblock %}
|
||||
>
|
||||
{% block group %}
|
||||
{% block input %}
|
||||
<div class="{{ form_field_wrapper_classes ?: 'form-input-wrapper' }} {{ field.size }} {{ field.wrapper_classes }}">
|
||||
{% block prepend %}{% endblock prepend %}
|
||||
<input
|
||||
{# required attribute structures #}
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
value="{{ value|join(', ')|e('html_attr') }}"
|
||||
{# input attribute structures #}
|
||||
{% block input_attributes %}
|
||||
class="{{ form_field_input_classes }} {{ field.classes }} {{ field.size }}"
|
||||
{% if field.id is defined %}id="{{ field.id|e }}" {% endif %}
|
||||
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
{% if field.placeholder %}placeholder="{{ field.placeholder|t|e('html_attr') }}"{% endif %}
|
||||
{% if autofocus %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if field.readonly in ['on', 'true', 1] %}readonly="readonly"{% endif %}
|
||||
{% if field.autocomplete is defined %}autocomplete="{{ field.autocomplete }}"{% endif %}
|
||||
{% if field.autocapitalize in ['off', 'characters', 'words', 'sentences'] %}autocapitalize="{{ field.autocapitalize }}"{% endif %}
|
||||
{% if field.inputmode in ['none', 'text', 'decimal', 'numeric', 'tel', 'search', 'email', 'url'] %}inputmode="{{ field.inputmode }}"{% endif %}
|
||||
{% if field.spellcheck in ['true', 'false'] %}spellcheck="{{ field.spellcheck }}"{% endif %}
|
||||
|
||||
{% if field.attributes is defined %}
|
||||
{% for attribute in field.attributes %}
|
||||
{{ attribute.name }}="{{ attribute.value|e }}"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if required %}required="required"{% endif %}
|
||||
{% if field.validate.pattern %}pattern="{{ field.validate.pattern|e }}"{% endif %}
|
||||
{% if field.validate.message %}title="{{ field.validate.message|t|e }}"
|
||||
{% elseif field.title is defined %}title="{{ field.title|t|e }}" {% endif %}
|
||||
{% if field.datasets %}
|
||||
{% for datakey, datavalue in field.datasets %}
|
||||
data-{{ datakey }}="{{ datavalue|e('html_attr') }}"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
/>
|
||||
{% block append %}{% endblock append %}
|
||||
{% if inline_errors and errors %}
|
||||
<div class="{{ form_errors_classes ?: 'form-errors' }}">
|
||||
<p class="form-message"><i class="fa fa-exclamation-circle"></i> {{ errors|first }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
{% if field.description %}
|
||||
<div class="form-extra-wrapper {{ field.wrapper_classes }}">
|
||||
<span class="form-description">
|
||||
{% if field.markdown %}
|
||||
{{ field.description|t|markdown(false)|raw }}
|
||||
{% else %}
|
||||
{{ field.description|t|raw }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% endif %}
|
||||
@@ -0,0 +1,15 @@
|
||||
{% for field_name, field in fields %}
|
||||
{% if field.type and not field.validate.ignore %}
|
||||
{%- if field_name starts with '.' -%}
|
||||
{% set field_name = name ? name ~ field_name : field_name[1:] %}
|
||||
{% set field = field|merge({ name: field_name }) %}
|
||||
{% endif %}
|
||||
|
||||
{% set value = form ? form.value(field_name) : data.value(field_name) %}
|
||||
{% block field_open %}{% endblock %}
|
||||
{% block field %}
|
||||
{% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %}
|
||||
{% endblock %}
|
||||
{% block field_close %}{% endblock %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,134 @@
|
||||
{% if form is null %}
|
||||
{% set form = grav.session.getFlashObject('form') %}
|
||||
{% endif %}
|
||||
|
||||
{% include 'partials/form-messages.html.twig' %}
|
||||
|
||||
{% set scope = scope ?: 'data.' %}
|
||||
{% set multipart = '' %}
|
||||
{% set blueprints = blueprints ?? form.blueprint() %}
|
||||
{% set method = form.method|upper|default('POST') %}
|
||||
{% set client_side_validation = form.client_side_validation is not null ? form.client_side_validation : config.plugins.form.client_side_validation|default(true) %}
|
||||
{% set inline_errors = form.inline_errors is not null ? form.inline_errors : config.plugins.form.inline_errors(false) %}
|
||||
|
||||
{% for field in form.fields %}
|
||||
{% if (method == 'POST' and field.type == 'file') %}
|
||||
{% set multipart = ' enctype="multipart/form-data"' %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% set action = form.action ?: page.route ~ uri.params %}
|
||||
{% set action = action starts with 'http' ? action : base_url ~ action %}
|
||||
|
||||
{% if (action == base_url_relative) %}
|
||||
{% set action = base_url_relative ~ '/' ~ page.slug %}
|
||||
{% endif %}
|
||||
|
||||
{% if form.keep_alive %}
|
||||
{% if grav.browser.browser == 'msie' and grav.browser.version < 12 %}
|
||||
{% do assets.addJs('plugin://form/assets/object.assign.polyfill.js') %}
|
||||
{% endif %}
|
||||
{% do assets.addJs('plugin://form/assets/form.vendor.js', { 'group': 'bottom', 'loading': 'defer' }) %}
|
||||
{% do assets.addJs('plugin://form/assets/form.min.js', { 'group': 'bottom', 'loading': 'defer' }) %}
|
||||
{% endif %}
|
||||
|
||||
{% do assets.addInlineJs("
|
||||
window.GravForm = window.GravForm || {};
|
||||
window.GravForm.config = {
|
||||
current_url: '" ~ uri.route(true) ~"',
|
||||
base_url_relative: '" ~ base_url_relative ~ "',
|
||||
param_sep: '"~ config.system.param_sep ~ "',
|
||||
form_nonce: '" ~ form.getNonce() ~ "',
|
||||
session_timeout: " ~ config.system.session.timeout ~ "
|
||||
};
|
||||
window.GravForm.translations = Object.assign({}, window.GravForm.translations || {}, { PLUGIN_FORM: {} });
|
||||
", {'group': 'bottom', 'position': 'before'}) %}
|
||||
|
||||
<form name="{{ form.name }}"
|
||||
action="{{ action | trim('/', 'right') }}"
|
||||
method="{{ method }}"{{ multipart }}
|
||||
{% if form.id %}id="{{ form.id }}"{% endif %}
|
||||
{% block form_classes %}
|
||||
class="{{ form_outer_classes }} {{ form.classes }}"
|
||||
{% endblock %}
|
||||
{% if form.novalidate %}novalidate{% endif %}
|
||||
{% if form.keep_alive %}data-grav-keepalive="true"{% endif %}
|
||||
>
|
||||
|
||||
{% block inner_markup_fields_start %}{% endblock %}
|
||||
|
||||
{% set data = data ?? form.data %}
|
||||
{% set context = context ?? data %}
|
||||
|
||||
{% block inner_markup_fields %}
|
||||
{% for field_name, field in form.fields %}
|
||||
{% set field_name = field.name ?? field_name %}
|
||||
{% if field_name and not field.validate.ignore %}
|
||||
{%- if field_name starts with '.' -%}
|
||||
{% set field_name = field_name[1:] %}
|
||||
{% set field = field|merge({ name: field_name }) %}
|
||||
{% endif %}
|
||||
|
||||
{% set value = form ? form.value(field_name) : data.value(field_name) %}
|
||||
{% block inner_markup_field_open %}{% endblock %}
|
||||
{% block process_field %}
|
||||
{% include "forms/fields/#{field.type}/#{field.type}.html.twig" ignore missing %}
|
||||
{% endblock %}
|
||||
{% block inner_markup_field_close %}{% endblock %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% include "forms/fields/formname/formname.html.twig" %}
|
||||
{% include "forms/fields/formtask/formtask.html.twig" %}
|
||||
|
||||
{% block inner_markup_fields_end %}{% endblock %}
|
||||
|
||||
{% block inner_markup_buttons_start %}
|
||||
<div class="{{ form_button_outer_classes ?: 'buttons'}}">
|
||||
{% endblock %}
|
||||
|
||||
{% for button in form.buttons %}
|
||||
{% if button.outerclasses is defined %}<div class=" {{ button.outerclasses }}">{% endif %}
|
||||
{% if button.url %}
|
||||
<a href="{{ button.url starts with 'http' ? button.url : base_url ~ button.url }}">
|
||||
{% endif %}
|
||||
<button
|
||||
{% if button.id %}id="{{ button.id }}"{% endif %}
|
||||
{% block button_classes %}
|
||||
class="{{ form_button_classes ?: 'button' }} {{ button.classes }}"
|
||||
{% endblock %}
|
||||
{% if button.disabled %}disabled="disabled"{% endif %}
|
||||
|
||||
type="{{ button.type|default('submit') }}"
|
||||
|
||||
{% if button.task %}
|
||||
name="task" value="{{ button.task }}"
|
||||
{% endif %}
|
||||
>
|
||||
{% if button.html %}
|
||||
{{ button.value|t|default('Submit')|raw }}
|
||||
{% else %}
|
||||
{{ button.value|t|default('Submit') }}
|
||||
{% endif %}
|
||||
</button>
|
||||
{% if button.url %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if button.outerclasses is defined %}</div>{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% block inner_markup_buttons_end %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% include 'forms/fields/uniqueid/uniqueid.html.twig' %}
|
||||
|
||||
{{ nonce_field(form.getNonceAction() ?? 'form', form.getNonceName() ?? 'form-nonce')|raw }}
|
||||
</form>
|
||||
|
||||
{% if config.forms.dropzone.enabled %}
|
||||
<div id="dropzone-template" style="display:none;">
|
||||
{% include 'forms/dropzone/template.html.twig' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -0,0 +1,9 @@
|
||||
<span class="checkboxes toggleable" data-grav-field="toggleable" data-grav-field-name="{{ field_name }}">
|
||||
<input type="checkbox"
|
||||
id="toggleable_{{ field.name }}"
|
||||
name="toggleable_{{ field_name }}"
|
||||
value="1"
|
||||
{% if checked %}checked="checked"{% endif %}
|
||||
>
|
||||
<label for="toggleable_{{ field.name }}"></label>
|
||||
</span>
|
||||
@@ -0,0 +1,39 @@
|
||||
<div class="dz-preview dz-file-preview">
|
||||
<div class="dz-image"><img data-dz-thumbnail /></div>
|
||||
|
||||
<div class="dz-details">
|
||||
<div class="dz-size"><span data-dz-size></span></div>
|
||||
<div class="dz-filename"><span data-dz-name></span></div>
|
||||
</div>
|
||||
<div class="dz-progress"><span class="dz-upload" data-dz-uploadprogress></span></div>
|
||||
<div class="dz-error-message"><span data-dz-errormessage></span></div>
|
||||
<a class="dz-remove" title="remove" href="javascript:undefined;" data-dz-remove>×</a>
|
||||
|
||||
<div class="dz-success-mark">
|
||||
|
||||
<svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: Sketch 3.2.1 (9971) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Check</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<path d="M23.5,31.8431458 L17.5852419,25.9283877 C16.0248253,24.3679711 13.4910294,24.366835 11.9289322,25.9289322 C10.3700136,27.4878508 10.3665912,30.0234455 11.9283877,31.5852419 L20.4147581,40.0716123 C20.5133999,40.1702541 20.6159315,40.2626649 20.7218615,40.3488435 C22.2835669,41.8725651 24.794234,41.8626202 26.3461564,40.3106978 L43.3106978,23.3461564 C44.8771021,21.7797521 44.8758057,19.2483887 43.3137085,17.6862915 C41.7547899,16.1273729 39.2176035,16.1255422 37.6538436,17.6893022 L23.5,31.8431458 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2" stroke-opacity="0.198794158" stroke="#747474" fill-opacity="0.816519475" fill="#FFFFFF" sketch:type="MSShapeGroup"></path>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
</div>
|
||||
<div class="dz-error-mark">
|
||||
|
||||
<svg width="54px" height="54px" viewBox="0 0 54 54" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<!-- Generator: Sketch 3.2.1 (9971) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>error</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="Check-+-Oval-2" sketch:type="MSLayerGroup" stroke="#747474" stroke-opacity="0.198794158" fill="#FFFFFF" fill-opacity="0.816519475">
|
||||
<path d="M32.6568542,29 L38.3106978,23.3461564 C39.8771021,21.7797521 39.8758057,19.2483887 38.3137085,17.6862915 C36.7547899,16.1273729 34.2176035,16.1255422 32.6538436,17.6893022 L27,23.3431458 L21.3461564,17.6893022 C19.7823965,16.1255422 17.2452101,16.1273729 15.6862915,17.6862915 C14.1241943,19.2483887 14.1228979,21.7797521 15.6893022,23.3461564 L21.3431458,29 L15.6893022,34.6538436 C14.1228979,36.2202479 14.1241943,38.7516113 15.6862915,40.3137085 C17.2452101,41.8726271 19.7823965,41.8744578 21.3461564,40.3106978 L27,34.6568542 L32.6538436,40.3106978 C34.2176035,41.8744578 36.7547899,41.8726271 38.3137085,40.3137085 C39.8758057,38.7516113 39.8771021,36.2202479 38.3106978,34.6538436 L32.6568542,29 Z M27,53 C41.3594035,53 53,41.3594035 53,27 C53,12.6405965 41.3594035,1 27,1 C12.6405965,1 1,12.6405965 1,27 C1,41.3594035 12.6405965,53 27,53 Z" id="Oval-2" sketch:type="MSShapeGroup"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1 @@
|
||||
{% extends "forms/default/field.html.twig" %}
|
||||
@@ -0,0 +1,99 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% macro renderer(key, text, field, scope) %}
|
||||
|
||||
{% if text is not iterable %}
|
||||
<div class="form-row{% if field.value_only %} array-field-value_only{% endif %}"
|
||||
data-grav-array-type="row">
|
||||
<span data-grav-array-action="sort" class="fa fa-bars"></span>
|
||||
{% if field.value_only != true %}
|
||||
{% if key == '0' and text == '' %}
|
||||
{% set key = '' %}
|
||||
{% endif %}
|
||||
|
||||
<input
|
||||
data-grav-array-type="key"
|
||||
type="text" value="{{ key }}"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
placeholder="{{ field.placeholder_key|e|t }}" />
|
||||
{% endif %}
|
||||
|
||||
{% if field.value_type == 'textarea' %}
|
||||
<textarea
|
||||
data-grav-array-type="value"
|
||||
name="{{ ((scope ~ field.name)|fieldName) ~ '[' ~ key ~ ']' }}"
|
||||
placeholder="{{ field.placeholder_value|e|t }}"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}>{{ text }}</textarea>
|
||||
{% else %}
|
||||
<input
|
||||
data-grav-array-type="value"
|
||||
type="text"
|
||||
name="{{ ((scope ~ field.name)|fieldName) ~ '[' ~ key ~ ']' }}"
|
||||
placeholder="{{ field.placeholder_value|e|t }}"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
value={% if text == 'true' %}true{% elseif text == 'false' %}false{% else %}"{{ text|join(', ')|e }}"{% endif %} />
|
||||
{% endif %}
|
||||
|
||||
<span data-grav-array-action="rem" class="fa fa-minus"></span>
|
||||
<span data-grav-array-action="add" class="fa fa-plus"></span>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% import _self as array_field %}
|
||||
|
||||
{% do assets.addJs('plugin://form/assets/form.vendor.js', { 'group': 'bottom', 'loading': 'defer' }) %}
|
||||
{% do assets.addJs('plugin://form/assets/form.min.js', { 'group': 'bottom', 'loading': 'defer' }) %}
|
||||
|
||||
{% block global_attributes %}
|
||||
data-grav-array-name="{{ (scope ~ field.name)|fieldName }}"
|
||||
data-grav-array-keyname="{{ field.placeholder_key|e|t }}"
|
||||
data-grav-array-valuename="{{ field.placeholder_value|e|t }}"
|
||||
data-grav-array-textarea="{{ field.value_type == 'textarea' }}"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
<div class="{{ field.size }} {{ field.classes }}" data-grav-array-type="container"{% if field.value_only %} data-grav-array-mode="value_only"{% endif %}{{ value|length <= 1 ? ' class="one-child"' : '' }}>
|
||||
{% if value|length %}
|
||||
{% for key, text in value -%}
|
||||
{% if text is not iterable %}
|
||||
{{ array_field.renderer(key, text, field, scope) }}
|
||||
{% else %}
|
||||
{# Backward compatibility for nested arrays (metas) which are not supported anymore #}
|
||||
{% for subkey, subtext in text -%}
|
||||
{{ array_field.renderer(key ~ '[' ~ subkey ~ ']', subtext, field, scope) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{%- else -%}
|
||||
{# Empty value, mock the entry field#}
|
||||
<div class="form-row" data-grav-array-type="row">
|
||||
<span data-grav-array-action="sort" class="fa fa-bars"></span>
|
||||
{% if field.value_only != true %}
|
||||
<input
|
||||
data-grav-array-type="key"
|
||||
type="text"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
placeholder="{{ field.placeholder_key|e|t }}" />
|
||||
{% endif %}
|
||||
{% if field.value_type == 'textarea' %}
|
||||
<textarea
|
||||
data-grav-array-type="value"
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
placeholder="{{ field.placeholder_value|e|t }}"></textarea>
|
||||
{% else %}
|
||||
<input
|
||||
data-grav-array-type="value"
|
||||
type="text"
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
placeholder="{{ field.placeholder_value|e|t }}" />
|
||||
{% endif %}
|
||||
<span data-grav-array-action="rem" class="fa fa-minus"></span>
|
||||
<span data-grav-array-action="add" class="fa fa-plus"></span>
|
||||
</div>
|
||||
{%- endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,10 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
{% set avatar = form.value('avatar') %}
|
||||
{% if avatar %}
|
||||
<label><img style="max-width:200px;" src="{{ base_url_simple ~ '/' ~ (avatar|first).path }}" /></label>
|
||||
{% else %}
|
||||
<label><img src="https://www.gravatar.com/avatar/{{ form.value('email')|md5 }}?s=200" /></label>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,96 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% set config = grav.config %}
|
||||
{% set site_key = field.recaptcha_site_key and field.recaptcha_site_key != 'ENTER_YOUR_CAPTCHA_SITE_KEY' ? field.recaptcha_site_key : config.plugins.form.recaptcha.site_key %}
|
||||
{% set action = (page.route|trim('/') ~ '-' ~ form.name)|underscorize %}
|
||||
{% set formName = form.name|underscorize %}
|
||||
{% set theme = config.plugins.form.recaptcha.theme ?? 'light' %}
|
||||
|
||||
{% block label %}{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
{% if not site_key %}
|
||||
<script>console && console.error('site_key was not defined for form "{{ form.name }}" (Grav Form Plugin)')</script>
|
||||
{% elseif config.plugins.form.recaptcha.version == 3 %}
|
||||
{#{% do assets.addJs('https://www.google.com/recaptcha/api.js?render='~site_key) %}#}
|
||||
<script src='https://www.google.com/recaptcha/api.js?render={{ site_key }}&theme={{ theme }}'></script>
|
||||
<script>
|
||||
(document.querySelectorAll('form') || []).forEach(function(form, index) {
|
||||
var submit = function(event) {
|
||||
event.preventDefault();
|
||||
grecaptcha.ready(function () {
|
||||
grecaptcha.execute('{{ site_key }}', { action: '{{ action }}' }).then(function(token) {
|
||||
var tokenElement = document.createElement('input');
|
||||
tokenElement.setAttribute('type', 'hidden');
|
||||
tokenElement.setAttribute('name', 'data[token]');
|
||||
tokenElement.setAttribute('value', token);
|
||||
|
||||
var actionElement = document.createElement('input');
|
||||
actionElement.setAttribute('type', 'hidden');
|
||||
actionElement.setAttribute('name', 'data[action]');
|
||||
actionElement.setAttribute('value', '{{ action }}');
|
||||
|
||||
form.insertBefore(tokenElement, form.firstChild);
|
||||
form.insertBefore(actionElement, form.firstChild);
|
||||
form.removeEventListener('submit', submit);
|
||||
form.submit();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
form.addEventListener('submit', submit);
|
||||
});
|
||||
</script>
|
||||
{% elseif config.plugins.form.recaptcha.version == '2-invisible' %}
|
||||
<script>
|
||||
function captchaOnloadCallback_{{ formName }}() {
|
||||
var form = document.querySelector('form#{{ form.id }}');
|
||||
var submits = form.querySelectorAll('[type="submit"]') || [];
|
||||
submits.forEach(function(submit) {
|
||||
submit.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
var captchaElement = form.querySelector('#g-recaptcha-{{ formName }}');
|
||||
|
||||
if (captchaElement) {
|
||||
captchaElement.remove();
|
||||
}
|
||||
|
||||
captchaElement = document.createElement('div');
|
||||
captchaElement.setAttribute('id', 'g-recaptcha-{{ formName }}');
|
||||
form.appendChild(captchaElement);
|
||||
|
||||
var widgetReference = grecaptcha.render('g-recaptcha-{{ formName }}', {
|
||||
sitekey: '{{ site_key }}', size: 'invisible',
|
||||
callback: function(/* token */) {
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
|
||||
grecaptcha.execute(widgetReference);
|
||||
});
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<script src="https://www.google.com/recaptcha/api.js?onload=captchaOnloadCallback_{{ formName }}&hl={{ grav.language.language }}&theme={{ theme }}"
|
||||
async defer></script>
|
||||
{% else %}
|
||||
<script>
|
||||
var captchaOnloadCallback_{{ formName }} = function captchaOnloadCallback_{{ formName }}() {
|
||||
grecaptcha.render('g-recaptcha-{{ formName }}', {
|
||||
'sitekey': "{{ site_key }}",
|
||||
'callback': captchaValidatedCallback_{{ formName }},
|
||||
'expired-callback': captchaExpiredCallback_{{ formName }}
|
||||
});
|
||||
};
|
||||
|
||||
var captchaValidatedCallback_{{ formName }} = function captchaValidatedCallback_{{ formName }}() {};
|
||||
var captchaExpiredCallback_{{ formName }} = function captchaExpiredCallback_{{ formName }}() {
|
||||
grecaptcha.reset();
|
||||
};
|
||||
</script>
|
||||
<script src="https://www.google.com/recaptcha/api.js?onload=captchaOnloadCallback_{{ formName }}&render=explicit&hl={{ grav.language.language }}&theme={{ theme }} "
|
||||
async defer></script>
|
||||
<div class="g-recaptcha" id="g-recaptcha-{{ formName }}"></div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,36 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block label %}
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
{% set id = field.id|default(field.name) ~ '-' ~ key %}
|
||||
<div class="{{ form_field_wrapper_classes ?: 'form-input-wrapper' }} {{ field.size }} {{ field.wrapper_classes }}">
|
||||
<input
|
||||
{# required attribute structures #}
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
value="{{ value|join(', ') }}"
|
||||
type="checkbox"
|
||||
{% if value == true %} checked="checked" {% endif %}
|
||||
|
||||
{# input attribute structures #}
|
||||
{% block input_attributes %}
|
||||
id="{{ id|e }}"
|
||||
{% if field.classes is defined %}class="{{ field.classes }}" {% endif %}
|
||||
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if required %}required="required"{% endif %}
|
||||
{% endblock %}
|
||||
/>
|
||||
<label style="display:inline;" class="inline" for="{{ id|e }}">
|
||||
{% if field.markdown %}
|
||||
{{ field.label|t|markdown(false) }}
|
||||
{% else %}
|
||||
{{ field.label|t|e }}
|
||||
{% endif %}
|
||||
{{ field.validate.required in ['on', 'true', 1] ? '<span class="required">*</span>' }}
|
||||
</label>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,43 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% set originalValue = value %}
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
{% if field.use == 'keys' and field.default %}
|
||||
{% set value = field.default|merge(value) %}
|
||||
{% endif %}
|
||||
|
||||
{% block global_attributes %}
|
||||
{{ parent() }}
|
||||
data-grav-keys="{{ field.use == 'keys' ? 'true' : 'false' }}"
|
||||
data-grav-field-name="{{ (scope ~ field.name)|fieldName }}"
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
{% for key, text in field.options %}
|
||||
|
||||
{% set id = field.id|default(field.name) ~ '-' ~ key %}
|
||||
{% set name = field.use == 'keys' ? key : id %}
|
||||
{% set val = field.use == 'keys' ? '1' : key %}
|
||||
{% set checked = (field.use == 'keys' ? value[key] : key in value) %}
|
||||
{% set help = (key in field.help_options|keys ? field.help_options[key] : false) %}
|
||||
|
||||
<div class="checkboxes {{ form_field_wrapper_classes }} {{ field.wrapper_classes }}">
|
||||
<input type="checkbox"
|
||||
id="{{ id|e }}"
|
||||
value="{{ val|e }}"
|
||||
name="{{ (scope ~ field.name)|fieldName ~ '[' ~ name ~ ']' }}"
|
||||
{% if checked %}checked="checked"{% endif %}
|
||||
{% if field.classes is defined %}class="{{ field.classes }}" {% endif %}
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
|
||||
>
|
||||
<label style="display: inline" for="{{ id|e }}">
|
||||
{% if help %}
|
||||
<span class="hint--bottom" data-hint="{{ help|t|e('html_attr') }}">{{ text|t|e }}</span>
|
||||
{% else %}
|
||||
{{ text|t|e }}
|
||||
{% endif %}
|
||||
</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,6 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="color"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
{% if field.fields %}
|
||||
<div class="form-column {{ field.classes }}">
|
||||
{% include 'forms/default/fields.html.twig' with {name: field.name, fields: field.fields} %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
<div class="form-columns {{ field.classes }}">
|
||||
{% if field.fields %}
|
||||
{% include 'forms/default/fields.html.twig' with {name: field.name, fields: field.fields} %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,21 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
{% set value = evaluate(field.condition) %}
|
||||
{% set value = value == 'true' ? 1 : value %}
|
||||
{% set value = value == 'false' ? 0 : value %}
|
||||
|
||||
{% if value %}
|
||||
{% if field.classes %}
|
||||
<div class="{{ field.classes }}">
|
||||
{% endif %}
|
||||
|
||||
{% if field.fields %}
|
||||
{% include 'forms/default/fields.html.twig' with {name: field.name, fields: field.fields} %}
|
||||
{% endif %}
|
||||
|
||||
{% if field.classes %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,8 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="date"
|
||||
{% if field.validate.min %}min="{{ field.validate.min }}"{% endif %}
|
||||
{% if field.validate.max %}max="{{ field.validate.max }}"{% endif %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1 @@
|
||||
{{ value ? value|date('m/d/Y')|e }}
|
||||
@@ -0,0 +1,2 @@
|
||||
{# DEPRECATED. Switched to Text field until implemented properly #}
|
||||
{% extends "forms/fields/text/text.html.twig" %}
|
||||
@@ -0,0 +1 @@
|
||||
{{ value ? value|date('m/d/Y \\a\\t g:i A')|e }}
|
||||
@@ -0,0 +1,17 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% if field.file %}
|
||||
{% set content = read_file(field.file) %}
|
||||
{% else %}
|
||||
{% set content = field.content %}
|
||||
{% endif %}
|
||||
|
||||
{% block input %}
|
||||
<div class="form-display-wrapper {{ field.size }} {{ field.classes }}" {% if field.id is defined %}id="{{ field.id|e }}" {% endif %}>
|
||||
{% if field.markdown %}
|
||||
{{ content|t|markdown|raw }}
|
||||
{% else %}
|
||||
{{ content|t|raw }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,7 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="email"
|
||||
{% if field.multiple in ['on', 'true', 1] %}multiple="multiple"{% endif %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,14 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
{% set scope = field.nest_id ? scope ~ field.name ~ '.' : scope %}
|
||||
|
||||
{% block field %}
|
||||
<fieldset {% if field.id is defined %}id="{{ field.id }}"{% endif %} {% if field.classes is defined %}class="{{ field.classes }}" {% endif %}>
|
||||
{% if field.legend %}
|
||||
<legend>{{ field.legend|t }}</legend>
|
||||
{% endif %}
|
||||
|
||||
{% if field.fields %}
|
||||
{% include 'forms/default/fields.html.twig' with {name: field.name, fields: field.fields} %}
|
||||
{% endif %}
|
||||
</fieldset>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,119 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% macro bytesToSize(bytes) -%}
|
||||
{% spaceless %}
|
||||
{% set kilobyte = 1024 %}
|
||||
{% set megabyte = kilobyte * 1024 %}
|
||||
{% set gigabyte = megabyte * 1024 %}
|
||||
{% set terabyte = gigabyte * 1024 %}
|
||||
|
||||
{% if bytes < kilobyte %}
|
||||
{{ bytes ~ ' B' }}
|
||||
{% elseif bytes < megabyte %}
|
||||
{{ (bytes / kilobyte)|number_format(2, '.') ~ ' KB' }}
|
||||
{% elseif bytes < gigabyte %}
|
||||
{{ (bytes / megabyte)|number_format(2, '.') ~ ' MB' }}
|
||||
{% elseif bytes < terabyte %}
|
||||
{{ (bytes / gigabyte)|number_format(2, '.') ~ ' GB' }}
|
||||
{% else %}
|
||||
{{ (bytes / terabyte)|number_format(2, '.') ~ ' TB' }}
|
||||
{% endif %}
|
||||
{% endspaceless %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro preview(path, value, global) %}
|
||||
{% if value %}
|
||||
{% set uri = global.grav.uri %}
|
||||
{% set files = global.files %}
|
||||
{% set config = global.grav.config %}
|
||||
{% set route = global.context.route() %}
|
||||
{% set type = global.context.content() is not null ? 'pages' : global.plugin ? 'plugins' : global.theme ? 'themes' : 'config' %}
|
||||
{% set blueprint_name = global.blueprints.getFilename %}
|
||||
{% if type == 'pages' %}
|
||||
{% set blueprint_name = type ~ '/' ~ blueprint_name %}
|
||||
{% endif %}
|
||||
{% set blueprint = base64_encode(blueprint_name) %}
|
||||
{% set real_path = value.thumb ?? global.context.media[path].relativePath ?? global.form.getPagePathFromToken(path) %}
|
||||
{% set remove = global.form.getFileDeleteAjaxRoute(files.name, path)|string ?: uri.addNonce(
|
||||
global.base_url_relative ~
|
||||
'/media.json' ~
|
||||
'/route' ~ config.system.param_sep ~ base64_encode(global.base_path ~ '/' ~ real_path) ~
|
||||
'/task' ~ config.system.param_sep ~ 'removeFileFromBlueprint' ~
|
||||
'/proute' ~ config.system.param_sep ~ base64_encode(route) ~
|
||||
'/blueprint' ~ config.system.param_sep ~ blueprint ~
|
||||
'/type' ~ config.system.param_sep ~ type ~
|
||||
'/field' ~ config.system.param_sep ~ files.name ~
|
||||
'/path' ~ config.system.param_sep ~ base64_encode(value.path), 'admin-form', 'admin-nonce') %}
|
||||
|
||||
{% set file = value|merge({remove: remove, path: value.thumb_url ?? (uri.rootUrl == '/' ? '/' : uri.rootUrl ~ '/' ~ real_path) }) %}
|
||||
<div class="hidden" data-file="{{ file|json_encode|e('html_attr') }}"></div>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% import _self as macro %}
|
||||
|
||||
{% set defaults = config.plugins.form %}
|
||||
{% set files = defaults.files|merge(field|default([])) %}
|
||||
{% set limit = not field.multiple ? 1 : files.limit %}
|
||||
|
||||
{% do config.set('forms.dropzone.enabled', true) %}
|
||||
|
||||
{% block input %}
|
||||
{% set page_can_upload = exists or (type == 'page' and not exists and not (field.destination starts with '@self' or field.destination starts with 'self@')) %}
|
||||
{% set max_filesize = (field.filesize > form_max_filesize or field.filesize == 0) ? form_max_filesize : field.filesize %}
|
||||
|
||||
{% block prepend %}{% endblock %}
|
||||
{% set settings = {name: field.name, paramName: (scope ~ field.name)|fieldName ~ (files.multiple ? '[]' : ''), limit: limit, filesize: max_filesize, accept: files.accept, resolution: files.resolution, resizeWidth: files.resizeWidth, resizeHeight: files.resizeHeight, resizeQuality: files.resizeQuality } %}
|
||||
{% set dropzoneSettings = field.dropzone %}
|
||||
<div class="{{ form_field_wrapper_classes ?: 'form-input-wrapper' }} {{ field.classes }} dropzone files-upload form-input-file {{ field.size }}" data-grav-file-settings="{{ settings|json_encode|e('html_attr') }}" data-dropzone-options="{{ dropzoneSettings|json_encode|e('html_attr') }}" {% if form.getFileUploadAjaxRoute %}data-file-url-add="{{ form.getFileUploadAjaxRoute() }}"{% endif %}>
|
||||
{% block file_extras %}{% endblock %}
|
||||
<input
|
||||
{# required attribute structures #}
|
||||
{% block input_attributes %}
|
||||
type="file"
|
||||
{% if files.multiple %}multiple="multiple"{% endif %}
|
||||
{% if files.accept %}accept="{{ files.accept|join(',') }}"{% endif %}
|
||||
{% if field.disabled %}disabled="disabled"{% endif %}
|
||||
{% if field.random_name %}random="true"{% endif %}
|
||||
{% if required %}required="required"{% endif %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
/>
|
||||
|
||||
{% for path, file in value %}
|
||||
{{ macro.preview(path, file, _context) }}
|
||||
{% endfor %}
|
||||
{% include 'forms/fields/hidden/hidden.html.twig' with {field: {name: '_json.' ~ field.name}, value: (value ?? [])|json_encode } %}
|
||||
</div>
|
||||
|
||||
{% if grav.browser.browser == 'msie' and grav.browser.version < 12 %}
|
||||
{% do assets.addJs('plugin://form/assets/object.assign.polyfill.js') %}
|
||||
{% endif %}
|
||||
{% do assets.addJs('jquery', 101) %}
|
||||
{% do assets.addJs('plugin://form/assets/form.vendor.js', { 'group': 'bottom', 'loading': 'defer' }) %}
|
||||
{% do assets.addJs('plugin://form/assets/form.min.js', { 'group': 'bottom', 'loading': 'defer' }) %}
|
||||
{% do assets.addCss('plugin://form/assets/dropzone.min.css', { 'group': 'form'}) %}
|
||||
{{ assets.css('form')|raw }}
|
||||
{% do assets.addInlineJs("
|
||||
window.GravForm = window.GravForm || {};
|
||||
window.GravForm = Object.assign({}, window.GravForm, {
|
||||
translations: {
|
||||
PLUGIN_FORM: {
|
||||
'DROPZONE_CANCEL_UPLOAD': " ~ 'PLUGIN_FORM.DROPZONE_CANCEL_UPLOAD'|t|json_encode ~ ",
|
||||
'DROPZONE_CANCEL_UPLOAD_CONFIRMATION': " ~ 'PLUGIN_FORM.DROPZONE_CANCEL_UPLOAD_CONFIRMATION'|t|json_encode ~ ",
|
||||
'DROPZONE_DEFAULT_MESSAGE': " ~ 'PLUGIN_FORM.DROPZONE_DEFAULT_MESSAGE'|t|json_encode ~ ",
|
||||
'DROPZONE_FALLBACK_MESSAGE': " ~ 'PLUGIN_FORM.DROPZONE_FALLBACK_MESSAGE'|t|json_encode ~ ",
|
||||
'DROPZONE_FALLBACK_TEXT': " ~ 'PLUGIN_FORM.DROPZONE_FALLBACK_TEXT'|t|json_encode ~ ",
|
||||
'DROPZONE_FILE_TOO_BIG': " ~ 'PLUGIN_FORM.DROPZONE_FILE_TOO_BIG'|t|json_encode ~ ",
|
||||
'DROPZONE_INVALID_FILE_TYPE': " ~ 'PLUGIN_FORM.DROPZONE_INVALID_FILE_TYPE'|t|json_encode ~ ",
|
||||
'DROPZONE_MAX_FILES_EXCEEDED': " ~ 'PLUGIN_FORM.DROPZONE_MAX_FILES_EXCEEDED'|t|json_encode ~ ",
|
||||
'DROPZONE_REMOVE_FILE': " ~ 'PLUGIN_FORM.DROPZONE_REMOVE_FILE'|t|json_encode ~ ",
|
||||
'DROPZONE_REMOVE_FILE_CONFIRMATION': " ~ 'PLUGIN_FORM.DROPZONE_REMOVE_FILE_CONFIRMATION'|t|json_encode ~ ",
|
||||
'DROPZONE_RESPONSE_ERROR': " ~ 'PLUGIN_FORM.DROPZONE_RESPONSE_ERROR'|t|json_encode ~ ",
|
||||
'RESOLUTION_MIN': " ~ 'PLUGIN_FORM.RESOLUTION_MIN'|t|json_encode ~ ",
|
||||
'RESOLUTION_MAX': " ~ 'PLUGIN_FORM.RESOLUTION_MAX'|t|json_encode ~ "
|
||||
}
|
||||
}
|
||||
});
|
||||
", {'group': 'bottom', 'position': 'before'}) %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,5 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
<input type="hidden" name="__form-name__" value="{{ form.name }}" />
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,8 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
{% if form.task %}
|
||||
<input type="hidden" name="task" value="{{ form.task }}" />
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
|
||||
{% set value = value ?: field.value|default(field.default) %}
|
||||
{% set value = field.evaluate ? evaluate(value) : value %}
|
||||
|
||||
<input data-grav-field="hidden" data-grav-disabled="false" type="hidden" class="input" name="{{ (scope ~ field.name)|fieldName }}" value="{{ value|join(', ')|e('html_attr') }}" />
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,12 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
<input aria-hidden="true"
|
||||
type="text"
|
||||
{% if config.plugins.form.inline_css == true %}
|
||||
style="visibility:hidden;position:absolute!important;height:1px;width:1px;overflow:hidden;clip:rect(1px,1px,1px,1px);"
|
||||
{% endif %}
|
||||
class="form-honeybear"
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
value="{{ value|join(', ') }}" />
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,26 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input %}
|
||||
<div class="form-input-wrapper {{ field.size }}">
|
||||
<input
|
||||
type="text"
|
||||
value="{{ value|e('html_attr')|join(', ') }}"
|
||||
data-key-observe="{{ (scope ~ field.name)|fieldName }}"
|
||||
{% block input_attributes %}
|
||||
{% if field.classes is defined %}class="{{ field.classes }}" {% endif %}
|
||||
{% if field.id is defined %}id="{{ field.id|e }}" {% endif %}
|
||||
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
{% if field.placeholder %}placeholder="{{ field.placeholder }}"{% endif %}
|
||||
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if field.readonly in ['on', 'true', 1] %}readonly="readonly"{% endif %}
|
||||
{% if field.autocomplete in ['on', 'off'] %}autocomplete="{{ field.autocomplete }}"{% endif %}
|
||||
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
|
||||
{% if field.validate.pattern %}pattern="{{ field.validate.pattern }}"{% endif %}
|
||||
{% if field.validate.message %}title="{{ field.validate.message|e|t }}"
|
||||
{% elseif field.title is defined %}title="{{ field.title|e|t }}" {% endif %}
|
||||
{% endblock %}
|
||||
/>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,6 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="month"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% extends "forms/fields/text/text.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="number"
|
||||
{% if field.validate.min is defined %}min="{{ field.validate.min }}"{% endif %}
|
||||
{% if field.validate.max is defined %}max="{{ field.validate.max }}"{% endif %}
|
||||
{% if field.validate.step is defined %}step="{{ field.validate.step }}"{% endif %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,6 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="password"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,23 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% set originalValue = value %}
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
|
||||
{% block input %}
|
||||
{% for key, text in field.options %}
|
||||
{% set id = field.id|default(field.name) ~ '-' ~ key %}
|
||||
|
||||
<div class="radio {{ form_field_wrapper_classes }} {{ field.wrapper_classes }}">
|
||||
<input type="radio"
|
||||
value="{{ key|e }}"
|
||||
id="{{ id|e }}"
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
{% if field.classes is defined %}class="{{ field.classes }}" {% endif %}
|
||||
{% if key == value %}checked="checked" {% endif %}
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
{% if required %}required="required"{% endif %}
|
||||
/>
|
||||
<label style="display: inline" class="inline" for="{{ id|e }}">{{ text|t|raw }}</label>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="range"
|
||||
{% if field.validate.min %}min="{{ field.validate.min }}"{% endif %}
|
||||
{% if field.validate.max %}max="{{ field.validate.max }}"{% endif %}
|
||||
{% if field.validate.step %}step="{{ field.validate.step }}"{% endif %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,21 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
{% if field.security is empty or authorize(array(field.security)) %}
|
||||
<div class="{{ field.classes }}">
|
||||
{% if field.title or field.underline %}
|
||||
<h1 class="{% if not field.underline %}no_underline{% endif %}">{{ field.title|t }}</h1>
|
||||
{% endif %}
|
||||
|
||||
{% if field.text %}
|
||||
<p>{{ field.text|t|raw }}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if field.fields %}
|
||||
<div class="form-section">
|
||||
{% include 'forms/default/fields.html.twig' with {name: field.name, fields: field.fields} %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,67 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block global_attributes %}
|
||||
data-grav-selectize="{{ (field.selectize is defined ? field.selectize : {})|json_encode()|e('html_attr') }}"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
<div class="{{ form_field_wrapper_classes ?: 'form-select-wrapper' }} {{ field.size }} {{ field.wrapper_classes }}">
|
||||
<select name="{{ (scope ~ field.name)|fieldName ~ (field.multiple ? '[]' : '') }}"
|
||||
class="{{ form_field_select_classes }} {{ field.classes }} {{ field.size }}"
|
||||
{% if field.id is defined %}id="{{ field.id|e }}" {% endif %}
|
||||
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
|
||||
{% if field.disabled %}disabled="disabled"{% endif %}
|
||||
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if required %}required="required"{% endif %}
|
||||
{% if field.multiple in ['on', 'true', 1] %}multiple="multiple"{% endif %}
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
{% if field.form %}form="{{ field.form }}"{% endif %}
|
||||
{% if field.key %}
|
||||
data-key-observe="{{ (scope ~ field.name)|fieldName }}"
|
||||
{% endif %}
|
||||
{% if field.datasets %}
|
||||
{% for datakey, datavalue in field.datasets %}
|
||||
data-{{ datakey }}="{{ datavalue|e('html_attr') }}"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
>
|
||||
{% if field.placeholder %}<option value="" disabled selected>{{ field.placeholder|t|raw }}</option>{% endif %}
|
||||
|
||||
{% set options = field.options %}
|
||||
{% if field.selectize.create and field.multiple %}
|
||||
{% set options = options|merge(value|default([]))|array_unique %}
|
||||
{% endif %}
|
||||
|
||||
{% for key, item_value in options %}
|
||||
{% if item_value is iterable and item_value.value %}
|
||||
{% set akey = field.selectize and field.multiple ? item_value : key %}
|
||||
{% set avalue = item_value.value|t %}
|
||||
<option {{ item_value.disabled ? 'disabled="disabled"' : '' }}
|
||||
{{ item_value.selected ? 'selected="selected"' : '' }}
|
||||
{{ item_value.label ? 'label=' ~ item_value.label : '' }}
|
||||
value="{{ item_value.akey }}"
|
||||
>
|
||||
{{ avalue|raw }}
|
||||
</option>
|
||||
{% elseif item_value is iterable %}
|
||||
<optgroup label="{{ key }}">
|
||||
{%for subkey, suboption in item_value %}
|
||||
{% set selected = field.selectize ? suboption : subkey %}
|
||||
{% set item_value = field.selectize and field.multiple ? suboption : subkey %}
|
||||
<option {% if subkey == value or (field.multiple and selected in value) %}selected="selected"{% endif %} value="{{ suboption }}">
|
||||
{{ suboption|t|raw }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
{% else %}
|
||||
{% set selected = field.selectize ? item_value : key %}
|
||||
{% set val = field.selectize and field.multiple ? item_value : key %}
|
||||
<option {% if val == value or (field.multiple and selected in value) %}selected="selected"{% endif %} value="{{ val }}">{{ item_value|t|raw }}</option>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
</select>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,42 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block global_attributes %}
|
||||
data-grav-selectize="{{ (field.selectize is defined ? field.selectize : {})|json_encode()|e('html_attr') }}"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
<div class="{{ form_field_wrapper_classes ?: 'form-select-wrapper' }} {{ field.size }} {{ field.wrapper_classes }}">
|
||||
<select name="{{ (scope ~ field.name)|fieldName ~ (field.multiple ? '[]' : '') }}"
|
||||
class="{{ form_field_select_classes }} {{ field.classes }}"
|
||||
{% if field.id is defined %}id="{{ field.id|e }}" {% endif %}
|
||||
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
|
||||
{% if field.disabled %}disabled="disabled"{% endif %}
|
||||
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if required %}required="required"{% endif %}
|
||||
{% if field.multiple in ['on', 'true', 1] %}multiple="multiple"{% endif %}
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
{% if field.form %}form="{{ field.form }}"{% endif %}
|
||||
{% if field.key %}
|
||||
data-key-observe="{{ (scope ~ field.name)|fieldName }}"
|
||||
{% endif %}
|
||||
>
|
||||
{% if field.placeholder %}<option value="" disabled selected>{{ field.placeholder|t|raw }}</option>{% endif %}
|
||||
|
||||
{% for key, optgroup in field.options %}
|
||||
{% set optgroup_label = optgroup|keys|first %}
|
||||
|
||||
<optgroup label="{{ optgroup_label }}">
|
||||
{%for subkey, suboption in field.options[key][optgroup_label] %}
|
||||
{% set selected = field.selectize ? suboption : subkey %}
|
||||
{% set item_value = field.selectize and field.multiple ? suboption : subkey %}
|
||||
<option {% if subkey == value or (field.multiple and selected in value) %}selected="selected"{% endif %} value="{{ suboption }}">
|
||||
{{ suboption|t|raw }}
|
||||
</option>
|
||||
{% endfor %}
|
||||
</optgroup>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,105 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block prepend %}
|
||||
<div id="signature-pad" class="signature-pad">
|
||||
<div class="signature-pad--body">
|
||||
<canvas></canvas>
|
||||
</div>
|
||||
<div class="signature-pad--footer">
|
||||
<div class="description">Sign above</div>
|
||||
|
||||
<div class="signature-pad--actions">
|
||||
<div>
|
||||
<button type="button" class="btn btn-primary-border" data-action="clear">Clear Signature</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="{{ url('plugin://form/assets/signature_pad.js') }}"></script>
|
||||
<script>
|
||||
|
||||
var wrapper = document.getElementById("signature-pad");
|
||||
var clearButton = wrapper.querySelector("[data-action=clear]");
|
||||
|
||||
var canvas = wrapper.querySelector("canvas");
|
||||
var signaturePad = new SignaturePad(canvas, {
|
||||
// It's Necessary to use an opaque color when saving image as JPEG;
|
||||
// this option can be omitted if only saving as PNG or SVG
|
||||
backgroundColor: 'rgb(255, 255, 255)',
|
||||
onEnd: function() {
|
||||
var input = document.querySelector('[name="data[{{ field.name }}]"]');
|
||||
input.value = this.toDataURL();
|
||||
}
|
||||
});
|
||||
|
||||
// Adjust canvas coordinate space taking into account pixel ratio,
|
||||
// to make it look crisp on mobile devices.
|
||||
// This also causes canvas to be cleared.
|
||||
function resizeCanvas() {
|
||||
// When zoomed out to less than 100%, for some very strange reason,
|
||||
// some browsers report devicePixelRatio as less than 1
|
||||
// and only part of the canvas is cleared then.
|
||||
var ratio = Math.max(window.devicePixelRatio || 1, 1);
|
||||
|
||||
// This part causes the canvas to be cleared
|
||||
canvas.width = canvas.offsetWidth * ratio;
|
||||
canvas.height = canvas.offsetHeight * ratio;
|
||||
canvas.getContext("2d").scale(ratio, ratio);
|
||||
|
||||
// This library does not listen for canvas changes, so after the canvas is automatically
|
||||
// cleared by the browser, SignaturePad#isEmpty might still return false, even though the
|
||||
// canvas looks empty, because the internal data of this library wasn't cleared. To make sure
|
||||
// that the state of this library is consistent with visual state of the canvas, you
|
||||
// have to clear it manually.
|
||||
signaturePad.clear();
|
||||
}
|
||||
|
||||
// On mobile devices it might make more sense to listen to orientation change,
|
||||
// rather than window resize events.
|
||||
window.onresize = resizeCanvas;
|
||||
resizeCanvas();
|
||||
|
||||
function download(dataURL, filename) {
|
||||
var blob = dataURLToBlob(dataURL);
|
||||
var url = window.URL.createObjectURL(blob);
|
||||
|
||||
var a = document.createElement("a");
|
||||
a.style = "display: none";
|
||||
a.href = url;
|
||||
a.download = filename;
|
||||
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
|
||||
window.URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
// One could simply use Canvas#toBlob method instead, but it's just to show
|
||||
// that it can be done using result of SignaturePad#toDataURL.
|
||||
function dataURLToBlob(dataURL) {
|
||||
// Code taken from https://github.com/ebidel/filer.js
|
||||
var parts = dataURL.split(';base64,');
|
||||
var contentType = parts[0].split(":")[1];
|
||||
var raw = window.atob(parts[1]);
|
||||
var rawLength = raw.length;
|
||||
var uInt8Array = new Uint8Array(rawLength);
|
||||
|
||||
for (var i = 0; i < rawLength; ++i) {
|
||||
uInt8Array[i] = raw.charCodeAt(i);
|
||||
}
|
||||
|
||||
return new Blob([uInt8Array], { type: contentType });
|
||||
}
|
||||
|
||||
clearButton.addEventListener("click", function (event) {
|
||||
signaturePad.clear();
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock prepend %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="hidden"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,19 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
<div class="form-spacer {{ field.classes }}">
|
||||
{% if field.title %}
|
||||
<h3>{{- field.title|t|raw -}}</h3>
|
||||
{% endif %}
|
||||
|
||||
{% if field.markdown %}
|
||||
<p>{{- field.text|t|markdown|raw -}}</p>
|
||||
{% else %}
|
||||
<p>{{- field.text|t|raw -}}</p>
|
||||
{% endif %}
|
||||
|
||||
{% if field.underline %}
|
||||
<hr />
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1 @@
|
||||
{% extends 'forms/fields/checkbox/checkbox.html.twig' %}
|
||||
@@ -0,0 +1,9 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
{% if field.fields %}
|
||||
<div class="form-tab">
|
||||
{% include 'forms/default/fields.html.twig' with {name: field.name, fields: field.fields} %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,66 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% if grav.admin is not defined %}
|
||||
{% do assets.addJs('plugin://form/assets/form.vendor.js', { 'group': 'bottom', 'loading': 'defer' }) %}
|
||||
{% do assets.addJs('plugin://form/assets/form.min.js', { 'group': 'bottom', 'loading': 'defer' }) %}
|
||||
{% endif %}
|
||||
|
||||
{% block field %}
|
||||
<div class="form-tabs {{ field.class }} {{ field.classes }}">
|
||||
|
||||
{% if field.fields %}
|
||||
{% set tabs = {} %}
|
||||
{% for tab in field.fields %}
|
||||
{% if tab.type == 'tab' and not tab.validate.ignore and (tab.security is empty or authorize(array(tab.security))) %}
|
||||
{% set tabs = tabs|merge([tab]) %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% set count = tabs|count %}
|
||||
|
||||
{% if count == 0 %}
|
||||
{# Nothing to display #}
|
||||
{% elseif count == 1 %}
|
||||
{% for field in (tabs|first).fields %}
|
||||
{% if field.type %}
|
||||
{% set value = field.name ? (form ? form.value(field.name) : data.value(field.name)) : data.toArray %}
|
||||
{% include ["forms/fields/#{field.type}/#{field.type}.html.twig", 'forms/fields/text/text.html.twig'] %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% set tabsKey = field.fields|keys|join('.') %}
|
||||
{% set storedValue = grav.admin is defined ? get_cookie('grav-tabs-state')|default('{}')|json_decode : [] %}
|
||||
{% set storedTab = attribute(storedValue, 'tab-' ~ tabsKey) %}
|
||||
|
||||
{% if storedTab is empty %}
|
||||
{% if uri.params.tab %}
|
||||
{% set active = uri.params.tab %}
|
||||
{% elseif field.active %}
|
||||
{% set active = field.active %}
|
||||
{% else %}
|
||||
{% set active = 1 %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<div class="tabs-nav">
|
||||
{% for tab in tabs %}
|
||||
{% if tab.type == 'tab' %}
|
||||
<a class="tab__link {{ (storedTab == scope ~ tab.name) or active == loop.index ? 'active' : '' }}" data-tabid="tab-{{ tabsKey ~ loop.index }}" data-tabkey="tab-{{ tabsKey }}" data-scope="{{ scope ~ tab.name }}">
|
||||
<span>{{ tab.title|t }}</span>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="tabs-content">
|
||||
{% embed 'forms/default/fields.html.twig' with {name: field.name, fields: field.fields} %}
|
||||
{% block field_open %}
|
||||
<div id="tab-{{ tabsKey ~ loop.index }}" class="tab__content {{ (storedTab == scope ~ field.name) or active == loop.index ? 'active' : '' }}">
|
||||
{% endblock %}
|
||||
{% block field_close %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endembed %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,6 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="tel"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,5 @@
|
||||
{% if link -%}
|
||||
<a href="{{ link }}">{{ value|join(', ')|e }}</a>
|
||||
{%- else -%}
|
||||
{{ value|join(', ')|e }}
|
||||
{%- endif %}
|
||||
@@ -0,0 +1,41 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block prepend %}
|
||||
{% if field.prepend %}
|
||||
<div class="form-input-addon form-input-prepend">
|
||||
{{- field.prepend|t|raw -}}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="text"
|
||||
{% if field.size %}size="{{ field.size }}"{% endif %}
|
||||
{% if field.minlength is defined or field.validate.min is defined %}minlength="{{ field.minlength | default(field.validate.min) }}"{% endif %}
|
||||
{% if field.maxlength is defined or field.validate.max is defined %}maxlength="{{ field.maxlength | default(field.validate.max) }}"{% endif %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block append %}
|
||||
{% if field.copy_to_clipboard %}
|
||||
<div class="form-input-addon form-input-append copy-to-clipboard">
|
||||
{{ dump(field.copy_to_clipboard|t|raw) }}
|
||||
{% if field.copy_to_clipboard in ['0', '1'] %}
|
||||
<i class="fa fa-clipboard"></i>
|
||||
{% else %}
|
||||
{{- field.copy_to_clipboard|t|raw -}}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% elseif field.append %}
|
||||
<div class="form-input-addon form-input-append">
|
||||
{{- field.append|t|raw -}}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
{% if field.prepend or field.append or field.copy_to_clipboard %}
|
||||
{% set field = field|merge({'wrapper_classes': 'form-input-addon-wrapper'}) %}
|
||||
{% endif %}
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,41 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input %}
|
||||
<div class="{{ form_field_wrapper_classes ?: 'form-textarea-wrapper' }} {{ field.size }} {{ field.wrapper_classes }}">
|
||||
{% block prepend %}{% endblock prepend %}
|
||||
<textarea
|
||||
{# required attribute structures #}
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
{# input attribute structures #}
|
||||
{% block input_attributes %}
|
||||
class="{{ form_field_textarea_classes }} {{ field.classes }} {{ field.size }}"
|
||||
{% if field.id is defined %}id="{{ field.id|e }}" {% endif %}
|
||||
{% if field.style is defined %}style="{{ field.style|e }}" {% endif %}
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
{% if field.placeholder %}placeholder="{{ field.placeholder|t }}"{% endif %}
|
||||
{% if field.autofocus in ['on', 'true', 1] %}autofocus="autofocus"{% endif %}
|
||||
{% if field.novalidate in ['on', 'true', 1] %}novalidate="novalidate"{% endif %}
|
||||
{% if field.readonly in ['on', 'true', 1] %}readonly="readonly"{% endif %}
|
||||
{% if field.autocomplete in ['on', 'off'] %}autocomplete="{{ field.autocomplete }}"{% endif %}
|
||||
{% if required %}required="required"{% endif %}
|
||||
{% if field.validate.pattern %}pattern="{{ field.validate.pattern }}"{% endif %}
|
||||
{% if field.validate.message %}title="{{ field.validate.message|t|e }}"{% endif %}
|
||||
{% if field.rows is defined %}rows="{{ field.rows }}"{% endif %}
|
||||
{% if field.cols is defined %}cols="{{ field.cols }}"{% endif %}
|
||||
{% if field.minlength is defined %}minlength="{{ field.minlength }}"{% endif %}
|
||||
{% if field.maxlength is defined %}maxlength="{{ field.maxlength }}"{% endif %}
|
||||
{% if field.datasets %}
|
||||
{% for datakey, datavalue in field.datasets %}
|
||||
data-{{ datakey }}="{{ datavalue|e('html_attr') }}"
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
>{{ value|trim|e('html') }}</textarea>
|
||||
{% block append %}{% endblock append %}
|
||||
{% if inline_errors and errors %}
|
||||
<div class="{{ form_errors_classes ?: 'form-errors' }}">
|
||||
<p class="form-message"><i class="fa fa-exclamation-circle"></i> {{ errors|first }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1 @@
|
||||
{{ value ? value|date('g:i A')|e }}
|
||||
@@ -0,0 +1,6 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="time"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,5 @@
|
||||
{%- if value -%}
|
||||
<span><i class="published fa fa-check-circle"></i></span>
|
||||
{%- else -%}
|
||||
<span><i class="unpublished fa fa-times-circle"></i></span>
|
||||
{%- endif -%}
|
||||
@@ -0,0 +1,62 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% macro spanToggle(input, length) %}
|
||||
{% set space = repeat(' ', (length - input|length) / 2) %}
|
||||
{{ (space ~ input ~ space)|raw }}
|
||||
{% endmacro %}
|
||||
|
||||
{% import _self as macro %}
|
||||
|
||||
{% set value = value ?? field.default %}
|
||||
{% set value = (value is same as(false) ? 0 : value) %}
|
||||
|
||||
{% set has_hidden = false %}
|
||||
{% for key, text in field.options %}
|
||||
{% if key is empty %}
|
||||
{% set has_hidden = true %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% block global_attributes %}
|
||||
{{ parent() }}
|
||||
data-grav-field-name="{{ (scope ~ field.name)|fieldName }}"
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
|
||||
<div class="switch-toggle switch-grav {{ field.size }} switch-{{ field.options|length }} {{ field.classes }}">
|
||||
{% set maxLen = 0 %}
|
||||
{% for text in field.options %}
|
||||
{% set translation = text|t|trim %}
|
||||
{% set maxLen = max(translation|length, maxLen) %}
|
||||
{% endfor %}
|
||||
|
||||
{% for key, text in field.options %}
|
||||
{% set id = "toggle_" ~ field.name ~ key %}
|
||||
{% set translation = text|t|trim %}
|
||||
|
||||
<input type="radio"
|
||||
value="{{ key }}"
|
||||
id="{{ id }}"
|
||||
name="{{ (scope ~ field.name)|fieldName }}"
|
||||
{% if field.highlight is defined %}
|
||||
class="{{ field.highlight == '' ~ key ? 'highlight' : '' }}"
|
||||
{% endif %}
|
||||
{% if field.disabled or isDisabledToggleable %}disabled="disabled"{% endif %}
|
||||
{% if field.toggleable %}
|
||||
{% if '' ~ key == '' ~ value %}
|
||||
checked="checked"
|
||||
{% elseif value is defined and (key == 1 or key == '1') %}
|
||||
checked="checked"
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if '' ~ key == '' ~ value %}
|
||||
checked="checked"
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if field.validate.required in ['on', 'true', 1] %}required="required"{% endif %}
|
||||
/>
|
||||
<label for="{{ id }}">{{ (macro.spanToggle(translation, maxLen)|trim)|raw }}</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,5 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block field %}
|
||||
<input type="hidden" name="__unique_form_id__" value="{{ form.uniqueid() ?? random_string(20) }}" />
|
||||
{% endblock %}
|
||||
@@ -0,0 +1 @@
|
||||
<a href="{{ url(value) }}" target="_blank"><i class="fa fa-link"></i>{{ value|e }}</a>
|
||||
@@ -0,0 +1,6 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="url"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,18 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% if field.options %}
|
||||
{% set value = field.options[value] ?: value %}
|
||||
{% endif %}
|
||||
|
||||
{% block input %}
|
||||
<span class="field-value">
|
||||
{% switch field.filter %}
|
||||
{% case 'date' %}
|
||||
{{ value|date }}
|
||||
{% case 'raw' %}
|
||||
{{ value|raw }}
|
||||
{% default %}
|
||||
{{ value }}
|
||||
{% endswitch %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,6 @@
|
||||
{% extends "forms/field.html.twig" %}
|
||||
|
||||
{% block input_attributes %}
|
||||
type="week"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
@@ -0,0 +1 @@
|
||||
{% extends "forms/default/form.html.twig" %}
|
||||
Reference in New Issue
Block a user