Passed
Push — master ( 3d3660...f6786e )
by Jean-Christophe
01:38
created

HtmlDropdown::__construct()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 23
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 19
nc 3
nop 4
dl 0
loc 23
rs 9.6333
c 0
b 0
f 0
1
<?php
2
namespace Ajax\semantic\html\modules;
3
4
use Ajax\semantic\html\base\HtmlSemDoubleElement;
5
use Ajax\semantic\html\content\HtmlDropdownItem;
6
use Ajax\semantic\html\elements\HtmlIcon;
7
use Ajax\common\html\html5\HtmlInput;
8
use Ajax\service\JArray;
9
use Ajax\semantic\html\base\constants\Direction;
10
use Ajax\semantic\html\base\traits\LabeledIconTrait;
11
use Ajax\JsUtils;
12
use Ajax\semantic\html\collections\form\traits\FieldTrait;
13
use Ajax\common\html\HtmlDoubleElement;
14
15
class HtmlDropdown extends HtmlSemDoubleElement {
16
	use FieldTrait,LabeledIconTrait {
17
		addIcon as addIconP;
18
	}
19
20
	protected $mClass = "menu";
21
22
	protected $mTagName = "div";
23
24
	protected $items = array();
25
26
	protected $_params = array(
27
		"action" => "nothing",
28
		"on" => "hover",
29
		"showOnFocus" => true
30
	);
31
32
	protected $input;
33
34
	protected $value;
35
36
	protected $_associative;
37
38
	protected $_multiple;
39
40
	public function __construct($identifier, $value = "", $items = array(), $associative = true) {
41
		parent::__construct($identifier, "div");
42
		$this->_template = include dirname(__FILE__) . '/../templates/tplDropdown.php';
43
		$this->setProperty("class", "ui dropdown");
44
		$this->_multiple = false;
45
		$content = [];
46
		if (isset($value)) {
47
			if ($value instanceof HtmlSemDoubleElement) {
48
				$text = $value;
49
			} else {
50
				$text = new HtmlSemDoubleElement("text-" . $this->identifier, "div");
51
				$text->setClass("text");
52
				$this->setValue($value);
53
			}
54
			$content = [
55
				"text" => $text
56
			];
57
		}
58
		$content["arrow"] = new HtmlIcon($identifier . "-icon", "dropdown");
59
		$this->content = $content;
60
		$this->tagName = "div";
61
		$this->_associative = $associative;
62
		$this->addItems($items);
63
	}
64
65
	public function getField() {
66
		return $this->input;
67
	}
68
69
	public function getDataField() {
70
		return $this->input;
71
	}
72
73
	public function addItem($item, $value = NULL, $image = NULL, $description = NULL) {
74
		$itemO = $this->beforeAddItem($item, $value, $image, $description);
75
		$this->items[] = $itemO;
76
		return $itemO;
77
	}
78
79
	public function addIcon($icon, $before = true, $labeled = false) {
80
		$this->removeArrow();
81
		$this->addIconP($icon, $before, $labeled);
82
		$elm = $this->getElementById("text-" . $this->identifier, $this->content);
83
		if (isset($elm)) {
84
			$elm->setWrapAfter("");
85
		}
86
		return $this;
87
	}
88
89
	public function addIcons($icons) {
90
		$count = $this->count();
91
		for ($i = 0; $i < \sizeof($icons) && $i < $count; $i ++) {
92
			$this->getItem($i)->addIcon($icons[$i]);
93
		}
94
	}
95
96
	/**
97
	 * Insert an item at a position
98
	 *
99
	 * @param mixed $item
100
	 * @param int $position
101
	 * @return HtmlDropdownItem
102
	 */
103
	public function insertItem($item, $position = 0) {
104
		$itemO = $this->beforeAddItem($item);
105
		$start = array_slice($this->items, 0, $position);
106
		$end = array_slice($this->items, $position);
107
		$start[] = $item;
108
		$this->items = array_merge($start, $end);
109
		return $itemO;
110
	}
111
112
	protected function removeArrow() {
113
		if (\sizeof($this->content) > 1) {
114
			unset($this->content["arrow"]);
115
			$this->content = \array_values($this->content);
116
		}
117
	}
118
119
	protected function beforeAddItem($item, $value = NULL, $image = NULL, $description = NULL) {
120
		$itemO = $item;
121
		if (\is_array($item)) {
122
			$description = JArray::getValue($item, "description", 3);
123
			$value = JArray::getValue($item, "value", 1);
124
			$image = JArray::getValue($item, "image", 2);
125
			$item = JArray::getValue($item, "item", 0);
126
		}
127
		if (! $item instanceof HtmlDropdownItem) {
128
			$itemO = new HtmlDropdownItem("dd-item-" . $this->identifier . "-" . \sizeof($this->items), $item, $value, $image, $description);
129
		} elseif ($itemO instanceof HtmlDropdownItem) {
130
			$this->addToProperty("class", "vertical");
131
		}
132
		return $itemO;
133
	}
134
135
	/*
136
	 * (non-PHPdoc)
137
	 * @see \Ajax\bootstrap\html\base\BaseHtml::fromDatabaseObject()
138
	 */
139
	public function fromDatabaseObject($object, $function) {
140
		$this->addItem($function($object));
141
	}
142
143
	public function addInput($name) {
144
		if (! isset($name))
145
			$name = "input-" . $this->identifier;
146
		$this->setAction("activate");
147
		$this->input = new HtmlInput($name, "hidden");
148
		$this->input->setIdentifier("input-" . $this->identifier);
149
		return $this->input;
150
	}
151
152
	/**
153
	 * Adds a search input item
154
	 *
155
	 * @param string $placeHolder
156
	 * @param string $icon
157
	 * @return HtmlDropdownItem
158
	 */
159
	public function addSearchInputItem($placeHolder = NULL, $icon = NULL) {
160
		return $this->addItem(HtmlDropdownItem::searchInput($placeHolder, $icon));
161
	}
162
163
	/**
164
	 * Adds a divider item
165
	 *
166
	 * @return HtmlDropdownItem
167
	 */
168
	public function addDividerItem() {
169
		return $this->addItem(HtmlDropdownItem::divider());
170
	}
171
172
	/**
173
	 * Adds an header item
174
	 *
175
	 * @param string $caption
176
	 * @param string $icon
177
	 * @return HtmlDropdownItem
178
	 */
179
	public function addHeaderItem($caption = NULL, $icon = NULL) {
180
		return $this->addItem(HtmlDropdownItem::header($caption, $icon));
181
	}
182
183
	/**
184
	 * Adds an item with a circular label
185
	 *
186
	 * @param string $caption
187
	 * @param string $color
188
	 * @return HtmlDropdownItem
189
	 */
190
	public function addCircularLabelItem($caption, $color) {
191
		return $this->addItem(HtmlDropdownItem::circular($caption, $color));
192
	}
193
194
	/**
195
	 *
196
	 * @param string $caption
197
	 * @param string $image
198
	 * @return \Ajax\semantic\html\content\HtmlDropdownItem
199
	 */
200
	public function addMiniAvatarImageItem($caption, $image) {
201
		return $this->addItem(HtmlDropdownItem::avatar($caption, $image));
202
	}
203
204
	public function addItems($items) {
205
		if (\is_array($items) && $this->_associative) {
206
			foreach ($items as $k => $v) {
207
				$this->addItem($v)->setData($k);
208
			}
209
		} else {
210
			foreach ($items as $item) {
211
				$this->addItem($item);
212
			}
213
		}
214
	}
215
216
	/**
217
	 * Sets the values of a property for each item in the collection
218
	 *
219
	 * @param string $property
220
	 * @param array|mixed $values
221
	 * @return $this
222
	 */
223
	public function setPropertyValues($property, $values) {
224
		$i = 0;
225
		if (\is_array($values) === false) {
226
			$values = \array_fill(0, $this->count(), $values);
227
		}
228
		foreach ($values as $value) {
229
			$c = $this->items[$i ++];
230
			if (isset($c)) {
231
				$c->setProperty($property, $value);
232
			} else {
233
				return $this;
234
			}
235
		}
236
		return $this;
237
	}
238
239
	public function each($callBack) {
240
		foreach ($this->items as $index => $value) {
241
			$callBack($index, $value);
242
		}
243
		return $this;
244
	}
245
246
	public function getItem($index) {
247
		return $this->items[$index];
248
	}
249
250
	/**
251
	 *
252
	 * @return int
253
	 */
254
	public function count() {
255
		return \sizeof($this->items);
256
	}
257
258
	/**
259
	 *
260
	 * @param boolean $dropdown
261
	 */
262
	public function asDropdown($dropdown) {
263
		if ($dropdown === false) {
264
			$this->_template = include dirname(__FILE__) . '/../templates/tplDropdownMenu.php';
265
			$dropdown = "menu";
266
		} else {
267
			$dropdown = "dropdown";
268
			$this->mClass = "menu";
269
		}
270
		return $this->addToPropertyCtrl("class", $dropdown, array(
271
			"menu",
272
			"dropdown"
273
		));
274
	}
275
276
	public function setVertical() {
277
		return $this->addToPropertyCtrl("class", "vertical", array(
278
			"vertical"
279
		));
280
	}
281
282
	public function setInline() {
283
		return $this->addToPropertyCtrl("class", "inline", [
284
			"inline"
285
		]);
286
	}
287
288
	public function setSimple() {
289
		return $this->addToPropertyCtrl("class", "simple", array(
290
			"simple"
291
		));
292
	}
293
294
	public function asButton($floating = false) {
295
		$this->removeArrow();
296
		if ($floating)
297
			$this->addToProperty("class", "floating");
298
		$this->removePropertyValue("class", "selection");
299
		return $this->addToProperty("class", "button");
300
	}
301
302
	public function asSelect($name = NULL, $multiple = false, $selection = true) {
303
		$this->_multiple = $multiple;
304
		if (isset($name))
305
			$this->addInput($name);
306
		if ($multiple) {
307
			$this->addToProperty("class", "multiple");
308
		}
309
		if ($selection) {
310
			if ($this->propertyContains("class", "button") === false)
311
				$this->addToPropertyCtrl("class", "selection", array(
312
					"selection"
313
				));
314
		}
315
		return $this;
316
	}
317
318
	public function asSearch($name = NULL, $multiple = false, $selection = true) {
319
		$this->asSelect($name, $multiple, $selection);
320
		return $this->addToProperty("class", "search");
321
	}
322
323
	public function setSelect($name = NULL, $multiple = false) {
324
		$this->_template = '<%tagName% id="%identifier%" %properties%>%items%</%tagName%>';
325
		if (! isset($name))
326
			$name = "select-" . $this->identifier;
327
		$this->input = null;
328
		if ($multiple) {
329
			$this->setProperty("multiple", true);
330
			$this->addToProperty("class", "multiple");
331
		}
332
		$this->setAction("activate");
333
		$this->tagName = "select";
334
		$this->setProperty("name", $name);
335
		$this->content = null;
336
		foreach ($this->items as $item) {
337
			$item->asOption();
338
		}
339
		return $this;
340
	}
341
342
	public function asSubmenu($pointing = NULL) {
343
		$this->setClass("ui dropdown link item");
344
		if (isset($pointing)) {
345
			$this->setPointing($pointing);
346
		}
347
		return $this;
348
	}
349
350
	public function setPointing($value = Direction::NONE) {
351
		return $this->addToPropertyCtrl("class", $value . " pointing", Direction::getConstantValues("pointing"));
352
	}
353
354
	public function setValue($value) {
355
		$this->value = $value;
356
		return $this;
357
	}
358
359
	public function setDefaultText($text) {
360
		$this->content["text"] = new HtmlSemDoubleElement("", "div", "default text", $text);
361
	}
362
363
	private function applyValue() {
364
		$value = $this->value;
365
		if (isset($this->input) && isset($value)) {
366
			$this->input->setProperty("value", $value);
367
		} else {
368
			$this->setProperty("value", $value);
369
		}
370
		$textElement = $this->getElementById("text-" . $this->identifier, $this->content);
371
		if (isset($textElement) && ($textElement instanceof HtmlDoubleElement) && ! $this->_multiple)
372
			$textElement->setContent($value);
373
		return $this;
374
	}
375
376
	/*
377
	 * (non-PHPdoc)
378
	 * @see BaseHtml::run()
379
	 */
380
	public function run(JsUtils $js) {
381
		if ($this->propertyContains("class", "simple") === false) {
382
			if (isset($this->_bsComponent) === false) {
383
				$this->_bsComponent = $js->semantic()->dropdown("#" . $this->identifier, $this->_params);
384
				$this->_bsComponent->setItemSelector(".item");
385
			}
386
			$this->addEventsOnRun($js);
387
			return $this->_bsComponent;
388
		}
389
	}
390
391
	public function setCompact() {
392
		return $this->addToPropertyCtrl("class", "compact", array(
393
			"compact"
394
		));
395
	}
396
397
	public function setAction($action) {
398
		$this->_params["action"] = $action;
399
	}
400
401
	public function setOn($on) {
402
		$this->_params["on"] = $on;
403
	}
404
405
	public function setShowOnFocus($value) {
406
		$this->_params["showOnFocus"] = $value;
407
	}
408
409
	public function setAllowAdditions($value) {
410
		$this->_params["allowAdditions"] = $value;
411
	}
412
413
	public function setFullTextSearch($value) {
414
		$this->_params["fullTextSearch"] = $value;
415
	}
416
417
	public function compile(JsUtils $js = NULL, &$view = NULL) {
418
		$this->applyValue();
419
		return parent::compile($js, $view);
420
	}
421
422
	public function getInput() {
423
		return $this->input;
424
	}
425
426
	public function setIcon($icon = "dropdown") {
427
		$this->content["arrow"] = new HtmlIcon($this->identifier . "-icon", $icon);
428
		return $this;
429
	}
430
431
	public function jsAddItem($caption, $value = null) {
432
		$value = $value ?? $caption;
433
		$js = "var first=$('#{$this->identifier} .item').first();if(first!=undefined){var newItem =first.clone();first.parent().append(newItem);newItem.html({$caption});newItem.attr('data-value',{$value}).removeClass('active filtered');}";
434
		return $js;
435
	}
436
437
	public function setClearable($value) {
438
		$this->_params["clearable"] = $value;
439
	}
440
441
	/**
442
	 * Is called after a dropdown selection is added using a multiple select dropdown, only receives the added value
443
	 * Parameters addedValue, addedText, $addedChoice
444
	 */
445
	public function setOnAdd($jsCode) {
446
		$this->_params["onAdd"] = $jsCode;
447
		return $this;
448
	}
449
450
	/**
451
	 * Is called after a dropdown selection is removed using a multiple select dropdown, only receives the removed value
452
	 * Parameters removedValue, removedText, $removedChoice
453
	 */
454
	public function setOnRemove($jsCode) {
455
		$this->_params["onRemove"] = $jsCode;
456
		return $this;
457
	}
458
}
459