'; /** * @var string */ protected $template = '%s'; /** * @var array */ protected $button = [ 'text' => null, 'class' => 'btn btn-sm btn-white waves-effect', 'style' => null, ]; /** * @var string */ protected $buttonId; /** * @var \Closure */ protected $builder; /** * @var bool */ protected $divider; /** * @var bool */ protected $click = false; /** * @var array */ protected $firstOptions = []; public function __construct(array $options = []) { $this->options($options); } /** * Set the options of dropdown menus. * * @param array $options * @param string|null $title * * @return $this */ public function options($options = [], string $title = null) { if (! $options) { return $this; } if ($options instanceof Arrayable) { $options = $options->toArray(); } $options = (array) $options; if (! $this->options) { $this->firstOptions = &$options; } $this->options[] = [$title, &$options]; return $this; } /** * Set the button text. * * @param string|null $text * * @return $this */ public function button(?string $text) { $this->button['text'] = $text; return $this; } /** * Without text of button. * * @return $this */ public function withoutTextButton() { return $this->button(''); } /** * Set the button class. * * @param string $class * * @return $this */ public function buttonClass(string $class) { $this->button['class'] = $class; return $this; } /** * Set the button style. * * @param string $class * * @return $this */ public function buttonStyle(string $style) { $this->button['style'] = $style; return $this; } /** * Show divider. * * @param string $class * * @return $this */ public function divider() { $this->divider = true; return $this; } /** * Applies the callback to the elements of the options. * * @param string $class * * @return $this */ public function map(\Closure $builder) { $this->builder = $builder; return $this; } /** * Add click event listener. * * @param string|null $defaultLabel * * @return $this */ public function click(?string $defaultLabel = null) { $this->click = true; $this->buttonId = 'dropd_'.Str::random(8); if ($defaultLabel !== null) { $this->button($defaultLabel); } return $this; } /** * Set the template of dropdown menu. * * @param string|\Closure|Renderable $template * * @return $this */ public function template($template) { $this->template = $this->toString($template); return $this; } /** * @return string */ protected function renderButton() { if (is_null($this->button['text']) && ! $this->click) { return; } $text = $this->button['text']; $class = $this->button['class']; $style = $this->button['style']; if ($this->click && ! $text) { if (Arr::isAssoc($this->firstOptions)) { $text = array_keys($this->firstOptions)[0]; } else { $text = $this->firstOptions[0] ?? ''; } if (is_array($text)) { $text = $text['label'] ?? current($text); } } return str_replace( ['{id}', '{class}', '{style}', '{text}'], [ $this->buttonId, $class, $style ? "style='$style'" : '', $text ? " $text  " : '', ], <<<'HTML' {text} HTML ); } /** * @return string */ public function getButtonId() { return $this->buttonId; } /** * @return string */ protected function renderOptions() { $opt = ''; foreach ($this->options as &$items) { [$title, $options] = $items; if ($title) { $opt .= ""; } foreach ($options as $key => $val) { $opt .= $this->renderOption($key, $val); } } return $opt; } /** * @param mixed $k * @param mixed $v * * @return mixed|string */ protected function renderOption($k, $v) { if ($v === static::DIVIDER) { return static::$dividerHtml; } if ($builder = $this->builder) { $v = $builder->call($this, $v, $k); } $v = mb_strpos($v, '') ? $v : "$v"; $v = ""; if ($this->divider) { $v .= static::$dividerHtml; $this->divider = null; } return $v; } /** * @return string */ public function render() { if (is_null($this->button['text']) && ! $this->options) { return ''; } $button = $this->renderButton(); if (! $this->options) { return $button; } $opt = $this->renderOptions(); if (! $button) { return sprintf('', $opt); } $label = $this->button['text']; if ($this->click) { Admin::script( <<buttonId}'), _a = btn.parent().find('ul li a'), text = '$label'; _a.on('click', function () { btn.find('stub').html($(this).html() + '  '); }); if (text) { btn.find('stub').html(text + '  '); } else { (!_a.length) || btn.find('stub').html($(_a[0]).html() + '  '); } })(); JS ); } return sprintf( $this->template, $button, $opt ); } }