From a57597719c409465311ef5b14a72a565794db8be Mon Sep 17 00:00:00 2001 From: Antonio Ramirez Date: Wed, 29 May 2013 23:50:06 +0200 Subject: [PATCH] buttons refactored (2nd round) --- framework/yii/bootstrap/Button.php | 166 +++++++--------------------- framework/yii/bootstrap/ButtonDropdown.php | 168 +++++++++++++++++++++++++++++ framework/yii/bootstrap/ButtonGroup.php | 127 ++++++++++++++++++++++ 3 files changed, 333 insertions(+), 128 deletions(-) create mode 100644 framework/yii/bootstrap/ButtonDropdown.php create mode 100644 framework/yii/bootstrap/ButtonGroup.php diff --git a/framework/yii/bootstrap/Button.php b/framework/yii/bootstrap/Button.php index b340a4c..be605b9 100644 --- a/framework/yii/bootstrap/Button.php +++ b/framework/yii/bootstrap/Button.php @@ -12,148 +12,58 @@ use yii\helpers\Html; /** - * Button renders a group or split button dropdown bootstrap component. + * Button renders a bootstrap button. * * For example, * * ```php - * // a button group using Dropdown widget - * echo \yii\bootstrap\Button::widget(array( + * echo Button::widget(array( * 'label' => 'Action', - * 'items' => Dropdown::widget(array( - * 'clientOptions' => false, - * 'items' => array( - * array( - * 'label' => 'DropdownA', - * 'url' => '/', - * ), - * array( - * 'label' => 'DropdownB', - * 'url' => '#', - * ), - * ), - * )), - * )); - * - * // split button group using `items` dropdown configuration - * echo \yii\bootstrap\Button::widget(array( - * 'label' => 'Action', - * 'split' => true, - * 'items' => array( - * array( - * 'label' => 'DropdownA', - * 'url' => '/', - * ), - * array( - * 'label' => 'DropdownB', - * 'url' => '#', - * ), - * ), + * 'options' => array('class' => 'btn-large'), * )); * ``` * @see http://twitter.github.io/bootstrap/javascript.html#buttons - * @see http://twitter.github.io/bootstrap/components.html#buttonDropdowns * @author Antonio Ramirez * @since 2.0 */ class Button extends Widget { - /** - * @var string the button label - */ - public $label; - /** - * @var array the HTML attributes of the button. - */ - public $buttonOptions = array(); - /** - * @var array list of menu items in the dropdown. Each array element represents a single - * menu with the following structure: - * - * - label: string, required, the label of the item link - * - url: string, optional, the url of the item link. Defaults to "#". - * - linkOptions: array, optional, the HTML attributes of the item link. - * - options: array, optional, the HTML attributes of the item. - * - items: array, optional, the dropdown items configuration array. - * - * @see https://github.com/twitter/bootstrap/issues/5050#issuecomment-11741727 - * @see [[Dropdown]] - */ - public $items = array(); - /** - * @var boolean whether to display a group or split styled button group. - */ - public $split = false; - /** - * @var boolean whether the labels for dropdown items should be HTML-encoded. - */ - public $encodeLabels = true; - - - /** - * Initializes the widget. - * If you override this method, make sure you call the parent implementation first. - * @throws InvalidConfigException - */ - public function init() - { - if ($this->label === null) { - throw new InvalidConfigException("The 'label' option is required."); - } - parent::init(); - $this->addCssClass($this->options, 'btn-group'); - } + /** + * @var string the tag to use to render the button + */ + public $tagName = 'button'; + /** + * @var string the button label + */ + public $label; + /** + * @var boolean whether the label should be HTML-encoded. + */ + public $encodeLabel = true; - /** - * Renders the widget. - */ - public function run() - { - echo Html::beginTag('div', $this->options) . "\n"; - echo $this->renderLabel() . "\n"; - echo $this->renderItems() . "\n"; - echo Html::endTag('div') . "\n"; - $this->registerPlugin('button'); - } - /** - * Generates the button label. - * @return string the rendering result. - */ - protected function renderLabel() - { - $label = $this->encodeLabels ? Html::encode($this->label) : $this->label; - $this->addCssClass($this->buttonOptions, 'btn'); - $splitButton = ''; - if ($this->split) { - $tag = 'button'; - $options = $this->buttonOptions; - $this->buttonOptions['data-toggle'] = 'dropdown'; - $this->addCssClass($this->buttonOptions, 'dropdown-toggle'); - $splitButton = Html::tag('button', '', $this->buttonOptions); - } else { - $tag = 'a'; - $label .= ' '; - $options = $this->buttonOptions; - if (!isset($options['href'])) { - $options['href'] = '#'; - } - $this->addCssClass($options, 'dropdown-toggle'); - $options['data-toggle'] = 'dropdown'; - } - return Html::tag($tag, $label, $options) . "\n" . $splitButton; - } + /** + * Initializes the widget. + * If you override this method, make sure you call the parent implementation first. + * @throws InvalidConfigException + */ + public function init() + { + if ($this->label === null) { + throw new InvalidConfigException("The 'label' option is required."); + } + parent::init(); + $this->clientOptions = false; + $this->addCssClass($this->options, 'btn'); + $this->label = $this->encodeLabel ? Html::encode($this->label) : $this->label; + } - /** - * Generates the dropdown menu as specified on [[items]]. - * @return string the rendering result. - */ - protected function renderItems() - { - if (is_string($this->items)) { - return $this->items; - } - $config = array('items' => $this->items, 'clientOptions' => false); - return Dropdown::widget($config); - } + /** + * Renders the widget. + */ + public function run() + { + echo Html::tag($this->tagName, $this->label, $this->options) . "\n"; + $this->registerPlugin('button'); + } } \ No newline at end of file diff --git a/framework/yii/bootstrap/ButtonDropdown.php b/framework/yii/bootstrap/ButtonDropdown.php new file mode 100644 index 0000000..65d0398 --- /dev/null +++ b/framework/yii/bootstrap/ButtonDropdown.php @@ -0,0 +1,168 @@ + 'Action', + * 'items' => Dropdown::widget(array( + * 'clientOptions' => false, + * 'items' => array( + * array( + * 'label' => 'DropdownA', + * 'url' => '/', + * ), + * array( + * 'label' => 'DropdownB', + * 'url' => '#', + * ), + * ), + * )), + * )); + * + * // split button dropdown using `items` configuration + * echo ButtonDropdown::widget(array( + * 'label' => 'Action', + * 'split' => true, + * 'items' => array( + * array( + * 'label' => 'DropdownA', + * 'url' => '/', + * ), + * array( + * 'label' => 'DropdownB', + * 'url' => '#', + * ), + * ), + * )); + * ``` + * @see http://twitter.github.io/bootstrap/javascript.html#buttons + * @see http://twitter.github.io/bootstrap/components.html#buttonDropdowns + * @author Antonio Ramirez + * @since 2.0 + */ +class ButtonDropdown extends Widget +{ + /** + * @var string the button label + */ + public $label; + /** + * @var array the HTML attributes of the button. + */ + public $buttonOptions = array(); + /** + * @var array list of menu items in the dropdown. Each array element represents a single + * menu with the following structure: + * + * - label: string, required, the label of the item link + * - url: string, optional, the url of the item link. Defaults to "#". + * - linkOptions: array, optional, the HTML attributes of the item link. + * - options: array, optional, the HTML attributes of the item. + * - items: array, optional, the dropdown items configuration array. + * + * @see https://github.com/twitter/bootstrap/issues/5050#issuecomment-11741727 + * @see [[Dropdown]] + */ + public $items = array(); + /** + * @var boolean whether to display a group or split styled button group. + */ + public $split = false; + /** + * @var boolean whether the labels for dropdown items should be HTML-encoded. + */ + public $encodeLabels = true; + + + /** + * Initializes the widget. + * If you override this method, make sure you call the parent implementation first. + * @throws InvalidConfigException + */ + public function init() + { + if ($this->label === null) { + throw new InvalidConfigException("The 'label' option is required."); + } + parent::init(); + $this->addCssClass($this->options, 'btn-group'); + } + + /** + * Renders the widget. + */ + public function run() + { + echo Html::beginTag('div', $this->options) . "\n"; + echo $this->renderButton() . "\n"; + echo $this->renderItems() . "\n"; + echo Html::endTag('div') . "\n"; + $this->registerPlugin('button'); + } + + /** + * Generates the button dropdown. + * @return string the rendering result. + */ + protected function renderButton() + { + $this->addCssClass($this->buttonOptions, 'btn'); + $splitButton = ''; + if ($this->split) { + $tag = 'button'; + $options = $this->buttonOptions; + $this->buttonOptions['data-toggle'] = 'dropdown'; + $this->addCssClass($this->buttonOptions, 'dropdown-toggle'); + $splitButton = Button::widget(array( + 'label' => '', + 'encodeLabel' => false, + 'options' => $this->buttonOptions, + ) + ); + } else { + $tag = 'a'; + $this->label .= ' '; + $options = $this->buttonOptions; + if (!isset($options['href'])) { + $options['href'] = '#'; + } + $this->addCssClass($options, 'dropdown-toggle'); + $options['data-toggle'] = 'dropdown'; + } + return Button::widget(array( + 'tagName' => $tag, + 'label' => $this->label, + 'options' => $options, + 'encodeLabel' => false, + )) . "\n" . $splitButton; + } + + /** + * Generates the dropdown menu as specified on [[items]]. + * @return string the rendering result. + */ + protected function renderItems() + { + if (is_string($this->items)) { + return $this->items; + } + $config = array('items' => $this->items, 'clientOptions' => false); + return Dropdown::widget($config); + } +} \ No newline at end of file diff --git a/framework/yii/bootstrap/ButtonGroup.php b/framework/yii/bootstrap/ButtonGroup.php new file mode 100644 index 0000000..9b98cc8 --- /dev/null +++ b/framework/yii/bootstrap/ButtonGroup.php @@ -0,0 +1,127 @@ + array( + * array('label'=>'A'), + * array('label'=>'B'), + * ) + * )); + * + * // button group with an item as a string + * echo ButtonGroup::::widget(array( + * 'items' => array( + * Button::widget(array('label'=>'A')), + * array('label'=>'B'), + * ) + * )); + * + * // button group with body content as string + * ButtonGroup::beging(); + * Button::widget(array('label'=>'A')), // you can also use plain string + * ButtonGroup::end(); + * ``` + * @see http://twitter.github.io/bootstrap/javascript.html#buttons + * @see http://twitter.github.io/bootstrap/components.html#buttonGroups + * @author Antonio Ramirez + * @since 2.0 + */ +class ButtonGroup extends Widget +{ + /** + * @var array list of buttons. Each array element represents a single + * menu with the following structure: + * + * - label: string, required, the button label. + * - options: array, optional, the HTML attributes of the button. + */ + public $items = array(); + /** + * @var boolean whether the labels for dropdown items should be HTML-encoded. + */ + public $encodeLabels = true; + + + /** + * Initializes the widget. + * If you override this method, make sure you call the parent implementation first. + */ + public function init() + { + parent::init(); + $this->clientOptions = false; + $this->addCssClass($this->options, 'btn-group'); + echo $this->renderGroupBegin() . "\n"; + } + + /** + * Renders the widget. + */ + public function run() + { + echo "\n" . $this->renderGroupEnd(); + $this->registerPlugin('button'); + } + + /** + * Renders the opening tag of the button group. + * @return string the rendering result. + */ + protected function renderGroupBegin() + { + return Html::beginTag('div', $this->options); + } + + /** + * Renders the items and closing tag of the button group. + * @return string the rendering result. + */ + protected function renderGroupEnd() + { + return $this->renderItems() . "\n" . Html::endTag('div'); + } + + /** + * Generates the buttons that compound the group as specified on [[items]]. + * @return string the rendering result. + */ + protected function renderItems() + { + if (is_string($this->items)) { + return $this->items; + } + $buttons = array(); + foreach ($this->items as $item) { + if (is_string($item)) { + $buttons[] = $item; + continue; + } + $label = ArrayHelper::getValue($item, 'label'); + $options = ArrayHelper::getValue($item, 'options'); + $buttons[] = Button::widget(array( + 'label' => $label, + 'options' => $options, + 'encodeLabel' => $this->encodeLabels + ) + ); + } + return implode("\n", $buttons); + } +} \ No newline at end of file