Files
wordpress-theme-aksrt/assets/widgets/admin.js
T

158 lines
6.8 KiB
JavaScript

(function ($) {
'use strict';
const config = window.aksrtWidgetAdmin || {};
const core = window.AKSRTWidgetAdminCore;
function initForm(root) {
const $root = $(root);
$root.find('.aksrt-widget-color').wpColorPicker();
$root.find('.aksrt-widget-repeater__rows').sortable({
handle: '.dashicons-move',
axis: 'y',
update: renumberRepeaters,
});
$root.find('input[type="range"]').each(function () {
const output = this.parentElement.querySelector('output');
if (output) this.addEventListener('input', () => { output.textContent = this.value; });
});
evaluateDependencies($root);
updateWidgetTitle($root);
updatePlacementWarning($root);
}
function updateWidgetTitle(root) {
const $root = $(root);
const title = String($root.find('.aksrt-widget-field[data-field-id="title"] input').first().val() || '').trim();
if (!title) return;
$root.closest('.widget').find('.widget-title h3, .widget-title-action + h3').first().contents().filter(function () {
return this.nodeType === Node.TEXT_NODE;
}).first().replaceWith(`${title} `);
}
function updatePlacementWarning(root) {
const $widget = $(root).closest('.widget');
const $hint = $widget.find('.aksrt-widget-placement-hint').first();
if (!$hint.length) return;
const size = String($hint.data('widget-size') || 'any');
const area = String($widget.closest('.widgets-sortables').attr('id') || '');
const isSidebar = /sidebar/.test(area);
$hint.toggleClass('is-warning', (size === 'wide' && isSidebar) || (size === 'sidebar' && !isSidebar && area !== ''));
}
function loadForm(container) {
const $container = $(container);
if ($container.data('loading') || $container.data('loaded')) return;
$container.data('loading', true).find('.aksrt-widget-form-lazy__status').text(config.i18n?.loading || 'Loading…');
$.post(config.ajaxUrl, {
action: config.action,
nonce: config.nonce,
id_base: $container.data('id-base'),
widget_number: $container.data('widget-number'),
}).done((response) => {
if (!response?.success || !response.data?.html) throw new Error('Invalid response');
const $form = $(response.data.html);
$container.replaceWith($form);
initForm($form);
}).fail(() => {
$container.data('loading', false).find('.aksrt-widget-form-lazy__status').text(config.i18n?.error || 'Failed to load.');
});
}
function renumberRepeaters(_event, ui) {
const $form = $(ui?.item || this).closest('.aksrt-widget-form');
$form.find('.aksrt-widget-repeater__rows').each(function () {
$(this).children('.aksrt-widget-repeater__row').each(function (index) {
this.dataset.rowIndex = String(index);
});
});
$form.find('[name]').each(function () {
const rowIndexes = $(this).parents('.aksrt-widget-repeater__row').get().reverse().map((row) => Number(row.dataset.rowIndex || 0));
if (!rowIndexes.length) return;
this.name = core.replaceRepeaterIndexes(this.name, rowIndexes);
});
}
function fieldValue($form, id) {
const $field = $form.find(`.aksrt-widget-field[data-field-id="${CSS.escape(id)}"]`).first();
const $checked = $field.find('input:checked').first();
if ($checked.length) return String($checked.val());
return String($field.find('input,select,textarea').first().val() ?? '');
}
function evaluateDependencies($form) {
$form.find('[data-dependency]').each(function () {
const rule = core.parseDependency(this.dataset.dependency || '[]');
const $row = $(this).closest('.aksrt-widget-repeater__row');
const current = fieldValue($row.length ? $row : $form, String(rule[0]));
this.hidden = !core.dependencyVisible(rule, current);
});
}
$(document)
.on('click', '.aksrt-widget-form-lazy__load', function () { loadForm($(this).closest('.aksrt-widget-form-lazy')); })
.on('click', '.widget.open .aksrt-widget-form-lazy', function () { loadForm(this); })
.on('change input', '.aksrt-widget-form input, .aksrt-widget-form select, .aksrt-widget-form textarea', function () {
const $form = $(this).closest('.aksrt-widget-form');
evaluateDependencies($form);
updateWidgetTitle($form);
})
.on('click', '.aksrt-widget-repeater__add', function () {
const $repeater = $(this).closest('.aksrt-widget-repeater');
const max = Number($repeater.data('max-items') || 50);
const $rows = $repeater.children('.aksrt-widget-repeater__rows');
if ($rows.children().length >= max) return;
const index = $rows.children().length;
const token = String($repeater.data('index-token') || '__index__');
const html = $repeater.children('template').html().replaceAll(token, String(index));
const $row = $(html).appendTo($rows);
initForm($row);
renumberRepeaters.call($rows[0]);
})
.on('click', '.aksrt-widget-repeater__remove', function () {
const $rows = $(this).closest('.aksrt-widget-repeater__rows');
$(this).closest('.aksrt-widget-repeater__row').remove();
renumberRepeaters.call($rows[0]);
})
.on('click', '.aksrt-widget-upload__choose', function () {
const $wrap = $(this).closest('.aksrt-widget-upload');
const frame = wp.media({ title: '选择媒体', multiple: false });
frame.on('select', () => {
const attachment = frame.state().get('selection').first().toJSON();
$wrap.find('input[type="url"]').val(attachment.url).trigger('change');
let $image = $wrap.find('img');
if (!$image.length) $image = $('<img alt="">').prependTo($wrap);
$image.attr('src', attachment.url);
});
frame.open();
})
.on('click', '.aksrt-widget-upload__remove', function () {
const $wrap = $(this).closest('.aksrt-widget-upload');
$wrap.find('input[type="url"]').val('').trigger('change');
$wrap.find('img').remove();
})
.on('click', '.aksrt-widget-template-preview', function () {
const $form = $(this).closest('form');
const $output = $('.aksrt-widget-template-preview-output').first();
$output.prop('hidden', false).html('<p>正在生成预览…</p>');
$.post(config.ajaxUrl, {
action: 'aksrt_widgets_template_preview',
nonce: config.transferNonce,
template: $form.find('[name="template"]').val(),
}).done((response) => {
if (!response?.success) throw new Error('Invalid response');
$output.html(response.data.html || '<p>模板为空。</p>');
}).fail(() => $output.html('<p class="notice notice-error">预览加载失败。</p>'));
});
$(document).on('widget-added widget-updated', function (_event, widget) {
$(widget).find('.aksrt-widget-form-lazy').each(function () { loadForm(this); });
updatePlacementWarning(widget);
});
$(function () {
$('.aksrt-widget-form').each(function () { initForm(this); });
$('.widget.open .aksrt-widget-form-lazy').each(function () { loadForm(this); });
});
})(jQuery);