Tabs.php 5.61 KB
Newer Older
1 2 3 4 5 6 7 8 9 10
<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace yii\jui;

use yii\base\InvalidConfigException;
11
use yii\helpers\ArrayHelper;
12
use yii\helpers\Url;
13 14 15
use yii\helpers\Html;

/**
Alexander Kochetov committed
16
 * Tabs renders a tabs jQuery UI widget.
17 18 19 20
 *
 * For example:
 *
 * ```php
Alexander Makarov committed
21 22 23
 * echo Tabs::widget([
 *     'items' => [
 *         [
24
 *             'label' => 'Tab one',
25
 *             'content' => 'Mauris mauris ante, blandit et, ultrices a, suscipit eget...',
Alexander Makarov committed
26 27
 *         ],
 *         [
28
 *             'label' => 'Tab two',
Alexander Kochetov committed
29
 *             'content' => 'Sed non urna. Phasellus eu ligula. Vestibulum sit amet purus...',
Alexander Makarov committed
30 31 32 33
 *             'options' => ['tag' => 'div'],
 *             'headerOptions' => ['class' => 'my-class'],
 *         ],
 *         [
34 35
 *             'label' => 'Tab with custom id',
 *             'content' => 'Morbi tincidunt, dui sit amet facilisis feugiat...',
Alexander Makarov committed
36 37 38
 *             'options' => ['id' => 'my-tab'],
 *         ],
 *         [
39
 *             'label' => 'Ajax tab',
Alexander Makarov committed
40 41
 *             'url' => ['ajax/content'],
 *         ],
42
 *     ],
Alexander Makarov committed
43 44 45 46 47
 *     'options' => ['tag' => 'div'],
 *     'itemOptions' => ['tag' => 'div'],
 *     'headerOptions' => ['class' => 'my-class'],
 *     'clientOptions' => ['collapsible' => false],
 * ]);
48 49 50 51 52 53 54 55
 * ```
 *
 * @see http://api.jqueryui.com/tabs/
 * @author Alexander Kochetov <creocoder@gmail.com>
 * @since 2.0
 */
class Tabs extends Widget
{
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
    /**
     * @var array the HTML attributes for the widget container tag. The following special options are recognized:
     *
     * - tag: string, defaults to "div", the tag name of the container tag of this widget.
     *
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $options = [];
    /**
     * @var array list of tab items. Each item can be an array of the following structure:
     *
     * - label: string, required, specifies the header link label. When [[encodeLabels]] is true, the label
     *   will be HTML-encoded.
     * - content: string, the content to show when corresponding tab is clicked. Can be omitted if url is specified.
     * - url: mixed, mixed, optional, the url to load tab contents via AJAX. It is required if no content is specified.
     * - template: string, optional, the header link template to render the header link. If none specified
72
     *   [[linkTemplate]] will be used instead.
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
     * - options: array, optional, the HTML attributes of the header.
     * - headerOptions: array, optional, the HTML attributes for the header container tag.
     */
    public $items = [];
    /**
     * @var array list of HTML attributes for the item container tags. This will be overwritten
     * by the "options" set in individual [[items]]. The following special options are recognized:
     *
     * - tag: string, defaults to "div", the tag name of the item container tags.
     *
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $itemOptions = [];
    /**
     * @var array list of HTML attributes for the header container tags. This will be overwritten
     * by the "headerOptions" set in individual [[items]].
     * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
     */
    public $headerOptions = [];
    /**
     * @var string the default header template to render the link.
     */
    public $linkTemplate = '<a href="{url}">{label}</a>';
    /**
     * @var boolean whether the labels for header items should be HTML-encoded.
     */
    public $encodeLabels = true;
100

101 102 103 104 105 106 107 108 109 110 111 112
    /**
     * Renders the widget.
     */
    public function run()
    {
        $options = $this->options;
        $tag = ArrayHelper::remove($options, 'tag', 'div');
        echo Html::beginTag($tag, $options) . "\n";
        echo $this->renderItems() . "\n";
        echo Html::endTag($tag) . "\n";
        $this->registerWidget('tabs', TabsAsset::className());
    }
113

114 115
    /**
     * Renders tab items as specified on [[items]].
116
     * @return string the rendering result.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
     * @throws InvalidConfigException.
     */
    protected function renderItems()
    {
        $headers = [];
        $items = [];
        foreach ($this->items as $n => $item) {
            if (!isset($item['label'])) {
                throw new InvalidConfigException("The 'label' option is required.");
            }
            if (isset($item['url'])) {
                $url = Url::to($item['url']);
            } else {
                if (!isset($item['content'])) {
                    throw new InvalidConfigException("The 'content' or 'url' option is required.");
                }
                $options = array_merge($this->itemOptions, ArrayHelper::getValue($item, 'options', []));
                $tag = ArrayHelper::remove($options, 'tag', 'div');
                if (!isset($options['id'])) {
                    $options['id'] = $this->options['id'] . '-tab' . $n;
                }
                $url = '#' . $options['id'];
                $items[] = Html::tag($tag, $item['content'], $options);
            }
            $headerOptions = array_merge($this->headerOptions, ArrayHelper::getValue($item, 'headerOptions', []));
            $template = ArrayHelper::getValue($item, 'template', $this->linkTemplate);
            $headers[] = Html::tag('li', strtr($template, [
                '{label}' => $this->encodeLabels ? Html::encode($item['label']) : $item['label'],
                '{url}' => $url,
            ]), $headerOptions);
        }
Alexander Kochetov committed
148

149 150
        return Html::tag('ul', implode("\n", $headers)) . "\n" . implode("\n", $items);
    }
151
}