<?php namespace PHPFUI\Input; class SelectAutoComplete extends \PHPFUI\Input\Select { use \PHPFUI\Traits\Page; protected string $acFieldId; protected \PHPFUI\Input\Text $acInput; protected string $arrayName = ''; protected array $autoCompleteOptions = [ 'minChars' => '1', 'type' => "'POST'", 'autoSelectFirst' => 'true', 'lookup' => 'arrayName', 'onSelect' => 'function(suggestion){ac.attr("placeholder",suggestion.value);ac.val("");fld.val(suggestion.data);fld.change()}', ]; protected \PHPFUI\Input\Hidden $hidden; protected string $realName; protected string | \PHPFUI\ToolTip $toolTip = ''; public function __construct(protected \PHPFUI\Page $page, string $name, string $label = '', protected bool $freeformInput = false) { $suffix = ''; $nameField = $name; if (\strstr($nameField, '[]')) { $suffix = '[]'; $nameField = \str_replace($suffix, '', $nameField); } $nameField .= 'Text'; parent::__construct($nameField, $label); $this->acInput = new \PHPFUI\Input\Text($nameField, $label); $this->realName = $name; $this->type = 'text'; $this->page->addTailScript('jquery.autocomplete.js'); $this->hidden = new \PHPFUI\Input\Hidden($this->realName); $this->hidden->getId(); } public function addAutoCompleteOption(string $option, mixed $value) : static { $this->autoCompleteOptions[$option] = $value; return $this; } public function getHiddenField() : \PHPFUI\Input\Hidden { return $this->hidden; } public function inReveal(bool $isInRevealModal = true) : self { return $this->addAutoCompleteOption('forceFixPosition', $isInRevealModal); } public function removeAutoCompleteOption(string $option) : static { unset($this->autoCompleteOptions[$option]); return $this; } public function setArray(string $name) : static { $this->arrayName = $name; return $this; } public function setToolTip(string | \PHPFUI\ToolTip $tip) : static { $this->toolTip = $tip; return $this; } protected function getBody() : string { return ''; } protected function getEnd() : string { $js = ''; if (! $this->arrayName) { $this->arrayName = "{$this->name}Array"; } else { $this->arrayName .= 'Array'; } $js = "var {$this->arrayName}=["; $comma = ''; foreach ($this->options as $option) { if (! $option['disabled']) { $js .= "{$comma}{data:'{$this->escapeData($option['value'])}',value:'{$this->escapeData($option['label'])}'}"; $comma = ','; } } $js .= '];'; $this->page->addJavaScript($js); $id = $this->getId(); $js = "{$id}('{$this->acFieldId}','{$this->hidden->getId()}',{$this->arrayName})"; $this->page->addJavaScript($js); return ''; } protected function getStart() : string { $dollar = '$'; $options = \PHPFUI\TextHelper::arrayToJS($this->autoCompleteOptions); $id = $this->getId(); $js = "function {$id}(acFieldId,hiddenFieldId,arrayName){var fld={$dollar}('#'+hiddenFieldId);var ac={$dollar}('#'+acFieldId);ac.devbridgeAutocomplete({$options});}"; $this->page->addJavaScript($js); $initValue = $initLabel = ''; foreach ($this->options as $option) { if ($option['selected']) { $initLabel = $option['label']; $initValue = $option['value']; $this->hidden->setValue($initValue); $this->acInput->setValue($initLabel); } } $this->setAttribute('placeholder', \str_replace("'", ''', $initLabel)); $this->setAttribute('autocomplete', 'off'); $this->hidden->setValue($initValue); $onChange = $this->getAttribute('onchange'); if ($onChange) { $this->deleteAttribute('onchange'); $this->hidden->addAttribute('onchange', $onChange); } $text = $this->upCastCopy($this->acInput, $this); $text->setToolTip($this->toolTip); if ($this->required) { $this->setAutoCompleteRequired($this->page, $text); } if ($this->freeformInput) { $this->page->addJavaScript('$("#' . $text->getId() . '").on("change", function(){$("#' . $this->hidden->getId() . '").val($(this).val()).change()})'); } $this->acFieldId = $text->getId(); return $text . $this->hidden; } private function escapeData(?string $data) : string { if (null === $data) { return ''; } $data = \str_replace('&', '&', $data); $data = \PHPFUI\TextHelper::unhtmlentities($data); $data = \str_replace("'", "\'", $data); return $data; } }