1: <?php
2:
3: declare(strict_types=1);
4:
5: namespace Atk4\Ui;
6:
7: use Atk4\Ui\Js\Jquery;
8: use Atk4\Ui\Js\JsExpression;
9: use Atk4\Ui\Js\JsExpressionable;
10: use Atk4\Ui\Js\JsFunction;
11:
12: class Dropdown extends Lister
13: {
14: public $ui = 'dropdown';
15:
16: public $defaultTemplate = 'dropdown.html';
17:
18: /** @var JsCallback|null Callback when a new value is selected in Dropdown. */
19: public $cb;
20:
21: /** @var array As per Fomantic-UI dropdown options. */
22: public $dropdownOptions = [];
23:
24: #[\Override]
25: protected function init(): void
26: {
27: parent::init();
28:
29: if (!$this->cb) {
30: $this->cb = JsCallback::addTo($this);
31: }
32: }
33:
34: /**
35: * Handle callback when user select a new item value in dropdown.
36: * Callback is fire only when selecting a different item value then the current item value.
37: * ex:
38: * $dropdown = Dropdown::addTo($menu, ['menu', 'dropdownOptions' => ['on' => 'hover']]);
39: * $dropdown->setModel($menuItems);
40: * $dropdown->onChange(function (string $item) {
41: * return 'New selected item: ' . $item;
42: * });.
43: *
44: * @param \Closure(string): (JsExpressionable|View|string|void) $fx handler where new selected Item value is passed too
45: */
46: public function onChange(\Closure $fx): void
47: {
48: // setting dropdown option for using callback URL
49: $this->dropdownOptions['onChange'] = new JsFunction(['value', 'name', 't'], [
50: new JsExpression(
51: 'if ($(this).data(\'currentValue\') != value) { $(this).atkAjaxec({ url: [url], urlOptions: { item: value } }); $(this).data(\'currentValue\', value); }',
52: ['url' => $this->cb->getJsUrl()]
53: ),
54: ]);
55:
56: $this->cb->set(static function (Jquery $j, string $value) use ($fx) {
57: return $fx($value);
58: }, ['item' => 'value']);
59: }
60:
61: #[\Override]
62: protected function renderView(): void
63: {
64: $this->js(true)->dropdown($this->dropdownOptions);
65:
66: parent::renderView();
67: }
68: }
69: