* @copyright Copyright (C) 2026 Moko Consulting. All rights reserved. * @license GNU General Public License version 3 or later; see LICENSE * * Text field with clickable placeholder pills that insert at cursor position. * Used for backup directory and archive name format fields. */ namespace Joomla\Component\MokoSuiteBackup\Administrator\Field; defined('_JEXEC') or die; use Joomla\CMS\Form\FormField; class PlaceholderTextField extends FormField { protected $type = 'PlaceholderText'; protected function getInput(): string { $value = htmlspecialchars($this->value ?? $this->default ?? '', ENT_QUOTES, 'UTF-8'); $id = htmlspecialchars($this->id, ENT_QUOTES, 'UTF-8'); $name = htmlspecialchars($this->name, ENT_QUOTES, 'UTF-8'); $hint = htmlspecialchars($this->element['hint'] ?? '', ENT_QUOTES, 'UTF-8'); $max = (int) ($this->element['maxlength'] ?? 512); $placeholderAttr = (string) ($this->element['placeholders'] ?? ''); $placeholders = array_filter(array_map('trim', explode(',', $placeholderAttr))); if (empty($placeholders)) { $placeholders = ['[host]', '[date]', '[datetime]', '[time]', '[year]', '[month]', '[day]', '[hour]', '[minute]', '[second]', '[profile_id]', '[profile_name]', '[site_name]', '[type]', '[random]']; } $html = ''; $html .= '
'; $html .= 'Insert:'; foreach ($placeholders as $ph) { $html .= ''; } $html .= '
'; $html .= << document.querySelectorAll('.moko-ph-insert[data-field="{$id}"]').forEach(function(btn) { btn.addEventListener('click', function(e) { e.preventDefault(); var target = document.getElementById(this.getAttribute('data-field')); var ph = this.getAttribute('data-ph'); if (!target) return; var start = target.selectionStart || 0; var end = target.selectionEnd || 0; var val = target.value; target.value = val.substring(0, start) + ph + val.substring(end); var newPos = start + ph.length; target.setSelectionRange(newPos, newPos); target.focus(); target.dispatchEvent(new Event('input', { bubbles: true })); }); }); JS; return $html; } }