1: <?php
2:
3: namespace Zippy\Html\Form;
4:
5: use Zippy\WebApplication;
6: use Zippy\Interfaces\Requestable;
7: use Zippy\Event;
8: use Zippy\Interfaces\EventReceiver;
9:
10: /**
11: * Компонент тэга &lt;input type=&quot;text&quot;&gt; с автозавершением
12: */
13: class AutocompleteTextInput extends TextInput implements Requestable
14: {
15: public $minChars = 2;
16: public $timeout = 100;
17: private $key = 0;
18: private $event2 = null;
19: private $event = null;
20: public $count = 12;
21: public $matcher = "return true;";
22:
23: /**
24: * Конструктор
25: * @param Zippy ID
26: * @param Минимальное количество символов
27: * @param Таймаут в мс.
28: */
29: public function __construct($id, $minChars = 2, $timeout = 100, $bgupdate = false) {
30: parent::__construct($id);
31: $this->minChars = $minChars;
32: $this->timeout = $timeout;
33: $this->bgupdate = $bgupdate;
34:
35: }
36:
37: protected function onAdded() {
38: if ($this->bgupdate) {
39: $page = $this->getPageOwner();
40: $this->onChange($page, 'OnBackgroundUpdate', true);
41: }
42: }
43:
44: public function RenderImpl() {
45: TextInput::RenderImpl();
46:
47: $onchange = "null";
48:
49: if ($this->event2 != null) {
50: $formid = $this->getFormOwner()->id;
51:
52: if ($this->event2->isajax == false) {
53:
54: $url = $this->owner->getURLNode() . '::' . $this->id;
55: $url = substr($url, 2 + strpos($url, 'q='));
56: $onchange = " { $('#" . $formid . "_q').attr('value','" . $url . "');$('#" . $formid . "_s').trigger('click');}";
57: } else {
58: $url = $this->owner->getURLNode() . "::" . $this->id;
59: $url = substr($url, 2 + strpos($url, 'q='));
60: $_BASEURL = WebApplication::$app->getResponse()->getHostUrl();
61: $onchange = " { var old=$('#" . $formid . "_q').attr('value') ; $('#" . $formid . "_q').attr('value','" . $url . "'); submitForm('{$formid}','{$_BASEURL}/?ajax=true');$('#" . $formid . "_q').attr('value',old); }";
62:
63: }
64: }
65: $url = $this->owner->getURLNode() . "::" . $this->id . "&ajax=true";
66:
67: if (strlen($this->matcher) > 0) {
68: $matcher = "matcher:function(item) {
69: {$this->matcher}
70: }, ";
71: }
72: $js = "
73: $('#{$this->id}').typeahead(
74: {
75: minLength:{$this->minChars},
76: items:{$this->count},
77: source: function (query, process) {
78:
79: return $.getJSON('{$url}&text=' + query, function (data) {
80: return process(data);
81: });
82: },
83: {$matcher}
84: highlighter: function(item) {
85: var parts = item.split('_');
86: parts.shift();
87: return parts.join('_');
88: },
89: updater: function(item) {
90: var parts = item.split('_'); ;
91: var userId = parts.shift();
92: $('#{$this->id}_id').val( userId);
93:
94: return parts.join('_');
95: } ,
96: afterSelect :function(item) {
97: ; {$onchange}
98: }
99: });
100: $('#{$this->id}').after('<input type=\"hidden\" id=\"{$this->id}_id\" name=\"{$this->id}_id\" value=\"{$this->key}\"/>');
101:
102: ";
103: // $this->setAttribute("data-key", $this->key);
104: $this->setAttribute("autocomplete", 'off');
105:
106:
107: WebApplication::$app->getResponse()->addJavaScript($js, true);
108: }
109:
110: /**
111: * @see Requestable
112: */
113: public function RequestHandle() {
114:
115: if ($_SERVER['REQUEST_METHOD'] == 'POST') {
116: $this->OnEvent2();
117: return;
118: }
119:
120: $posts = array();
121:
122: $this->setValue($_REQUEST['text']);
123: $arr = $this->OnAutocomplete();
124: if (is_array($arr)) {
125: foreach ($arr as $key => $value) {
126: //$posts[] = array("id"=>$key, "value"=> $value);
127: $posts[] = $key . "_" . $value;
128: }
129: }
130:
131:
132: WebApplication::$app->getResponse()->addAjaxResponse(json_encode($posts));
133: }
134:
135: /**
136: * Событие при автозавершении.
137: * Вызывает обработчик который должен вернуть массив строк для выпадающего списка.
138: */
139: public function OnAutocomplete() {
140: if ($this->event != null) {
141: return $this->event->onEvent($this);
142: }
143: return null;
144: }
145:
146: /**
147: * Устанавливает событие
148: * @param Event
149: */
150: public function onText(EventReceiver $receiver, $handler) {
151:
152: $this->event = new Event($receiver, $handler);
153: }
154:
155: /**
156: * @see SubmitDataRequest
157: */
158: public function getRequestData() {
159: if(!isset($_REQUEST[$this->id])) {
160: return;
161: }
162:
163: $this->setValue($_REQUEST[$this->id]);
164: $this->key = $_REQUEST[$this->id . "_id"];
165:
166: if (strlen(trim($this->getValue())) == 0) {
167: $this->key = 0;
168: }
169: }
170:
171: //возвращает ключ для выбранного значения
172: public function getKey() {
173: return $this->key;
174: }
175:
176: //
177: public function setKey($key) {
178: $this->key = $key;
179: }
180:
181: /**
182: * @see ChangeListener
183: */
184: public function onChange(EventReceiver $receiver, $handler, $ajax = false) {
185: $this->event2 = new Event($receiver, $handler);
186: $this->event2->isajax = $ajax;
187: }
188:
189: /**
190: * @see ChangeListener
191: */
192: public function OnEvent2() {
193: if ($this->event2 != null) {
194: $this->event2->onEvent($this);
195: }
196: }
197:
198: public function clean() {
199: $this->setKey(0);
200: $this->setText('');
201: }
202: }
203: