/* global ajaxurl, WZTomSelectSettings, jQuery, TomSelect */ (function ($) { 'use strict'; function normalizeOption(item) { if (!item || typeof item !== 'object') { return null; } const value = item.id || item.value || ''; const text = item.name || item.text || value; if (!value && !text) { return null; } return { value: String(value), text: String(text) }; } function getEndpointOptions(settings, endpoint) { if (!settings || !endpoint) { return []; } const endpointOptions = settings[endpoint]; if (!Array.isArray(endpointOptions)) { return []; } return endpointOptions .map(normalizeOption) .filter(Boolean); } function isTaxonomyEndpoint(endpoint) { const key = typeof endpoint === 'string' ? endpoint : ''; return key === 'category' || key === 'post_tag' || key.includes('tax'); } function initTomSelect(root) { const scope = (root && typeof root.querySelectorAll === 'function') ? root : document; const elements = scope.querySelectorAll('.ts_autocomplete'); elements.forEach(function (element) { if (element.tomselect) { return; } const tagName = (element.tagName || '').toUpperCase(); if (tagName !== 'INPUT' && tagName !== 'SELECT' && tagName !== 'TEXTAREA') { return; } const prefix = element.getAttribute('data-wp-prefix') || 'WZ'; const settingsKey = `${prefix}TomSelectSettings`; const settings = window[settingsKey] || window.WZTomSelectSettings || window.freemkitTomSelectSettings || {}; if (!settings || typeof settings !== 'object') { return; } const action = element.getAttribute('data-wp-action') || settings.action; const nonce = element.getAttribute('data-wp-nonce') || settings.nonce; const endpoint = element.getAttribute('data-wp-endpoint') || settings.endpoint; const strings = settings.strings || {}; const formattedOptions = getEndpointOptions(settings, endpoint); let rawValue = ''; if (tagName === 'SELECT' && element.multiple && element.selectedOptions) { rawValue = Array.from(element.selectedOptions) .map(option => String(option.value || '').trim()) .filter(Boolean) .join(','); } else if (typeof element.value === 'string') { rawValue = element.value; } else { const valueAttribute = element.getAttribute('value'); rawValue = typeof valueAttribute === 'string' ? valueAttribute : ''; } const savedIds = rawValue.split(',').map(id => id.trim()).filter(Boolean); const taxonomyEndpoint = isTaxonomyEndpoint(endpoint); // For taxonomy endpoints, add saved values as options so Tom Select can display them if (taxonomyEndpoint && savedIds.length > 0) { const savedOptions = savedIds.map(savedValue => { // Extract term name from formatted string "Name (taxonomy:id)" const match = savedValue.match(/^(.*)\s+\(.*:\d+\)$/); const termName = match ? match[1] : savedValue; return { value: savedValue, text: termName }; }); // Merge saved options with existing options, avoiding duplicates const allOptions = [...formattedOptions]; savedOptions.forEach(savedOption => { if (!allOptions.some(opt => opt.value === savedOption.value)) { allOptions.push(savedOption); } }); // Replace formattedOptions with merged options formattedOptions.length = 0; formattedOptions.push(...allOptions); } // For non-taxonomy endpoints, add saved values as options so Tom Select can display them. if (!taxonomyEndpoint && savedIds.length > 0) { savedIds.forEach(savedValue => { if (!formattedOptions.some(opt => opt.value === savedValue)) { formattedOptions.push({ value: savedValue, text: savedValue }); } }); } // Get any custom config from data attributes let customConfig = {}; const configAttr = element.getAttribute('data-ts-config'); if (configAttr) { try { customConfig = JSON.parse(configAttr); } catch (e) { console.error('Error parsing custom config:', configAttr, e); } } // Default config const defaultConfig = { plugins: ['dropdown_input', 'clear_button', 'remove_button'], valueField: 'value', labelField: 'text', searchField: ['text', 'value'], options: formattedOptions, items: savedIds, persist: true, createOnBlur: false, create: false, render: { no_results: (data, escape) => { const template = strings.no_results || 'No results for "%s"'; return `