1 <?php
2
3 4 5 6 7 8 9 10
11
12 namespace Grido\Components\Filters;
13
14 15 16 17 18 19 20 21 22 23
24 class Text extends Filter
25 {
26
27 protected $condition = 'LIKE ?';
28
29
30 protected $formatValue = '%%value%';
31
32
33 protected $suggestion = FALSE;
34
35
36 protected $suggestionColumn;
37
38
39 protected $suggestionLimit = 10;
40
41
42 protected $suggestionCallback;
43
44 45 46 47 48
49 public function setSuggestion($column = NULL)
50 {
51 $this->suggestion = TRUE;
52 $this->suggestionColumn = $column;
53
54 $prototype = $this->getControl()->getControlPrototype();
55 $prototype->attrs['autocomplete'] = 'off';
56 $prototype->class[] = 'suggest';
57
58 $filter = $this;
59 $this->grid->onRender[] = function() use ($prototype, $filter) {
60 $replacement = '-query-';
61 $prototype->data['grido-suggest-replacement'] = $replacement;
62 $prototype->data['grido-suggest-limit'] = $filter->suggestionLimit;
63 $prototype->data['grido-suggest-handler'] = $filter->link('suggest!', array(
64 'query' => $replacement
65 ));
66 };
67
68 return $this;
69 }
70
71 72 73 74 75
76 public function setSuggestionLimit($limit)
77 {
78 $this->suggestionLimit = (int) $limit;
79 return $this;
80 }
81
82 83 84 85 86
87 public function setSuggestionCallback($callback)
88 {
89 $this->suggestionCallback = $callback;
90 return $this;
91 }
92
93
94
95 96 97
98 public function getSuggestionLimit()
99 {
100 return $this->suggestionLimit;
101 }
102
103 104 105
106 public function getSuggestionCallback()
107 {
108 return $this->suggestionCallback;
109 }
110
111 112 113
114 public function getSuggestionColumn()
115 {
116 return $this->suggestionColumn;
117 }
118
119 120 121 122 123
124 public function handleSuggest($query)
125 {
126 $this->grid->onRegistered && $this->grid->onRegistered($this->grid);
127 $name = $this->getName();
128
129 if (!$this->getPresenter()->isAjax() || !$this->suggestion || $query == '') {
130 $this->getPresenter()->terminate();
131 }
132
133 $actualFilter = $this->grid->getActualFilter();
134 if (isset($actualFilter[$name])) {
135 unset($actualFilter[$name]);
136 }
137
138 $conditions = $this->grid->__getConditions($actualFilter);
139
140 if ($this->suggestionCallback === NULL) {
141 $conditions[] = $this->__getCondition($query);
142
143 $column = $this->suggestionColumn ? $this->suggestionColumn : current($this->getColumn());
144 $items = $this->grid->model->suggest($column, $conditions, $this->suggestionLimit);
145
146 } else {
147 $items = callback($this->suggestionCallback)->invokeArgs(array($query, $actualFilter, $conditions, $this));
148 if (!is_array($items)) {
149 throw new \Exception('Items must be an array.');
150 }
151 }
152
153
154 $startsWith = $caseSensitive = $caseInsensitive = array();
155 foreach ($items as $item) {
156 if (stripos($item, $query) === 0) {
157 $startsWith[] = $item;
158 } elseif (strpos($item, $query) !== FALSE) {
159 $caseSensitive[] = $item;
160 } else {
161 $caseInsensitive[] = $item;
162 }
163 }
164
165 sort($startsWith);
166 sort($caseSensitive);
167 sort($caseInsensitive);
168
169 $items = array_merge($startsWith, $caseSensitive, $caseInsensitive);
170 $this->getPresenter()->sendResponse(new \Nette\Application\Responses\JsonResponse($items));
171 }
172
173 174 175
176 protected function getFormControl()
177 {
178 $control = new \Nette\Forms\Controls\TextInput($this->label);
179 $control->getControlPrototype()->class[] = 'text';
180
181 return $control;
182 }
183 }
184