Initial commit
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,158 @@
|
||||
/**
|
||||
* FluentCRM — public form field initializers.
|
||||
*
|
||||
* Source file. The build copies resources/libs -> assets/libs (viteStaticCopy),
|
||||
* so this ships as assets/libs/fluentcrm/form-fields.js and is enqueued by
|
||||
* FormElementBuilder via wp_enqueue_script — no hardcoded inline <script>, so
|
||||
* the subscription/preference forms don't require `script-src 'unsafe-inline'`.
|
||||
*
|
||||
* Initializes flatpickr date/datetime pickers, Choices multi-selects, legacy
|
||||
* combodate inputs and native day/month/year dropdowns. Driven entirely by
|
||||
* CSS classes/structure (no per-field config inlined). Translatable strings
|
||||
* arrive via wp_localize_script as window.fluentcrmFormFields.i18n.
|
||||
*
|
||||
* Each initializer is idempotent and degrades gracefully if its library is
|
||||
* absent. Deferred to DOMContentLoaded so it is independent of script order.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
var i18n = (window.fluentcrmFormFields && window.fluentcrmFormFields.i18n) || {};
|
||||
|
||||
function initDatePickers() {
|
||||
if (typeof window.flatpickr === 'undefined') {
|
||||
return;
|
||||
}
|
||||
document.querySelectorAll('.fc-js-date-picker').forEach(function (picker) {
|
||||
if (picker.dataset.fpInitialized) {
|
||||
return;
|
||||
}
|
||||
window.flatpickr(picker, { dateFormat: 'Y-m-d', allowInput: true });
|
||||
picker.dataset.fpInitialized = '1';
|
||||
});
|
||||
document.querySelectorAll('.fc-js-datetime-picker').forEach(function (picker) {
|
||||
if (picker.dataset.fpInitialized) {
|
||||
return;
|
||||
}
|
||||
window.flatpickr(picker, {
|
||||
enableTime: true,
|
||||
dateFormat: 'Y-m-d H:i:S',
|
||||
time_24hr: true,
|
||||
allowInput: true
|
||||
});
|
||||
picker.dataset.fpInitialized = '1';
|
||||
});
|
||||
}
|
||||
|
||||
function initMultiSelects() {
|
||||
if (typeof window.Choices === 'undefined') {
|
||||
return;
|
||||
}
|
||||
document.querySelectorAll('.fc-js-choice-multi').forEach(function (select) {
|
||||
if (select.dataset.choicesInitialized) {
|
||||
return;
|
||||
}
|
||||
new window.Choices(select, {
|
||||
removeItemButton: true,
|
||||
placeholderValue: select.dataset.placeholder || i18n.selectOptions || 'Select options',
|
||||
searchEnabled: true,
|
||||
itemSelectText: '',
|
||||
noResultsText: i18n.noResults || 'No matching options found',
|
||||
noChoicesText: i18n.noChoices || 'No options available'
|
||||
});
|
||||
select.dataset.choicesInitialized = '1';
|
||||
});
|
||||
}
|
||||
|
||||
function initComboDates() {
|
||||
var $ = window.jQuery;
|
||||
if (!$ || !$.fn || !$.fn.combodate) {
|
||||
return;
|
||||
}
|
||||
$('.fc-js-combodate').each(function () {
|
||||
if (this.dataset.combodateInitialized) {
|
||||
return;
|
||||
}
|
||||
$(this).combodate();
|
||||
this.dataset.combodateInitialized = '1';
|
||||
});
|
||||
}
|
||||
|
||||
function initDateDropdowns() {
|
||||
document.querySelectorAll('.fc_date_dropdowns').forEach(function (wrap) {
|
||||
if (wrap.dataset.ddInitialized) {
|
||||
return;
|
||||
}
|
||||
var hidden = wrap.querySelector('input[type="hidden"]');
|
||||
var daySelect = wrap.querySelector('[data-role="day"]');
|
||||
var monthSelect = wrap.querySelector('[data-role="month"]');
|
||||
var yearSelect = wrap.querySelector('[data-role="year"]');
|
||||
if (!hidden || !daySelect || !monthSelect || !yearSelect) {
|
||||
return;
|
||||
}
|
||||
function daysInMonth(month, year) {
|
||||
if (!month || !year) {
|
||||
return 31;
|
||||
}
|
||||
return new Date(parseInt(year, 10), parseInt(month, 10), 0).getDate();
|
||||
}
|
||||
function updateDayOptions() {
|
||||
var maxDay = daysInMonth(monthSelect.value, yearSelect.value);
|
||||
var currentDay = parseInt(daySelect.value, 10) || 0;
|
||||
var options = daySelect.querySelectorAll('option');
|
||||
for (var i = 1; i < options.length; i++) {
|
||||
var val = parseInt(options[i].value, 10);
|
||||
options[i].disabled = val > maxDay;
|
||||
if (val > maxDay && currentDay === val) {
|
||||
currentDay = maxDay;
|
||||
}
|
||||
}
|
||||
if (currentDay > maxDay) {
|
||||
daySelect.value = String(maxDay);
|
||||
}
|
||||
}
|
||||
function sync() {
|
||||
var d = parseInt(daySelect.value, 10);
|
||||
var m = parseInt(monthSelect.value, 10);
|
||||
var y = parseInt(yearSelect.value, 10);
|
||||
if (d && m && y) {
|
||||
var maxDay = daysInMonth(m, y);
|
||||
if (d > maxDay) {
|
||||
d = maxDay;
|
||||
}
|
||||
hidden.value = y + '-' + (m < 10 ? '0' + m : m) + '-' + (d < 10 ? '0' + d : d);
|
||||
} else {
|
||||
hidden.value = '';
|
||||
}
|
||||
}
|
||||
monthSelect.addEventListener('change', function () { updateDayOptions(); sync(); });
|
||||
yearSelect.addEventListener('change', function () { updateDayOptions(); sync(); });
|
||||
daySelect.addEventListener('change', sync);
|
||||
updateDayOptions();
|
||||
sync();
|
||||
wrap.dataset.ddInitialized = '1';
|
||||
});
|
||||
}
|
||||
|
||||
function initAll() {
|
||||
// Isolate each initializer: a throw in one (e.g. legacy combodate when
|
||||
// moment.js isn't loaded) must not stop the others from running. The old
|
||||
// code emitted these as separate inline <script> blocks, which had this
|
||||
// isolation for free; consolidating into one IIFE removed it.
|
||||
[initDatePickers, initMultiSelects, initComboDates, initDateDropdowns].forEach(function (init) {
|
||||
try {
|
||||
init();
|
||||
} catch (e) {
|
||||
if (window.console && console.error) {
|
||||
console.error('[fluentcrm] form field init failed:', e);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initAll);
|
||||
} else {
|
||||
initAll();
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,2 @@
|
||||
<?php
|
||||
// Silence is golden.
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* multiple-select - Multiple select is a jQuery plugin to select multiple elements with checkboxes :).
|
||||
*
|
||||
* @version v1.5.2
|
||||
* @homepage http://multiple-select.wenzhixin.net.cn
|
||||
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],t):t((e=e||self).jQuery)}(this,(function(e){"use strict";(e=e&&e.hasOwnProperty("default")?e.default:e).fn.multipleSelect.locales["en-US"]={formatSelectAll:function(){return"[Select all]"},formatAllSelected:function(){return"All selected"},formatCountSelected:function(e,t){return e+" of "+t+" selected"},formatNoMatchesFound:function(){return"No matches found"}},e.extend(e.fn.multipleSelect.defaults,e.fn.multipleSelect.locales["en-US"])}));
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* multiple-select - Multiple select is a jQuery plugin to select multiple elements with checkboxes :).
|
||||
*
|
||||
* @version v1.5.2
|
||||
* @homepage http://multiple-select.wenzhixin.net.cn
|
||||
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
@charset "UTF-8";.ms-offscreen{clip:rect(0 0 0 0)!important;width:1px!important;height:1px!important;border:0!important;margin:0!important;padding:0!important;overflow:hidden!important;position:absolute!important;outline:0!important;left:auto!important;top:auto!important}.ms-parent{display:inline-block;position:relative;vertical-align:middle}.ms-choice{display:block;width:100%;height:26px;padding:0;overflow:hidden;cursor:pointer;border:1px solid #aaa;text-align:left;white-space:nowrap;line-height:26px;color:#444;text-decoration:none;border-radius:4px;background-color:#fff}.ms-choice.disabled{background-color:#f4f4f4;background-image:none;border:1px solid #ddd;cursor:default}.ms-choice>span{position:absolute;top:0;left:0;right:20px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block;padding-left:8px}.ms-choice>span.placeholder{color:#999}.ms-choice>div.icon-close{position:absolute;top:0;right:16px;height:100%;width:16px}.ms-choice>div.icon-close:before{content:'×';color:#888;font-weight:bold;position:absolute;top:50%;margin-top:-14px}.ms-choice>div.icon-close:hover:before{color:#333}.ms-choice>div.icon-caret{position:absolute;width:0;height:0;top:50%;right:8px;margin-top:-2px;border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px}.ms-choice>div.icon-caret.open{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.ms-drop{width:auto;min-width:100%;overflow:hidden;display:none;margin-top:-1px;padding:0;position:absolute;z-index:1000;background:#fff;color:#000;border:1px solid #aaa;border-radius:4px}.ms-drop.bottom{top:100%;box-shadow:0 4px 5px rgba(0,0,0,0.15)}.ms-drop.top{bottom:100%;box-shadow:0 -4px 5px rgba(0,0,0,0.15)}.ms-search{display:inline-block;margin:0;min-height:26px;padding:2px;position:relative;white-space:nowrap;width:100%;z-index:10000;box-sizing:border-box}.ms-search input{width:100%;height:auto!important;min-height:24px;padding:0 5px;margin:0;outline:0;font-family:sans-serif;border:1px solid #aaa;border-radius:5px;box-shadow:none}.ms-drop ul{overflow:auto;margin:0;padding:0}.ms-drop ul>li{list-style:none;display:list-item;background-image:none;position:static;padding:.25rem 8px}.ms-drop ul>li .disabled{font-weight:normal!important;opacity:.35;filter:Alpha(Opacity=35);cursor:default}.ms-drop ul>li.multiple{display:block;float:left}.ms-drop ul>li.group{clear:both}.ms-drop ul>li.multiple label{width:100%;display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ms-drop ul>li label{position:relative;padding-left:1.25rem;margin-bottom:0;font-weight:normal;display:block;white-space:nowrap;cursor:pointer}.ms-drop ul>li label.optgroup{font-weight:bold}.ms-drop ul>li.hide-radio{padding:0}.ms-drop ul>li.hide-radio:focus,.ms-drop ul>li.hide-radio:hover{background-color:#f8f9fa}.ms-drop ul>li.hide-radio.selected{color:#fff;background-color:#007bff}.ms-drop ul>li.hide-radio label{margin-bottom:0;padding:5px 8px}.ms-drop ul>li.hide-radio input{display:none}.ms-drop ul>li.option-level-1 label{padding-left:28px}.ms-drop input[type="radio"],.ms-drop input[type="checkbox"]{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.ms-drop .ms-no-results{display:none}
|
||||
+10
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user