feat: VivesPOS landing on Winter CMS 1.2 — theme + plugin + Dockerfile
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
Some checks are pending
Module sub-split / Sub-split (push) Waiting to run
- Base: wintercms/winter branch 1.2 (full framework) - Theme vivespos: Canvas 7 + Bootstrap 5 CDN, custom CSS - Layout: deferred GTM/GA4 tracking, JSON-LD SoftwareApplication - Partials: hero (offline-first), features, modes (offline/nube toggle), screenshots, pricing (3 planes), comparison, FAQ, CTA - Plugin VivesPOS.Site with ContactForm - Dockerfile: PHP 8.2 Apache, port 80, healthcheck - Added winter/wn-pages, blog, sitemap, seo plugins - Active theme set to vivespos
This commit is contained in:
391
modules/backend/widgets/form/assets/js/winter.form.js
Normal file
391
modules/backend/widgets/form/assets/js/winter.form.js
Normal file
@@ -0,0 +1,391 @@
|
||||
/*
|
||||
* Form Widget
|
||||
*
|
||||
* Dependences:
|
||||
* - Nil
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
var Base = $.wn.foundation.base,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var FormWidget = function (element, options) {
|
||||
this.$el = $(element)
|
||||
this.options = options || {}
|
||||
this.fieldElementCache = null
|
||||
|
||||
/*
|
||||
* Throttle dependency updating
|
||||
*/
|
||||
this.dependantUpdateInterval = 300
|
||||
this.dependantUpdateTimers = {}
|
||||
|
||||
$.wn.foundation.controlUtils.markDisposable(element)
|
||||
Base.call(this)
|
||||
this.init()
|
||||
}
|
||||
|
||||
FormWidget.prototype = Object.create(BaseProto)
|
||||
FormWidget.prototype.constructor = FormWidget
|
||||
|
||||
FormWidget.prototype.init = function() {
|
||||
|
||||
this.$form = this.$el.closest('form')
|
||||
|
||||
this.bindDependants()
|
||||
this.bindCheckboxlist()
|
||||
this.toggleEmptyTabs()
|
||||
this.bindLazyTabs()
|
||||
this.bindCollapsibleSections()
|
||||
|
||||
this.$el.on('oc.triggerOn.afterUpdate', this.proxy(this.toggleEmptyTabs))
|
||||
this.$el.one('dispose-control', this.proxy(this.dispose))
|
||||
}
|
||||
|
||||
FormWidget.prototype.dispose = function() {
|
||||
this.unbindDependants()
|
||||
this.unbindCheckboxList()
|
||||
this.unbindLazyTabs()
|
||||
this.unbindCollapsibleSections()
|
||||
|
||||
this.$el.off('dispose-control', this.proxy(this.dispose))
|
||||
this.$el.removeData('oc.formwidget')
|
||||
|
||||
this.$el = null
|
||||
this.$form = null
|
||||
this.options = null
|
||||
this.fieldElementCache = null
|
||||
|
||||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
||||
/*
|
||||
* Logic for checkboxlist
|
||||
*/
|
||||
FormWidget.prototype.bindCheckboxlist = function() {
|
||||
|
||||
var checkAllBoxes = function($field, flag) {
|
||||
$('input[type=checkbox]', $field)
|
||||
.prop('checked', flag)
|
||||
.first()
|
||||
.trigger('change')
|
||||
}
|
||||
|
||||
this.$el.on('click', '[data-field-checkboxlist-all]', function() {
|
||||
checkAllBoxes($(this).closest('.field-checkboxlist'), true)
|
||||
})
|
||||
|
||||
this.$el.on('click', '[data-field-checkboxlist-none]', function() {
|
||||
checkAllBoxes($(this).closest('.field-checkboxlist'), false)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Unbind checkboxlist handlers
|
||||
*/
|
||||
FormWidget.prototype.unbindCheckboxList = function() {
|
||||
this.$el.off('click', '[data-field-checkboxlist-all]')
|
||||
this.$el.off('click', '[data-field-checkboxlist-none]')
|
||||
}
|
||||
|
||||
/*
|
||||
* Get all fields elements that belong to this form, nested form
|
||||
* fields are removed from this collection.
|
||||
*/
|
||||
FormWidget.prototype.getFieldElements = function() {
|
||||
if (this.fieldElementCache !== null) {
|
||||
return this.fieldElementCache
|
||||
}
|
||||
|
||||
var form = this.$el,
|
||||
nestedFields = form.find('[data-control="formwidget"] [data-field-name]')
|
||||
|
||||
return this.fieldElementCache = form.find('[data-field-name]').not(nestedFields)
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind dependant fields
|
||||
*/
|
||||
FormWidget.prototype.bindDependants = function() {
|
||||
var self = this,
|
||||
fieldMap = this._getDependants()
|
||||
|
||||
/*
|
||||
* When a field is updated, refresh its dependents
|
||||
*/
|
||||
$.each(fieldMap, function(fieldName, toRefresh) {
|
||||
$(document).on('change.oc.formwidget',
|
||||
'[data-field-name="' + fieldName + '"]',
|
||||
$.proxy(self.onRefreshDependants, self, fieldName, toRefresh)
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* Dispose of the dependant field handlers
|
||||
*/
|
||||
FormWidget.prototype.unbindDependants = function() {
|
||||
var fieldMap = this._getDependants()
|
||||
|
||||
$.each(fieldMap, function(fieldName, toRefresh) {
|
||||
$(document).off('change.oc.formwidget', '[data-field-name="' + fieldName + '"]')
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve the dependant fields
|
||||
*/
|
||||
FormWidget.prototype._getDependants = function() {
|
||||
if (!$('[data-field-depends]', this.$el).length) {
|
||||
return;
|
||||
}
|
||||
|
||||
var fieldMap = {},
|
||||
fieldElements = this.getFieldElements()
|
||||
|
||||
/*
|
||||
* Map master and slave fields
|
||||
*/
|
||||
fieldElements.filter('[data-field-depends]').each(function() {
|
||||
var name = $(this).data('field-name'),
|
||||
depends = $(this).data('field-depends')
|
||||
|
||||
$.each(depends, function(index, depend){
|
||||
if (!fieldMap[depend]) {
|
||||
fieldMap[depend] = { fields: [] }
|
||||
}
|
||||
|
||||
fieldMap[depend].fields.push(name)
|
||||
})
|
||||
})
|
||||
|
||||
return fieldMap
|
||||
}
|
||||
|
||||
/*
|
||||
* Refresh a dependancy field
|
||||
* Uses a throttle to prevent duplicate calls and click spamming.
|
||||
*
|
||||
* The event parameter is passed automatically by jQuery as the third
|
||||
* argument (after the two preset arguments from $.proxy). It carries
|
||||
* a cascadeChain array that tracks which fields have already been
|
||||
* refreshed in the current cascade, preventing infinite loops when
|
||||
* fields have circular dependsOn declarations.
|
||||
*/
|
||||
FormWidget.prototype.onRefreshDependants = function(fieldName, toRefresh, event) {
|
||||
var self = this,
|
||||
form = this.$el,
|
||||
formEl = this.$form,
|
||||
fieldElements = this.getFieldElements(),
|
||||
cascadeChain = (event && event.cascadeChain) || []
|
||||
|
||||
/*
|
||||
* If this field already appears in the cascade chain, we have
|
||||
* a circular dependency. Stop the cascade to prevent an
|
||||
* infinite loop. See: https://github.com/wintercms/winter/issues/421
|
||||
*/
|
||||
if (cascadeChain.indexOf(fieldName) !== -1) {
|
||||
return
|
||||
}
|
||||
|
||||
if (this.dependantUpdateTimers[fieldName] !== undefined) {
|
||||
window.clearTimeout(this.dependantUpdateTimers[fieldName])
|
||||
}
|
||||
|
||||
this.dependantUpdateTimers[fieldName] = window.setTimeout(function() {
|
||||
var refreshData = $.extend({},
|
||||
toRefresh,
|
||||
paramToObj('data-refresh-data', self.options.refreshData)
|
||||
)
|
||||
|
||||
formEl.request(self.options.refreshHandler, {
|
||||
data: refreshData
|
||||
}).success(function() {
|
||||
self.toggleEmptyTabs()
|
||||
|
||||
var newChain = cascadeChain.concat([fieldName])
|
||||
$.each(toRefresh.fields, function(key, field) {
|
||||
var cascadeEvent = $.Event('change')
|
||||
cascadeEvent.cascadeChain = newChain
|
||||
$('[data-field-name="' + field + '"]').trigger(cascadeEvent)
|
||||
})
|
||||
})
|
||||
}, this.dependantUpdateInterval)
|
||||
|
||||
$.each(toRefresh.fields, function(index, field) {
|
||||
fieldElements.filter('[data-field-name="'+field+'"]:visible')
|
||||
.addClass('loading-indicator-container size-form-field')
|
||||
.loadIndicator()
|
||||
})
|
||||
}
|
||||
|
||||
/*
|
||||
* Render tab form fields once a lazy tab is selected.
|
||||
*/
|
||||
FormWidget.prototype.bindLazyTabs = function() {
|
||||
var tabControl = $('[data-control=tab]', this.$el),
|
||||
tabContainer = $('.nav-tabs', tabControl)
|
||||
|
||||
tabContainer.on('click', '.tab-lazy [data-toggle="tab"]', function() {
|
||||
var $el = $(this),
|
||||
handlerName = $el.data('tab-lazy-handler')
|
||||
|
||||
$.request(handlerName, {
|
||||
data: {
|
||||
target: $el.data('target'),
|
||||
name: $el.data('tab-name'),
|
||||
section: $el.data('tab-section'),
|
||||
},
|
||||
success: function(data) {
|
||||
this.success(data)
|
||||
$el.parent().removeClass('tab-lazy')
|
||||
// Trigger all input presets to populate new fields.
|
||||
setTimeout(function() {
|
||||
$('[data-input-preset]').each(function() {
|
||||
var preset = $(this).data('oc.inputPreset')
|
||||
if (preset && preset.$src) {
|
||||
preset.$src.trigger('input')
|
||||
}
|
||||
})
|
||||
}, 0)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// If initial active tab is lazy loaded, load it immediately
|
||||
if ($('> li.active.tab-lazy', tabContainer).length) {
|
||||
$('> li.active.tab-lazy > [data-toggle="tab"]', tabContainer).trigger('click')
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Unbind the lazy tab handlers
|
||||
*/
|
||||
FormWidget.prototype.unbindLazyTabs = function() {
|
||||
var tabControl = $('[data-control=tab]', this.$el)
|
||||
|
||||
$('.nav-tabs', tabControl).off('click', '.tab-lazy [data-toggle="tab"]')
|
||||
}
|
||||
|
||||
/*
|
||||
* Hides tabs that have no content, it is possible this can be
|
||||
* called multiple times in a single cycle due to input.trigger.
|
||||
*/
|
||||
FormWidget.prototype.toggleEmptyTabs = function() {
|
||||
var self = this,
|
||||
form = this.$el
|
||||
|
||||
if (this.toggleEmptyTabsTimer !== undefined) {
|
||||
window.clearTimeout(this.toggleEmptyTabsTimer)
|
||||
}
|
||||
|
||||
this.toggleEmptyTabsTimer = window.setTimeout(function() {
|
||||
|
||||
var tabControl = $('[data-control=tab]', self.$el),
|
||||
tabContainer = $('.nav-tabs', tabControl)
|
||||
|
||||
if (!tabControl.length || !form || !form.length || !$.contains(form.get(0), tabControl.get(0)))
|
||||
return
|
||||
|
||||
/*
|
||||
* Check each tab pane for form field groups
|
||||
*/
|
||||
$('.tab-pane:not(.lazy)', tabControl).each(function() {
|
||||
$('[data-target="#' + $(this).attr('id') + '"]', tabControl)
|
||||
.closest('li')
|
||||
.toggle(!!$('> .form-group:not(:empty):not(.hide)', $(this)).length)
|
||||
})
|
||||
|
||||
/*
|
||||
* If a hidden tab was selected, select the first visible tab
|
||||
*/
|
||||
if (!$('> li.active:visible', tabContainer).length) {
|
||||
$('> li:visible:first', tabContainer)
|
||||
.find('> a:first')
|
||||
.tab('show')
|
||||
}
|
||||
|
||||
}, 1)
|
||||
}
|
||||
|
||||
/*
|
||||
* Makes sections collapsible by targeting every field after
|
||||
* up until the next section
|
||||
*/
|
||||
FormWidget.prototype.bindCollapsibleSections = function() {
|
||||
$('.section-field[data-field-collapsible]', this.$form)
|
||||
.addClass('collapsed')
|
||||
.find('.field-section:first')
|
||||
.addClass('is-collapsible')
|
||||
.end()
|
||||
.on('click', function() {
|
||||
$(this)
|
||||
.toggleClass('collapsed')
|
||||
.nextUntil('.section-field').toggle()
|
||||
})
|
||||
.nextUntil('.section-field').hide()
|
||||
}
|
||||
|
||||
/*
|
||||
* Unbinds collapsible section handlers
|
||||
*/
|
||||
FormWidget.prototype.unbindCollapsibleSections = function() {
|
||||
$('.section-field[data-field-collapsible]', this.$form).off('click')
|
||||
}
|
||||
|
||||
FormWidget.DEFAULTS = {
|
||||
refreshHandler: null,
|
||||
refreshData: {}
|
||||
}
|
||||
|
||||
// FORM WIDGET PLUGIN DEFINITION
|
||||
// ============================
|
||||
|
||||
var old = $.fn.formWidget
|
||||
|
||||
$.fn.formWidget = function (option) {
|
||||
var args = arguments,
|
||||
result
|
||||
|
||||
this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('oc.formwidget')
|
||||
var options = $.extend({}, FormWidget.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
if (!data) $this.data('oc.formwidget', (data = new FormWidget(this, options)))
|
||||
if (typeof option == 'string') result = data[option].call($this)
|
||||
if (typeof result != 'undefined') return false
|
||||
})
|
||||
|
||||
return result ? result : this
|
||||
}
|
||||
|
||||
$.fn.formWidget.Constructor = FormWidget
|
||||
|
||||
// FORM WIDGET NO CONFLICT
|
||||
// =================
|
||||
|
||||
$.fn.formWidget.noConflict = function () {
|
||||
$.fn.formWidget = old
|
||||
return this
|
||||
}
|
||||
|
||||
// FORM WIDGET DATA-API
|
||||
// ==============
|
||||
|
||||
function paramToObj(name, value) {
|
||||
if (value === undefined) value = ''
|
||||
if (typeof value == 'object') return value
|
||||
|
||||
try {
|
||||
return ocJSON("{" + value + "}")
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error('Error parsing the '+name+' attribute value. '+e)
|
||||
}
|
||||
}
|
||||
|
||||
$(document).render(function() {
|
||||
$('[data-control="formwidget"]').formWidget();
|
||||
})
|
||||
|
||||
}(window.jQuery);
|
||||
11
modules/backend/widgets/form/partials/_field-container.php
Normal file
11
modules/backend/widgets/form/partials/_field-container.php
Normal file
@@ -0,0 +1,11 @@
|
||||
<div
|
||||
class="form-group <?= $this->previewMode ? 'form-group-preview' : '' ?> <?= $field->type ?>-field span-<?= $field->span ?> <?= $field->required?'is-required':'' ?> <?= $field->stretch?'layout-relative':'' ?> <?= $field->cssClass ?>"
|
||||
<?php if ($depends = $this->getFieldDepends($field)): ?>
|
||||
data-field-depends="<?= $depends ?>"
|
||||
<?php endif ?>
|
||||
data-field-name="<?= $field->fieldName ?>"
|
||||
<?= $field->getAttributes('container') ?>
|
||||
id="<?= $field->getId('group') ?>"><?=
|
||||
/* Must be on the same line for :empty selector */
|
||||
trim($this->makePartial('field', ['field' => $field]))
|
||||
?></div>
|
||||
30
modules/backend/widgets/form/partials/_field.php
Normal file
30
modules/backend/widgets/form/partials/_field.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php if (!$field->hidden): ?>
|
||||
|
||||
<?php if (!$this->showFieldLabels($field)): ?>
|
||||
|
||||
<?= $this->renderFieldElement($field) ?>
|
||||
|
||||
<?php else: ?>
|
||||
<?php
|
||||
$fieldComment = $field->commentHtml ? trans($field->comment) : e(trans($field->comment));
|
||||
?>
|
||||
|
||||
<?php if ($field->label): ?>
|
||||
<label for="<?= $field->getId() ?>">
|
||||
<?= e(trans($field->label)) ?>
|
||||
</label>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($field->comment && $field->commentPosition == 'above'): ?>
|
||||
<p class="help-block before-field"><?= $fieldComment ?></p>
|
||||
<?php endif ?>
|
||||
|
||||
<?= $this->renderFieldElement($field) ?>
|
||||
|
||||
<?php if ($field->comment && $field->commentPosition == 'below'): ?>
|
||||
<p class="help-block"><?= $fieldComment ?></p>
|
||||
<?php endif ?>
|
||||
|
||||
<?php endif ?>
|
||||
|
||||
<?php endif ?>
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
$fieldOptions = $field->options();
|
||||
?>
|
||||
<!-- Balloon selector -->
|
||||
<div
|
||||
data-control="balloon-selector"
|
||||
id="<?= $field->getId() ?>"
|
||||
class="control-balloon-selector <?= $this->previewMode || $field->disabled ? 'control-disabled' : '' ?>"
|
||||
<?= $field->getAttributes() ?>>
|
||||
<ul>
|
||||
<?php foreach ($fieldOptions as $value => $text): ?>
|
||||
<li data-value="<?= e($value) ?>" class="<?= $field->isSelected($value) ? 'active' : '' ?>"><?= e(trans($text)) ?></li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="<?= $field->getName() ?>"
|
||||
id="<?= $field->getId() ?>"
|
||||
value="<?= e($field->value) ?>"
|
||||
/>
|
||||
</div>
|
||||
74
modules/backend/widgets/form/partials/_field_button.php
Normal file
74
modules/backend/widgets/form/partials/_field_button.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
/**
|
||||
* @var \Winter\Storm\Database\Model $formModel
|
||||
* @var \Backend\Classes\FormField $field
|
||||
*/
|
||||
$action = 'button';
|
||||
$handler = null;
|
||||
$href = null;
|
||||
$target = null;
|
||||
|
||||
if (!empty($field->config['href']) || filter_var($field->value, FILTER_VALIDATE_URL)) {
|
||||
$action = 'link';
|
||||
$href = $field->config['href'] ?? '';
|
||||
$target = $field->config['target'] ?? null;
|
||||
if ($formModel->hasAttribute($href)) {
|
||||
$href = $formModel->getAttribute($href);
|
||||
}
|
||||
if (filter_var($field->value, FILTER_VALIDATE_URL)) {
|
||||
$href = $field->value;
|
||||
}
|
||||
} elseif (!empty($field->config['handler'])) {
|
||||
$action = 'popup';
|
||||
$handler = $field->config['handler'];
|
||||
}
|
||||
|
||||
$element = $action === 'link' ? 'a' : 'button';
|
||||
$label = $field->config['buttonLabel'] ?? '';
|
||||
$buttonType = $field->config['buttonType'] ?? 'default';
|
||||
$classes = implode(' ', array_filter([
|
||||
"btn btn-$buttonType",
|
||||
$field->config['buttonCssClass'] ?? ''
|
||||
]));
|
||||
$request = $field->config['request'] ?? '';
|
||||
|
||||
$loadingText = $field->config['loading'] ?? '';
|
||||
$icon = $field->config['icon'] ?? '';
|
||||
?>
|
||||
<div class="loading-indicator-container">
|
||||
<?php if ($field->path): ?>
|
||||
<?= $this->controller->makePartial($field->path, [
|
||||
'formWidget' => $this,
|
||||
'formModel' => $formModel,
|
||||
'formField' => $field,
|
||||
'formValue' => $field->value,
|
||||
'model' => $formModel,
|
||||
'field' => $field,
|
||||
'value' => $field->value,
|
||||
'action' => $action,
|
||||
'element' => $element,
|
||||
'label' => $label,
|
||||
'buttonType' => $buttonType,
|
||||
'classes' => $classes,
|
||||
'handler' => $handler,
|
||||
'request' => $request,
|
||||
'href' => $href,
|
||||
'target' => $target,
|
||||
'loading' => $loadingText,
|
||||
'icon' => $icon,
|
||||
]) ?>
|
||||
<?php else: ?>
|
||||
<<?= e($element); ?>
|
||||
class="<?= e($classes); ?>"
|
||||
data-load-indicator<?= !empty($loadingText) ? '="' . e(trans($loadingText)) . '"' : ''; ?>
|
||||
<?= $action === 'popup' ? 'data-control="popup"' : ''; ?>
|
||||
<?= !empty($handler) ? 'data-handler="' . e($handler) . '"' : ''; ?>
|
||||
<?= !empty($request) ? 'data-request="' . e($request) . '"' : ''; ?>
|
||||
<?= !empty($href) ? 'href="' . e($href) . '"' : ''; ?>
|
||||
<?= !empty($target) ? 'target="' . e($target) . '"' : ''; ?>
|
||||
>
|
||||
<?= !empty($icon) ? '<i class="' . e($icon) . '"></i>' : '' ?>
|
||||
<?= e(trans($label)); ?>
|
||||
</<?= e($element); ?>>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
23
modules/backend/widgets/form/partials/_field_checkbox.php
Normal file
23
modules/backend/widgets/form/partials/_field_checkbox.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<!-- Checkbox -->
|
||||
<div class="checkbox custom-checkbox" tabindex="0">
|
||||
<input
|
||||
type="hidden"
|
||||
name="<?= $field->getName() ?>"
|
||||
value="0"
|
||||
<?= $this->previewMode ? 'disabled="disabled"' : '' ?>>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="<?= $field->getId() ?>"
|
||||
name="<?= $field->getName() ?>"
|
||||
value="1"
|
||||
<?= $this->previewMode ? 'disabled="disabled"' : '' ?>
|
||||
<?= $field->isSelected() ? 'checked="checked"' : '' ?>
|
||||
<?= $field->getAttributes() ?>>
|
||||
|
||||
<label for="<?= $field->getId() ?>">
|
||||
<?= e(trans($field->label)) ?>
|
||||
</label>
|
||||
<?php if ($field->comment): ?>
|
||||
<p class="help-block"><?= $field->commentHtml ? trans($field->comment) : e(trans($field->comment)) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
120
modules/backend/widgets/form/partials/_field_checkboxlist.php
Normal file
120
modules/backend/widgets/form/partials/_field_checkboxlist.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
$fieldOptions = $field->options();
|
||||
$checkedValues = (array) $field->value;
|
||||
$isScrollable = count($fieldOptions) > 10;
|
||||
$readOnly = $this->previewMode || $field->readOnly || $field->disabled;
|
||||
$quickselectEnabled = $field->getConfig('quickselect', $isScrollable);
|
||||
?>
|
||||
<!-- Checkbox List -->
|
||||
<?php if ($readOnly && $field->value): ?>
|
||||
|
||||
<div class="field-checkboxlist">
|
||||
<?php
|
||||
$index = 0;
|
||||
foreach ($fieldOptions as $value => $option):
|
||||
$index++;
|
||||
$checkboxId = 'checkbox_'.$field->getId().'_'.$index;
|
||||
if (!in_array($value, $checkedValues)) {
|
||||
continue;
|
||||
}
|
||||
if (!is_array($option)) {
|
||||
$option = [$option];
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="checkbox custom-checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="<?= $checkboxId ?>"
|
||||
name="<?= $field->getName() ?>[]"
|
||||
value="<?= e($value) ?>"
|
||||
disabled="disabled"
|
||||
checked="checked">
|
||||
|
||||
<label for="<?= $checkboxId ?>">
|
||||
<?= e(trans($option[0])) ?>
|
||||
</label>
|
||||
<?php if (isset($option[1])): ?>
|
||||
<p class="help-block"><?= e(trans($option[1])) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
|
||||
<?php elseif (count($fieldOptions)): ?>
|
||||
|
||||
<div class="field-checkboxlist <?= $isScrollable ? 'is-scrollable' : '' ?>">
|
||||
<?php if ($quickselectEnabled): ?>
|
||||
<!-- Quick selection -->
|
||||
<div class="checkboxlist-controls">
|
||||
<div>
|
||||
<a href="javascript:;" data-field-checkboxlist-all>
|
||||
<i class="icon-check-square"></i> <?= e(trans('backend::lang.form.select_all')) ?>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="javascript:;" data-field-checkboxlist-none>
|
||||
<i class="icon-eraser"></i> <?= e(trans('backend::lang.form.select_none')) ?>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="field-checkboxlist-inner">
|
||||
|
||||
<?php if ($isScrollable): ?>
|
||||
<!-- Scrollable Checkbox list -->
|
||||
<div class="field-checkboxlist-scrollable">
|
||||
<div class="control-scrollbar" data-control="scrollbar">
|
||||
<?php endif ?>
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="<?= $field->getName() ?>"
|
||||
value="0" />
|
||||
|
||||
<?php
|
||||
$index = 0;
|
||||
foreach ($fieldOptions as $value => $option):
|
||||
$index++;
|
||||
$checkboxId = 'checkbox_'.$field->getId().'_'.$index;
|
||||
if (!is_array($option)) {
|
||||
$option = [$option];
|
||||
}
|
||||
?>
|
||||
|
||||
<div class="checkbox custom-checkbox">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="<?= $checkboxId ?>"
|
||||
name="<?= $field->getName() ?>[]"
|
||||
value="<?= e($value) ?>"
|
||||
<?= $readOnly ? 'disabled="disabled"' : '' ?>
|
||||
<?= in_array($value, $checkedValues) ? 'checked="checked"' : '' ?>>
|
||||
|
||||
<label for="<?= $checkboxId ?>">
|
||||
<?= e(trans($option[0])) ?>
|
||||
</label>
|
||||
<?php if (isset($option[1])): ?>
|
||||
<p class="help-block"><?= e(trans($option[1])) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
|
||||
<?php if ($isScrollable): ?>
|
||||
</div>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<!-- No options specified -->
|
||||
<?php if ($field->placeholder): ?>
|
||||
<p><?= e(trans($field->placeholder)) ?></p>
|
||||
<?php endif ?>
|
||||
|
||||
<?php endif ?>
|
||||
43
modules/backend/widgets/form/partials/_field_dropdown.php
Normal file
43
modules/backend/widgets/form/partials/_field_dropdown.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
$fieldOptions = $field->options();
|
||||
if ($fieldOptions instanceof Illuminate\Support\Collection) {
|
||||
$fieldOptions = $fieldOptions->all();
|
||||
}
|
||||
?>
|
||||
|
||||
<!-- Dropdown -->
|
||||
<?php if ($this->previewMode || $field->readOnly): ?>
|
||||
<div class="form-control" <?= $field->readOnly ? 'disabled="disabled"' : ''; ?>>
|
||||
<?= (isset($fieldOptions[$field->value])) ? e(trans($fieldOptions[$field->value])) : '' ?>
|
||||
</div>
|
||||
<input type="hidden" name="<?= $field->getName() ?>" value="<?= $field->value ?>">
|
||||
<?php else:
|
||||
$emptyOption = $field->getConfig('emptyOption', $field->placeholder);
|
||||
$options = $field->getAttributes(htmlBuild:false);
|
||||
$options['id'] = $field->getId();
|
||||
$options['class'] = 'form-control custom-select';
|
||||
if ($field->getConfig('showSearch', true) === false) {
|
||||
$options['class'] .= ' select-no-search';
|
||||
}
|
||||
if ($field->getConfig('allowCustom', false)) {
|
||||
$options['class'] .= ' select-modifiable';
|
||||
}
|
||||
if ($emptyOption) {
|
||||
$options['emptyOption'] = e(trans($emptyOption));
|
||||
}
|
||||
if ($field->placeholder) {
|
||||
$options['data-placeholder'] = e(trans($field->placeholder));
|
||||
}
|
||||
foreach ($fieldOptions as $key => &$value) {
|
||||
if (is_string($value) && str_contains($value, '::')) {
|
||||
$value = e(trans($value));
|
||||
}
|
||||
}
|
||||
?>
|
||||
<?= Form::select(
|
||||
name: $field->getName(),
|
||||
list: $fieldOptions,
|
||||
selected: $field->value,
|
||||
options: $options
|
||||
) ?>
|
||||
<?php endif ?>
|
||||
30
modules/backend/widgets/form/partials/_field_email.php
Normal file
30
modules/backend/widgets/form/partials/_field_email.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<!-- Email -->
|
||||
<div class="input-group static">
|
||||
<span class="input-group-addon">
|
||||
<i class="empty wn-icon-envelope"></i>
|
||||
</span>
|
||||
<?php if ($this->previewMode): ?>
|
||||
<?php if ($field->value): ?>
|
||||
<a
|
||||
href="mailto:<?= e($field->value) ?>"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="form-control"
|
||||
>
|
||||
<?= e($field->value) ?>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span class="form-control"> </span>
|
||||
<?php endif ?>
|
||||
<?php else: ?>
|
||||
<input
|
||||
type="email"
|
||||
name="<?= $field->getName() ?>"
|
||||
id="<?= $field->getId() ?>"
|
||||
value="<?= e($field->value) ?>"
|
||||
placeholder="<?= e(trans($field->placeholder)) ?>"
|
||||
class="form-control"
|
||||
<?= $field->getAttributes() ?>
|
||||
/>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
8
modules/backend/widgets/form/partials/_field_hint.php
Normal file
8
modules/backend/widgets/form/partials/_field_hint.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?= $this->controller->makeHintPartial($field->getId(), $field->path ?: $field->fieldName, [
|
||||
'formModel' => $formModel,
|
||||
'formField' => $field,
|
||||
'formValue' => $field->value,
|
||||
'model' => $formModel,
|
||||
'field' => $field,
|
||||
'value' => $field->value
|
||||
]) ?>
|
||||
26
modules/backend/widgets/form/partials/_field_number.php
Normal file
26
modules/backend/widgets/form/partials/_field_number.php
Normal file
@@ -0,0 +1,26 @@
|
||||
<!-- Number -->
|
||||
<?php if ($this->previewMode): ?>
|
||||
<span class="form-control"><?= isset($field->value) ? e($field->value) : ' ' ?></span>
|
||||
<?php else: ?>
|
||||
<?php
|
||||
$min = isset($field->config['min']) ? $field->config['min'] : false;
|
||||
$max = isset($field->config['max']) ? $field->config['max'] : false;
|
||||
$step = isset($field->config['step']) ? $field->config['step'] : 'any';
|
||||
?>
|
||||
|
||||
<input
|
||||
type="number"
|
||||
step="<?= $step ?>"
|
||||
name="<?= $field->getName() ?>"
|
||||
id="<?= $field->getId() ?>"
|
||||
value="<?= e($field->value) ?>"
|
||||
placeholder="<?= e(trans($field->placeholder)) ?>"
|
||||
class="form-control"
|
||||
autocomplete="off"
|
||||
<?= $min !== false ? 'min="' . $min . '"' : ''; ?>
|
||||
<?= $max !== false ? 'max="' . $max . '"' : ''; ?>
|
||||
<?= $field->hasAttribute('pattern') ? '' : 'pattern="-?\d+(\.\d+)?"' ?>
|
||||
<?= $field->hasAttribute('maxlength') ? '' : 'maxlength="255"' ?>
|
||||
<?= $field->getAttributes() ?>
|
||||
/>
|
||||
<?php endif ?>
|
||||
9
modules/backend/widgets/form/partials/_field_partial.php
Normal file
9
modules/backend/widgets/form/partials/_field_partial.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?= $this->controller->makePartial($field->path ?: $field->fieldName, [
|
||||
'formWidget' => $this,
|
||||
'formModel' => $formModel,
|
||||
'formField' => $field,
|
||||
'formValue' => $field->value,
|
||||
'model' => $formModel,
|
||||
'field' => $field,
|
||||
'value' => $field->value
|
||||
]) ?>
|
||||
16
modules/backend/widgets/form/partials/_field_password.php
Normal file
16
modules/backend/widgets/form/partials/_field_password.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<!-- Password -->
|
||||
<?php if ($this->previewMode): ?>
|
||||
<div class="form-control">********</div>
|
||||
<?php else: ?>
|
||||
<input
|
||||
type="password"
|
||||
name="<?= $field->getName() ?>"
|
||||
id="<?= $field->getId() ?>"
|
||||
value=""
|
||||
placeholder="<?= e(trans($field->placeholder)) ?>"
|
||||
class="form-control"
|
||||
<?= $field->hasAttribute('autocomplete') ? '' : 'autocomplete="new-password"' ?>
|
||||
<?= $field->hasAttribute('maxlength') ? '' : 'maxlength="255"' ?>
|
||||
<?= $field->getAttributes() ?>
|
||||
/>
|
||||
<?php endif ?>
|
||||
43
modules/backend/widgets/form/partials/_field_radio.php
Normal file
43
modules/backend/widgets/form/partials/_field_radio.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
$fieldOptions = $field->options();
|
||||
?>
|
||||
<!-- Radio List -->
|
||||
<?php if (count($fieldOptions)): ?>
|
||||
|
||||
<?php $index = 0; foreach ($fieldOptions as $value => $option): ?>
|
||||
<?php
|
||||
$index++;
|
||||
if (is_string($option)) {
|
||||
$option = array($option);
|
||||
}
|
||||
|
||||
$fieldId = md5(uniqid($field->getId($index), true));
|
||||
?>
|
||||
<div class="radio custom-radio">
|
||||
|
||||
<input
|
||||
id="<?= $fieldId ?>"
|
||||
name="<?= $field->getName() ?>"
|
||||
value="<?= e($value) ?>"
|
||||
type="radio"
|
||||
<?= $field->isSelected($value) ? 'checked="checked"' : '' ?>
|
||||
<?= $this->previewMode ? 'disabled="disabled"' : '' ?>
|
||||
<?= $field->getAttributes() ?>>
|
||||
|
||||
<label for="<?= $fieldId ?>">
|
||||
<?= e(trans($option[0])) ?>
|
||||
</label>
|
||||
<?php if (isset($option[1])): ?>
|
||||
<p class="help-block"><?= e(trans($option[1])) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<!-- No options specified -->
|
||||
<?php if ($field->placeholder): ?>
|
||||
<p><?= e(trans($field->placeholder)) ?></p>
|
||||
<?php endif ?>
|
||||
|
||||
<?php endif ?>
|
||||
40
modules/backend/widgets/form/partials/_field_range.php
Normal file
40
modules/backend/widgets/form/partials/_field_range.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<!-- Range -->
|
||||
<?php if ($this->previewMode): ?>
|
||||
<span class="form-control"><?= isset($field->value) ? e($field->value) : ' ' ?></span>
|
||||
<?php else: ?>
|
||||
<?php
|
||||
$min = $field->config['min'] ?? 0;
|
||||
$max = $field->config['max'] ?? 100;
|
||||
$step = $field->config['step'] ?? 1;
|
||||
$value = $field->value;
|
||||
if ($min > $max) {
|
||||
$min = $max - $step;
|
||||
}
|
||||
if (is_null($value)) {
|
||||
$value = ($min + $max) / 2;
|
||||
}
|
||||
?>
|
||||
|
||||
<input
|
||||
type="range"
|
||||
step="<?= $step ?>"
|
||||
name="<?= $field->getName() ?>"
|
||||
id="<?= $field->getId() ?>"
|
||||
value="<?= e($value) ?>"
|
||||
min="<?= $min ?>"
|
||||
max="<?= $max ?>"
|
||||
<?= $field->getAttributes() ?>
|
||||
/>
|
||||
<span style="position: absolute; transform: translateX(-50%)"></span>
|
||||
<script>
|
||||
(() => {
|
||||
const input = document.getElementById("<?= $field->getId() ?>");
|
||||
input.addEventListener("input", function () {
|
||||
this.nextElementSibling.innerHTML = this.value;
|
||||
var pos = ((this.value - <?= $min ?>) / (<?= $max ?> - <?= $min ?>) * 100);
|
||||
this.nextElementSibling.style.left = `calc(${pos}% + ${8 - pos * 0.15}px)`;
|
||||
});
|
||||
input.dispatchEvent(new Event('input'));
|
||||
})();
|
||||
</script>
|
||||
<?php endif; ?>
|
||||
10
modules/backend/widgets/form/partials/_field_section.php
Normal file
10
modules/backend/widgets/form/partials/_field_section.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<!-- Section -->
|
||||
<div class="field-section">
|
||||
<?php if ($field->label): ?>
|
||||
<h4><?= e(trans($field->label)) ?></h4>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($field->comment): ?>
|
||||
<p class="help-block"><?= $field->commentHtml ? trans($field->comment) : e(trans($field->comment)) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
38
modules/backend/widgets/form/partials/_field_switch.php
Normal file
38
modules/backend/widgets/form/partials/_field_switch.php
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
$previewMode = false;
|
||||
if ($this->previewMode || $field->readOnly) {
|
||||
$previewMode = true;
|
||||
}
|
||||
|
||||
$on = isset($field->config['on']) ? $field->config['on'] : 'backend::lang.form.field_on';
|
||||
$off = isset($field->config['off']) ? $field->config['off'] : 'backend::lang.form.field_off';
|
||||
?>
|
||||
|
||||
<!-- Switch -->
|
||||
<div class="<?= $previewMode ? 'disabled' : '' ?>">
|
||||
<div class="field-switch">
|
||||
<label for="<?= $field->getId() ?>"><?= e(trans($field->label)) ?></label>
|
||||
<?php if ($field->comment): ?>
|
||||
<p class="help-block"><?= $field->commentHtml ? trans($field->comment) : e(trans($field->comment)) ?></p>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="<?= $field->getName() ?>"
|
||||
value="0"
|
||||
<?= $previewMode ? 'disabled="disabled"' : '' ?>>
|
||||
|
||||
<label class="custom-switch" <?= $previewMode ? 'onclick="return false"' : '' ?>>
|
||||
<input
|
||||
type="checkbox"
|
||||
id="<?= $field->getId() ?>"
|
||||
name="<?= $field->getName() ?>"
|
||||
value="1"
|
||||
<?= $previewMode ? 'readonly="readonly"' : '' ?>
|
||||
<?= $field->value == 1 ? 'checked="checked"' : '' ?>
|
||||
<?= $field->getAttributes() ?>>
|
||||
<span><span><?= e(trans($on)) ?></span><span><?= e(trans($off)) ?></span></span>
|
||||
<a class="slide-button"></a>
|
||||
</label>
|
||||
</div>
|
||||
49
modules/backend/widgets/form/partials/_field_tel.php
Normal file
49
modules/backend/widgets/form/partials/_field_tel.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<!-- Tel (Phone) -->
|
||||
<?php
|
||||
$fieldOptions = $field->options();
|
||||
$hasOptions = is_array($fieldOptions) && count($fieldOptions);
|
||||
$listId = $hasOptions ? $field->getId() . '-list' : null;
|
||||
?>
|
||||
<div class="input-group static">
|
||||
<span class="input-group-addon">
|
||||
<i class="empty wn-icon-phone"></i>
|
||||
</span>
|
||||
<?php if ($this->previewMode): ?>
|
||||
<?php if ($field->value): ?>
|
||||
<a
|
||||
href="tel:<?= e($field->value) ?>"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="form-control"
|
||||
>
|
||||
<?= e($field->value) ?>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span class="form-control"> </span>
|
||||
<?php endif ?>
|
||||
<?php else: ?>
|
||||
<input
|
||||
type="tel"
|
||||
id="<?= $field->getId() ?>"
|
||||
name="<?= $field->getName() ?>"
|
||||
value="<?= e($field->value) ?>"
|
||||
class="form-control"
|
||||
<?= isset($field->autocomplete) && is_string($field->autocomplete) ? 'autocomplete="' . e($field->autocomplete) . '"' : '' ?>
|
||||
<?= isset($field->maxlength) && is_numeric($field->maxlength) ? 'maxlength="' . e($field->maxlength) . '"' : '' ?>
|
||||
<?= isset($field->minlength) && is_numeric($field->minlength) ? 'minlength="' . e($field->minlength) . '"' : '' ?>
|
||||
<?= isset($field->pattern) && is_string($field->pattern) ? 'pattern="' . e($field->pattern) . '"' : '' ?>
|
||||
<?= isset($field->placeholder) && is_string($field->placeholder) ? 'placeholder="' . e(trans($field->placeholder)) . '"' : '' ?>
|
||||
<?= isset($field->size) && is_numeric($field->size) ? 'size="' . e($field->size) . '"' : '' ?>
|
||||
<?= $field->getAttributes() ?>
|
||||
<?= $listId ? 'list="' . e($listId) . '"' : '' ?>
|
||||
/>
|
||||
<?php if ($hasOptions): ?>
|
||||
<datalist id="<?= e($listId) ?>">
|
||||
<?php foreach ($fieldOptions as $value => $label): ?>
|
||||
<?php $value = is_int($value) ? $label : $value ?>
|
||||
<option value="<?= e($value) ?>"<?= $value !== $label ? ' label="' . e(trans($label)) . '"' : '' ?>></option>
|
||||
<?php endforeach ?>
|
||||
</datalist>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
15
modules/backend/widgets/form/partials/_field_text.php
Normal file
15
modules/backend/widgets/form/partials/_field_text.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<!-- Text -->
|
||||
<?php if ($this->previewMode): ?>
|
||||
<span class="form-control"><?= $field->value ? e($field->value) : ' ' ?></span>
|
||||
<?php else: ?>
|
||||
<input
|
||||
type="text"
|
||||
name="<?= $field->getName() ?>"
|
||||
id="<?= $field->getId() ?>"
|
||||
value="<?= e($field->value) ?>"
|
||||
placeholder="<?= e(trans($field->placeholder)) ?>"
|
||||
class="form-control"
|
||||
autocomplete="off"
|
||||
<?= $field->getAttributes() ?>
|
||||
/>
|
||||
<?php endif ?>
|
||||
12
modules/backend/widgets/form/partials/_field_textarea.php
Normal file
12
modules/backend/widgets/form/partials/_field_textarea.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<!-- Textarea -->
|
||||
<?php if ($this->previewMode): ?>
|
||||
<div class="form-control"><?= nl2br(e($field->value)) ?></div>
|
||||
<?php else: ?>
|
||||
<textarea
|
||||
name="<?= $field->getName() ?>"
|
||||
id="<?= $field->getId() ?>"
|
||||
autocomplete="off"
|
||||
class="form-control field-textarea size-<?= $field->size ?>"
|
||||
placeholder="<?= e(trans($field->placeholder)) ?>"
|
||||
<?= $field->getAttributes() ?>><?= e($field->value) ?></textarea>
|
||||
<?php endif?>
|
||||
49
modules/backend/widgets/form/partials/_field_url.php
Normal file
49
modules/backend/widgets/form/partials/_field_url.php
Normal file
@@ -0,0 +1,49 @@
|
||||
<!-- URL -->
|
||||
<?php
|
||||
$fieldOptions = $field->options();
|
||||
$hasOptions = is_array($fieldOptions) && count($fieldOptions);
|
||||
$listId = $hasOptions ? $field->getId() . '-list' : null;
|
||||
?>
|
||||
<div class="input-group static">
|
||||
<span class="input-group-addon">
|
||||
<i class="empty wn-icon-link"></i>
|
||||
</span>
|
||||
<?php if ($this->previewMode): ?>
|
||||
<?php if ($field->value): ?>
|
||||
<a
|
||||
href="<?= e($field->value) ?>"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="form-control"
|
||||
>
|
||||
<?= e($field->value) ?>
|
||||
</a>
|
||||
<?php else: ?>
|
||||
<span class="form-control"> </span>
|
||||
<?php endif ?>
|
||||
<?php else: ?>
|
||||
<input
|
||||
type="url"
|
||||
name="<?= $field->getName() ?>"
|
||||
id="<?= $field->getId() ?>"
|
||||
value="<?= e($field->value) ?>"
|
||||
class="form-control"
|
||||
<?= isset($field->autocomplete) && is_string($field->autocomplete) ? 'autocomplete="' . e($field->autocomplete) . '"' : '' ?>
|
||||
<?= isset($field->maxlength) && is_numeric($field->maxlength) ? 'maxlength="' . e($field->maxlength) . '"' : '' ?>
|
||||
<?= isset($field->minlength) && is_numeric($field->minlength) ? 'minlength="' . e($field->minlength) . '"' : '' ?>
|
||||
<?= isset($field->pattern) && is_string($field->pattern) ? 'pattern="' . e($field->pattern) . '"' : '' ?>
|
||||
<?= isset($field->placeholder) && is_string($field->placeholder) ? 'placeholder="' . e(trans($field->placeholder)) . '"' : '' ?>
|
||||
<?= isset($field->size) && is_numeric($field->size) ? 'size="' . e($field->size) . '"' : '' ?>
|
||||
<?= $field->getAttributes() ?>
|
||||
<?= $listId ? 'list="' . e($listId) . '"' : '' ?>
|
||||
/>
|
||||
<?php if ($hasOptions): ?>
|
||||
<datalist id="<?= e($listId) ?>">
|
||||
<?php foreach ($fieldOptions as $value => $label): ?>
|
||||
<?php $value = is_int($value) ? $label : $value ?>
|
||||
<option value="<?= e($value) ?>"<?= $value !== $label ? ' label="' . e(trans($label)) . '"' : '' ?>></option>
|
||||
<?php endforeach ?>
|
||||
</datalist>
|
||||
<?php endif ?>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
5
modules/backend/widgets/form/partials/_field_widget.php
Normal file
5
modules/backend/widgets/form/partials/_field_widget.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<!-- Widget -->
|
||||
<?php
|
||||
$widget = $this->makeFormFieldWidget($field);
|
||||
?>
|
||||
<?= $widget->render() ?>
|
||||
10
modules/backend/widgets/form/partials/_form-container.php
Normal file
10
modules/backend/widgets/form/partials/_form-container.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<div
|
||||
data-control="formwidget"
|
||||
data-refresh-handler="<?= $this->getEventHandler('onRefresh') ?>"
|
||||
class="form-widget form-elements layout"
|
||||
role="form"
|
||||
id="<?= $this->getId() ?>">
|
||||
|
||||
<?= $this->makePartial('form') ?>
|
||||
|
||||
</div>
|
||||
12
modules/backend/widgets/form/partials/_form.php
Normal file
12
modules/backend/widgets/form/partials/_form.php
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
<?php if ($outsideTabs->hasFields()): ?>
|
||||
<?= $this->makePartial('section', ['tabs' => $outsideTabs]) ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($primaryTabs->hasFields()): ?>
|
||||
<?= $this->makePartial('section', ['tabs' => $primaryTabs]) ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($secondaryTabs->hasFields()): ?>
|
||||
<?= $this->makePartial('section', ['tabs' => $secondaryTabs]) ?>
|
||||
<?php endif ?>
|
||||
3
modules/backend/widgets/form/partials/_form_fields.php
Normal file
3
modules/backend/widgets/form/partials/_form_fields.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php foreach ($fields as $field): ?>
|
||||
<?= $this->makePartial('field-container', ['field' => $field]) ?>
|
||||
<?php endforeach ?>
|
||||
62
modules/backend/widgets/form/partials/_form_tabs.php
Normal file
62
modules/backend/widgets/form/partials/_form_tabs.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
$type = $tabs->section;
|
||||
|
||||
$navCss = '';
|
||||
$contentCss = '';
|
||||
$paneCss = '';
|
||||
|
||||
if ($tabs->stretch) {
|
||||
$navCss = 'layout-row min-size';
|
||||
$contentCss = 'layout-row';
|
||||
$paneCss = 'layout-cell';
|
||||
}
|
||||
?>
|
||||
<div class="<?= $navCss ?>">
|
||||
<ul class="nav nav-tabs" <?= $tabs->linkable ? 'data-linkable' : '' ?>>
|
||||
<?php
|
||||
$index = 0;
|
||||
foreach ($tabs as $name => $fields):
|
||||
$lazy = in_array($name, $tabs->lazy);
|
||||
?>
|
||||
|
||||
<li class="<?= ($index++ === 0) ? 'active' : '' ?> <?= $lazy ? 'tab-lazy' : '' ?>">
|
||||
<a
|
||||
href="#<?= $type . 'tab-' . ($tabs->linkable ? str_slug($name) : $index) ?>"
|
||||
<?php if ($lazy): ?>
|
||||
data-tab-name="<?= e($name) ?>"
|
||||
data-tab-section="<?= $type ?>"
|
||||
data-tab-lazy-handler="<?= $this->getEventHandler('onLazyLoadTab') ?>"
|
||||
<?php endif ?>
|
||||
>
|
||||
<span class="title">
|
||||
<span>
|
||||
<?php if ($tabs->getIcon($name)): ?>
|
||||
<span class="<?= $tabs->getIcon($name) ?>"></span>
|
||||
<?php endif; ?>
|
||||
<?= e(trans($name)) ?>
|
||||
</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<?php endforeach ?>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="tab-content <?= $contentCss ?>">
|
||||
<?php
|
||||
$index = 0;
|
||||
foreach ($tabs as $name => $fields):
|
||||
$lazy = in_array($name, $tabs->lazy);
|
||||
?>
|
||||
|
||||
<div
|
||||
class="tab-pane <?= $lazy ? 'lazy' : '' ?> <?= e($tabs->getPaneCssClass($index, $name)) ?> <?= ($index++ === 0) ? 'active' : '' ?> <?= $paneCss ?>"
|
||||
id="<?= $type . 'tab-' . $index ?>">
|
||||
<?php if ($lazy): ?>
|
||||
<?= $this->makePartial('form_tabs_lazy', ['fields' => $fields]) ?>
|
||||
<?php else: ?>
|
||||
<?= $this->makePartial('form_fields', ['fields' => $fields]) ?>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
<?php endforeach ?>
|
||||
</div>
|
||||
37
modules/backend/widgets/form/partials/_form_tabs_lazy.php
Normal file
37
modules/backend/widgets/form/partials/_form_tabs_lazy.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<div class="loading-indicator-container m-t">
|
||||
<div class="loading-indicator indicator-center">
|
||||
<span></span>
|
||||
</div>
|
||||
</div>
|
||||
<?php
|
||||
// Do not create a hidden field for these field types since
|
||||
// they don't contain any form data.
|
||||
$ignoredTypes = ['section', 'partial'];
|
||||
|
||||
foreach ($fields as $field):
|
||||
if (in_array($field->type, $ignoredTypes)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$isMultiValue = is_array($field->value);
|
||||
foreach (array_wrap($field->value) as $index => $value):
|
||||
// Use array field names if the field has multiple values (repeater, checkboxlist, etc.).
|
||||
$fieldName = $isMultiValue ? sprintf('%s[%s]', $field->getName(), $index) : $field->getName();
|
||||
|
||||
$valueIsArray = is_array($value);
|
||||
foreach (array_wrap($value) as $index => $value):
|
||||
// Set the correct array keys if the value is an array (repeater form fields).
|
||||
$currentFieldName = $valueIsArray ? sprintf('%s[%s]', $fieldName, $index) : $fieldName;
|
||||
?>
|
||||
|
||||
<input
|
||||
type="hidden"
|
||||
name="<?= $currentFieldName ?>"
|
||||
id="<?= $this->nameToId($currentFieldName) ?>"
|
||||
value="<?= e($value) ?>"
|
||||
<?= $field->getAttributes() ?>
|
||||
/>
|
||||
|
||||
<?php endforeach ?>
|
||||
<?php endforeach ?>
|
||||
<?php endforeach ?>
|
||||
20
modules/backend/widgets/form/partials/_section-container.php
Normal file
20
modules/backend/widgets/form/partials/_section-container.php
Normal file
@@ -0,0 +1,20 @@
|
||||
<div
|
||||
data-control="formwidget"
|
||||
data-refresh-handler="<?= $this->getEventHandler('onRefresh') ?>"
|
||||
class="layout-row"
|
||||
role="form"
|
||||
id="<?= $this->getId($renderSection.'Container') ?>">
|
||||
|
||||
<?php if ($renderSection == 'outside'): ?>
|
||||
<?= $this->makePartial('section', ['tabs' => $outsideTabs]) ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($renderSection == 'primary'): ?>
|
||||
<?= $this->makePartial('section', ['tabs' => $primaryTabs]) ?>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if ($renderSection == 'secondary'): ?>
|
||||
<?= $this->makePartial('section', ['tabs' => $secondaryTabs]) ?>
|
||||
<?php endif ?>
|
||||
|
||||
</div>
|
||||
30
modules/backend/widgets/form/partials/_section.php
Normal file
30
modules/backend/widgets/form/partials/_section.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
$type = $tabs->section;
|
||||
|
||||
$containerCss = 'layout-row min-size';
|
||||
|
||||
if ($tabs->stretch) {
|
||||
$containerCss = 'layout-row';
|
||||
}
|
||||
?>
|
||||
<!-- <?= ucfirst($type) ?> Tabs -->
|
||||
<div class="<?= $containerCss ?>">
|
||||
<?php if ($tabs->suppressTabs): ?>
|
||||
|
||||
<div
|
||||
id="<?= $this->getId($type.'Tabs') ?>"
|
||||
class="form-tabless-fields <?= $tabs->cssClass ?>">
|
||||
<?= $this->makePartial('form_fields', ['fields' => $tabs]) ?>
|
||||
</div>
|
||||
|
||||
<?php else: ?>
|
||||
|
||||
<div
|
||||
id="<?= $this->getId($type.'Tabs') ?>"
|
||||
class="control-tabs <?= $type ?>-tabs layout <?= $tabs->cssClass ?>"
|
||||
data-control="tab">
|
||||
<?= $this->makePartial('form_tabs', ['tabs' => $tabs]) ?>
|
||||
</div>
|
||||
|
||||
<?php endif ?>
|
||||
</div>
|
||||
Reference in New Issue
Block a user