(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; }); }); initRemoteSelects($root); evaluateDependencies($root); updateWidgetTitle($root); updatePlacementWarning($root); } function initRemoteSelects(root) { $(root).find('select.aksrt-widget-remote-select').each(function () { const $select = $(this); if ($select.data('remote-ready')) return; $select.data('remote-ready', true); const $picker = $('
'); const $selected = $(''); const $search = $('').attr('placeholder', String($select.data('placeholder') || '输入关键词以搜索')); const $results = $(''); $select.wrap($picker); $select.after($selected, $search, $results); const renderSelected = () => { $selected.empty(); $select.find('option:selected').each(function () { const $tag = $('').text($(this).text()).attr('aria-label', `移除 ${$(this).text()}`); $tag.on('click', () => { $(this).remove(); $select.trigger('change'); renderSelected(); }); $selected.append($tag); }); }; let timer = 0; $search.on('input', function () { window.clearTimeout(timer); const query = String(this.value || '').trim(); const minLength = Number($select.data('min-length') || 0); if (query.length < minLength) { $results.prop('hidden', true).empty(); return; } timer = window.setTimeout(() => { $results.prop('hidden', false).empty().append($('').text(config.i18n?.loading || '正在加载…')); $.post(config.ajaxUrl, { action: config.searchAction, nonce: config.nonce, source: $select.data('option-source'), queryArgs: $select.attr('data-query-args') || '{}', search: query, }).done((response) => { $results.empty(); const items = response?.success && Array.isArray(response.data?.results) ? response.data.results : []; if (!items.length) { $results.append($('').text('未找到匹配内容')); return; } items.forEach((item) => { const id = String(item.id || ''); const text = String(item.text || `#${id}`); const $button = $('').text(text); $button.on('click', () => { let $option = $select.find('option').filter(function () { return String(this.value) === id; }).first(); if (!$option.length) $option = $('').val(id).text(text).appendTo($select); $option.prop('selected', true); $select.trigger('change'); renderSelected(); $search.val('').trigger('focus'); $results.prop('hidden', true).empty(); }); $results.append($button); }); }).fail(() => $results.empty().append($('').text(config.i18n?.error || '加载失败,请重试。'))); }, 250); }); renderSelected(); }); } 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 scope = $row.length ? $row : $form; const ids = Array.isArray(rule[0]) ? rule[0].map((part) => part[0]) : String(rule[0] || '').split('|'); const current = {}; ids.forEach((id) => { current[id] = fieldValue(scope, id); }); 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: $wrap.data('media-library') === 'video' ? '选择视频' : '选择图片', library: $wrap.data('media-library') ? { type: $wrap.data('media-library') } : undefined, 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 = $('正在生成预览…
'); $.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 || '模板为空。
'); }).fail(() => $output.html('预览加载失败。
')); }); $(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);