├── .gitignore
├── LICENSE
├── LICENSE.md
├── Metronic.php
├── README.md
├── builders
└── TreeBuilder.php
├── bundles
├── BaseAssetBundle.php
├── BootboxAsset.php
├── CoreAsset.php
├── DatePickerAsset.php
├── DateRangePickerAsset.php
├── DraggablePortletsAssetBundle.php
├── DropZoneAsset.php
├── FontAsset.php
├── GridViewAsset.php
├── GridViewSortableAsset.php
├── IonRangeSliderAsset.php
├── ListViewAsset.php
├── ListViewSortableAsset.php
├── ModalAsset.php
├── MultiSelectAsset.php
├── NotificationAsset.php
├── Select2Asset.php
├── SpinnerAsset.php
├── StepsLineBundle.php
├── StyleBasedAsset.php
├── TagInputAsset.php
├── ThemeAsset.php
└── TreeAsset.php
├── composer.json
├── composer.lock
├── composer
└── Installer.php
├── helpers
├── Font.php
├── Html.php
└── Layout.php
├── layouts
└── main.php
├── traits
└── HtmlTrait.php
└── widgets
├── Accordion.php
├── ActionColumn.php
├── ActiveField.php
├── ActiveForm.php
├── Alert.php
├── Badge.php
├── Breadcrumbs.php
├── Button.php
├── ButtonDropdown.php
├── ButtonGroup.php
├── CheckboxList.php
├── DatePicker.php
├── DateRangePicker.php
├── Decorator.php
├── DetailView.php
├── DraggablePortlets.php
├── DropZone.php
├── Dropdown.php
├── DropdownContent.php
├── GridView.php
├── HorizontalMenu.php
├── InputWidget.php
├── IonRangeSlider.php
├── Link.php
├── ListView.php
├── Menu.php
├── Modal.php
├── MultiSelect.php
├── Nav.php
├── NavBar.php
├── Note.php
├── Notification.php
├── Panel.php
├── Portlet.php
├── Ribbon.php
├── Select2.php
├── Spinner.php
├── StepsLine.php
├── Tabs.php
├── TagInput.php
├── TextInputWidget.php
├── Tree.php
└── Widget.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | /nbproject/private/
3 | /nbproject/
4 | /vendor/
5 | assets/*
6 | !assets/.gitignore
7 | protected/runtime/*
8 | !protected/runtime/.gitignore
9 | protected/data/*.db
10 | themes/classic/views/
11 | assets
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015, jirisvoboda
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | * Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | * Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | * Neither the name of yii2-metronic nor the names of its
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The Yii2Metronic is free software. It is released under the terms of
2 | the following BSD License.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions
6 | are met:
7 |
8 | * Redistributions of source code must retain the above copyright
9 | notice, this list of conditions and the following disclaimer.
10 | * Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in
12 | the documentation and/or other materials provided with the
13 | distribution.
14 | * Neither the name of Yii2Metronic nor the names of its
15 | contributors may be used to endorse or promote products derived
16 | from this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 | FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 | COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 | POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------------
/Metronic.php:
--------------------------------------------------------------------------------
1 | sidebarOption && self::SIDEBAR_MENU_HOVER === $this->sidebarMenu) {
241 | throw new InvalidConfigException('Hover Sidebar Menu is not compatible with Fixed Sidebar Mode. Select Default Sidebar Mode Instead.');
242 | }
243 |
244 | if (!$this->resources) {
245 | throw new InvalidConfigException('You have to specify resources locations to be able to create symbolic links. Specify "admin" and "global" theme folder locations.');
246 | }
247 |
248 | if (!is_link(self::ASSETS_LINK) && !is_dir(self::ASSETS_LINK)) {
249 | symlink($this->resources, self::ASSETS_LINK);
250 | }
251 | }
252 |
253 | public function parseAssetsParams(&$string)
254 | {
255 | if (preg_match('/\{[a-z]+\}/', $string)) {
256 | $string = str_replace(static::PARAM_VERSION, $this->version, $string);
257 |
258 | $string = str_replace(static::PARAM_THEME, $this->theme, $string);
259 | }
260 | }
261 |
262 | /**
263 | * @return Metronic Get Metronic component
264 | */
265 | public static function getComponent()
266 | {
267 | try {
268 | return \Yii::$app->get(static::$componentName);
269 | } catch (InvalidConfigException $ex) {
270 | return null;
271 | }
272 | }
273 |
274 | /**
275 | * Get base url to metronic assets
276 | * @param $view View
277 | * @return string
278 | */
279 | public static function getAssetsUrl($view)
280 | {
281 | if (static::$assetsBundle === null) {
282 | static::$assetsBundle = static::registerThemeAsset($view);
283 | }
284 |
285 | return (static::$assetsBundle instanceof AssetBundle) ? static::$assetsBundle->baseUrl : '';
286 | }
287 |
288 | /**
289 | * Register Theme Asset
290 | * @param $view View
291 | * @return AssetBundle
292 | */
293 | public static function registerThemeAsset($view)
294 | {
295 | return static::$assetsBundle = ThemeAsset::register($view);
296 | }
297 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # yii2-metronic
2 | Yii2 [Metronic theme](http://www.keenthemes.com/) integration. Currently is supported the version 4.6
3 |
4 | Requirements
5 | ------------
6 | To use this extension it is required to buy own license for Metronic theme from https://themeforest.net/item/metronic-responsive-admin-dashboard-template/4021469?ref=keenthemes
7 |
8 | Installation
9 | ------------
10 |
11 | The extension is in development and the only way to use this fork is through through [composer](http://getcomposer.org/download/).
12 |
13 |
14 | So add it to your composer.json with this composer command:
15 | ```
16 | php composer.phar require dlds/yii2-metronic dev-master
17 | ```
18 |
19 |
20 | Then You've to unzip the contents of your metronic Zip theme inside the ```@webroot/metronic``` folder. Check [Aliases](http://www.yiiframework.com/doc-2.0/guide-concept-aliases.html).
21 |
22 | You should have a folder structure like this:
23 |
24 | * app/
25 | * web/
26 | * metronic/
27 | * _documentation
28 | * _resources
29 | * _start
30 | * theme
31 | * theme_rtl
32 |
33 |
34 |
35 | Quick Start
36 | -----------
37 | Edit your ```config/web.php``` configuration file and add the metronic component:
38 |
39 | ```
40 | 'components' => [
41 | 'metronic'=>[
42 | 'class'=>'dlds\metronic\Metronic',
43 | 'resources'=>'[path to my web]/web/metronic/assets/theme/assets',
44 | 'style'=>\dlds\metronic\Metronic::STYLE_MATERIAL,
45 | 'theme'=>\dlds\metronic\Metronic::THEME_LIGHT,
46 | 'layoutOption'=>\dlds\metronic\Metronic::LAYOUT_FLUID,
47 | 'headerOption'=>\dlds\metronic\Metronic::HEADER_FIXED,
48 | 'sidebarPosition'=>\dlds\metronic\Metronic::SIDEBAR_POSITION_LEFT,
49 | 'sidebarOption'=>\dlds\metronic\Metronic::SIDEBAR_MENU_ACCORDION,
50 | 'footerOption'=>\dlds\metronic\Metronic::FOOTER_FIXED,
51 |
52 | ],
53 | ]
54 | ```
55 |
56 | **WARNING**
57 | Check the "resources" key. This component field is used to locate the content of the zip theme.
58 | The component try to create a symlink to this directory inside it's folder. **Eventually this may not work!**
59 | In the case the link is invalid, you've to build it by yourself :)
60 |
61 | My vendor folder looks like this:
62 |
63 | * app/
64 | * [...]
65 | * vendor/
66 | * dlds/
67 | * yii2-metronic/
68 | * assets -> symlink to /var/www/project/web/metronic/assets/theme/assets
69 | * builders/
70 | * bundles/
71 | * helpers/
72 | * layouts/
73 | * widgets/
74 |
75 |
76 | I suggest also to configure the assetManager. My actual configuration is this:
77 | ```
78 | 'assetManager' => [
79 | 'linkAssets' => true,
80 | 'bundles' => [
81 | 'yii\web\JqueryAsset' => [
82 | 'sourcePath' => null, // do not publish the bundle
83 | 'js' => [
84 | '//code.jquery.com/jquery-1.11.2.min.js', // use custom jquery
85 | ]
86 | ],
87 |
88 | 'dlds\metronic\bundles\ThemeAsset' => [
89 | 'addons'=>[
90 | 'default/login'=>[
91 | 'css'=>[
92 | 'pages/css/login-4.min.css',
93 | ],
94 | 'js'=>[
95 | 'global/plugins/backstretch/jquery.backstretch.min.js',
96 |
97 | ]
98 | ],
99 | ]
100 | ],
101 | ],
102 | ],
103 | ```
104 |
105 | In the ThemeAsset class i've added the support for addons. You can specify additional css/js for specific controller/action.
106 |
107 | In the example is visible the way to add login-4.min.css and jquery.backstretch.min.js to the login page (in my case, the actionLogin is managed by a controller named DefaultController).
108 |
109 | Configuring the layout for your views is the last step.
110 |
111 | The metronic component contains a sample layout view. I've not checked it. I'm working on my layout :)
112 |
113 | Here is my sample ```views/layout/main.php```:
114 |
115 | ```
116 | assetManager->getPublishedUrl($asset->sourcePath);
128 | ?>
129 | beginPage() ?>
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | = Html::csrfMetaTags() ?>
140 | = Html::encode($this->title) ?>
141 | head() ?>
142 |
143 | 'page-container-bg-solid'],true) ?>>
144 | beginBody() ?>
145 |
146 | = $this->render('parts/header.php', ['directoryAsset' => $directoryAsset]) ?>
147 |
148 |
149 |
150 | = $this->render('parts/sidebar.php', ['directoryAsset' => $directoryAsset]) ?>
151 |
152 | = $this->render('parts/content.php', ['content' => $content, 'directoryAsset' => $directoryAsset]) ?>
153 |
154 | = $this->render('parts/footer.php', ['directoryAsset' => $directoryAsset]) ?>
155 |
156 | endBody() ?>
157 |
158 |
159 |
160 | endPage() ?>
161 | ```
162 |
163 | Metronic theme require that you replace yii\helpers\Html with it's helper. So, you have to add a ```config/bootstrap.php``` with the following content:
164 |
165 | ```
166 |
169 | ```
170 |
171 | The file bootstrap.php should be loaded before the web application is created. So you need to edit your ```web/index.php``` file
172 | and adjust it, and add a require directive. The file content should look like this:
173 |
174 | ```
175 | run();
187 | ```
188 |
189 | Things to notice:
190 |
191 | * I've moved the rendering of the main parts to separate files (parts/*). You can build this files and add them to your project.
192 | * I pass everywhere the $directoryAsset variable: this contain the path to the assets. Useful to load images bundled with the metronic theme.
193 | * the BODY tag is managed with a Layout::getHtmlOptions(). This method is able to build all the Metronic required classes.
194 | * Always check to use $this->beginPage(), $this->beginBody() and relatives $this->endBody() and $this->endPage() in the proper places :)
195 |
196 |
--------------------------------------------------------------------------------
/builders/TreeBuilder.php:
--------------------------------------------------------------------------------
1 | _items = $items;
65 |
66 | $this->setParams($params);
67 | }
68 |
69 | /**
70 | * Retrieves new instance of MTreeBuilder
71 | * @param array $items given items to traverse
72 | */
73 | public static function instance($items, $params = array())
74 | {
75 | return new self($items, $params);
76 | }
77 |
78 | /**
79 | * Build tree from given items
80 | */
81 | public function build()
82 | {
83 | return $this->renderTree();
84 | }
85 |
86 | /**
87 | * Sets class params
88 | * @param array $params given params
89 | * @throws Exception if param does not exists
90 | */
91 | public function setParams($params)
92 | {
93 | foreach ($params as $param => $value)
94 | {
95 | if (!property_exists($this, $param))
96 | {
97 | throw new Exception(Yii::t('app', 'Class {class} has no param called "{param}."', array(
98 | '{class}' => get_class($this),
99 | '{param}' => $param
100 | )));
101 | }
102 |
103 | $this->{$param} = $value;
104 | }
105 | }
106 |
107 | /**
108 | * Renders tree
109 | * @return string html
110 | */
111 | protected function renderTree()
112 | {
113 | $html = '';
114 |
115 | $level = -1;
116 |
117 | foreach ($this->_items as $model)
118 | {
119 | if (is_array($model)){
120 | $model = (object) $model;
121 | }
122 |
123 | if ($model->{$this->levelAttr} == $level)
124 | {
125 | $html .= $this->renderItemClose();
126 | }
127 | else if ($model->{$this->levelAttr} > $level)
128 | {
129 | $html .= $this->renderTreeOpen();
130 | }
131 | else
132 | {
133 | $html .= $this->renderItemClose();
134 |
135 | for ($i = $level - $model->{$this->levelAttr}; $i; $i--)
136 | {
137 | $html .= $this->renderTreeClose();
138 |
139 | $html .= $this->renderItemClose();
140 | }
141 | }
142 |
143 | $html .= $this->renderItemOpen($model->primaryKey);
144 |
145 | $html .= Html::tag('i','', [
146 | 'class' => 'jstree-icon jstree-ocl',
147 | 'role' => 'presentation'
148 | ]
149 | );
150 |
151 | if (is_callable($this->contentCallback))
152 | {
153 | $html .= $this->renderContent(call_user_func($this->contentCallback, $model, $level));
154 | }
155 | else
156 | {
157 | $html .= $this->renderContent($model);
158 | }
159 |
160 |
161 | $level = $model->{$this->levelAttr};
162 | }
163 |
164 | for ($i = $level; $i; $i--)
165 | {
166 | $html .= $this->renderItemClose();
167 | $html .= $this->renderTreeClose();
168 | }
169 |
170 | return $html;
171 | }
172 |
173 | /**
174 | * Renders tree open tag
175 | * @return string html
176 | */
177 | protected function renderTreeOpen()
178 | {
179 | $options = $this->getHtmlOptions($this->treeHtmlOptions);
180 |
181 | return Html::beginTag($this->treeTag, $options);
182 | }
183 |
184 | /**
185 | * Renders item open tag
186 | * @return string html
187 | */
188 | protected function renderItemOpen($id)
189 | {
190 | $options = $this->getHtmlOptions($this->itemHtmlOptions, $id);
191 |
192 | return Html::beginTag($this->itemTag, $options);
193 | }
194 |
195 | /**
196 | * Renders item content
197 | */
198 | protected function renderContent($content)
199 | {
200 | if ($this->contentTag)
201 | {
202 | $options = $this->getHtmlOptions($this->contentHtmlOptions);
203 |
204 | return Html::tag($this->contentTag, $options, $content);
205 | }
206 |
207 | return $content;
208 | }
209 |
210 | /**
211 | * Renders item close tag
212 | * @return string html
213 | */
214 | protected function renderItemClose()
215 | {
216 | return Html::endTag($this->itemTag);
217 | }
218 |
219 | /**
220 | * Renders tree close tag
221 | * @return string html
222 | */
223 | protected function renderTreeClose()
224 | {
225 | return Html::endTag($this->treeTag);
226 | }
227 |
228 | /**
229 | * Retrieves html options for given property
230 | * @return array html options
231 | */
232 | protected function getHtmlOptions($property, $attr = null)
233 | {
234 | if (is_callable($property))
235 | {
236 | return (array) $property->__invoke($attr);
237 | }
238 |
239 | return (array) $property;
240 | }
241 | }
--------------------------------------------------------------------------------
/bundles/BaseAssetBundle.php:
--------------------------------------------------------------------------------
1 | css as $k=>$v) {
21 | if (strpos($v,'.min.css')===false) {
22 | $fileName = str_replace('.css','.min.css',$v);
23 | $newFile = \Yii::getAlias($this->sourcePath) .'/'. $fileName;
24 | if (!file_exists($newFile)) {
25 | $fileName = $v;
26 | }
27 | $this->css[$k] = defined(YII_ENV_DEV) ? $v : $fileName;
28 | }
29 | }
30 | foreach($this->js as $k=>$v) {
31 | if (strpos($v,'.min.js')===false) {
32 | $fileName = str_replace('.css','.min.css',$v);
33 | $newFile = \Yii::getAlias($this->sourcePath) .'/'. $fileName;
34 | if (!file_exists($newFile)) {
35 | $fileName = $v;
36 | }
37 | $this->js[$k] = defined(YII_ENV_DEV) ? $v : $fileName;
38 | }
39 | }
40 | parent::init(); // TODO: Change the autogenerated stub
41 | }
42 | }
--------------------------------------------------------------------------------
/bundles/BootboxAsset.php:
--------------------------------------------------------------------------------
1 | view->registerJs('
23 | yii.confirm = function(message, ok, cancel) {
24 | bootbox.confirm({
25 | title: "Confirm",
26 | message: message,
27 | callback: function(result) { if (result) { !ok || ok(); } else { !cancel || cancel(); } }
28 | });
29 | }
30 | ');
31 | }
32 | }
--------------------------------------------------------------------------------
/bundles/CoreAsset.php:
--------------------------------------------------------------------------------
1 | [
36 | 'plugins/respond.min.js' => 'if lt IE 9',
37 | 'plugins/excanvas.min.js' => 'if lt IE 9',
38 | ],
39 | ];
40 |
41 | /**
42 | * @var array js assets
43 | */
44 | public $js = [
45 | // 'global/plugins/jquery.min.js',
46 | 'global/plugins/jquery-migrate.min.js',
47 | 'global/plugins/jquery-ui/jquery-ui.min.js',
48 | // 'global/plugins/bootstrap/js/bootstrap.min.js',
49 | 'global/plugins/jquery-slimscroll/jquery.slimscroll.min.js',
50 | 'global/plugins/jquery.blockui.min.js',
51 | 'global/plugins/bootstrap-hover-dropdown/bootstrap-hover-dropdown.min.js',
52 | 'global/plugins/bootstrap-switch/js/bootstrap-switch.min.js',
53 |
54 |
55 | ];
56 | }
57 |
--------------------------------------------------------------------------------
/bundles/DatePickerAsset.php:
--------------------------------------------------------------------------------
1 | js = array_merge($this->js, static::$extraJs);
28 | parent::init();
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/bundles/DateRangePickerAsset.php:
--------------------------------------------------------------------------------
1 | true
27 | ];
28 | }
--------------------------------------------------------------------------------
/bundles/FontAsset.php:
--------------------------------------------------------------------------------
1 | metronic;
40 | if (isset($component->ionSliderSkin)) {
41 | $skin = $component->ionSliderSkin;
42 | }
43 |
44 | $base = 'global/plugins/ion.rangeslider/css/ion.rangeSlider.%s.css';
45 | $this->css[] = sprintf($base, $skin);
46 |
47 | parent::init();
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/bundles/ListViewAsset.php:
--------------------------------------------------------------------------------
1 | [
32 | 'global/css/components.css',
33 | 'global/css/plugins.css',
34 | ],
35 | Metronic::STYLE_ROUNDED => [
36 | 'global/css/components-rounded.css',
37 | 'global/css/plugins.css',
38 | ],
39 | Metronic::STYLE_MATERIAL => [
40 | 'global/css/components-md.css',
41 | 'global/css/plugins-md.css',
42 | ]
43 | ];
44 |
45 | /**
46 | * Inits bundle
47 | */
48 | public function init()
49 | {
50 | $this->_handleStyleBased();
51 |
52 | return parent::init();
53 | }
54 |
55 | /**
56 | * Handles style based files
57 | */
58 | private function _handleStyleBased()
59 | {
60 | if (Metronic::getComponent())
61 | {
62 | $css = $this->styleBasedCss[Metronic::getComponent()->style];
63 | $this->css = ArrayHelper::merge($css, $this->css);
64 | }
65 | }
66 | }
--------------------------------------------------------------------------------
/bundles/TagInputAsset.php:
--------------------------------------------------------------------------------
1 | _handleSourcePath();
53 |
54 | $this->_handleAddons();
55 |
56 | $this->_handleDynamicCss();
57 |
58 | $this->_handleDynamicJs();
59 |
60 | return parent::init();
61 | }
62 |
63 | /**
64 | * Parses source path
65 | */
66 | private function _handleSourcePath()
67 | {
68 | if (Metronic::getComponent())
69 | {
70 | Metronic::getComponent()->parseAssetsParams($this->sourcePath);
71 | }
72 | }
73 |
74 | /**
75 | * Parses dynamic css
76 | */
77 | private function _handleDynamicCss()
78 | {
79 | $component = Metronic::getComponent();
80 |
81 | if ($component)
82 | {
83 | array_walk($this->css, [$component, 'parseAssetsParams']);
84 | }
85 | }
86 |
87 | /**
88 | * Parses dynamic js
89 | */
90 | private function _handleDynamicJs()
91 | {
92 | $component = Metronic::getComponent();
93 |
94 | if ($component)
95 | {
96 | array_walk($this->js, [$component, 'parseAssetsParams']);
97 | }
98 | }
99 |
100 | private function _handleAddons() {
101 | $controller = Yii::$app->controller->id .'/'. Yii::$app->controller->action->id;
102 | if (array_key_exists($controller, $this->addons)) {
103 | $additional = $this->addons[$controller];
104 | if (array_key_exists('js',$additional) && is_array($additional['js'])) {
105 | $this->js = array_merge($this->js, $additional['js']);
106 | }
107 | if (array_key_exists('css',$additional) && is_array($additional['css'])) {
108 | $this->css = array_merge($this->css, $additional['css']);
109 | }
110 | }
111 | }
112 | }
--------------------------------------------------------------------------------
/bundles/TreeAsset.php:
--------------------------------------------------------------------------------
1 | style)
42 | {
43 | Html::addCssClass($options, 'page-md');
44 | }
45 |
46 | if (Metronic::getComponent() && Metronic::LAYOUT_BOXED === Metronic::getComponent()->layoutOption)
47 | {
48 | Html::addCssClass($options, 'page-boxed');
49 | }
50 |
51 | if (Metronic::getComponent() && Metronic::HEADER_FIXED === Metronic::getComponent()->headerOption)
52 | {
53 | Html::addCssClass($options, 'page-header-fixed');
54 | }
55 |
56 | if (Metronic::getComponent() && Metronic::SIDEBAR_POSITION_RIGHT === Metronic::getComponent()->sidebarPosition)
57 | {
58 | Html::addCssClass($options, 'page-sidebar-reversed');
59 | }
60 |
61 | if (Metronic::getComponent() && Metronic::SIDEBAR_FIXED === Metronic::getComponent()->sidebarOption)
62 | {
63 | Html::addCssClass($options, 'page-sidebar-fixed');
64 | }
65 |
66 | if (Metronic::getComponent() && Metronic::FOOTER_FIXED === Metronic::getComponent()->footerOption)
67 | {
68 | Html::addCssClass($options, 'page-footer-fixed');
69 | }
70 |
71 | return $options;
72 | }
73 |
74 | /**
75 | * Adds header tag options
76 | * @param array $options given options
77 | */
78 | private static function _headerOptions($options)
79 | {
80 | Html::addCssClass($options, 'page-header navbar');
81 |
82 | if (Metronic::getComponent() && Metronic::HEADER_FIXED === Metronic::getComponent()->headerOption)
83 | {
84 | Html::addCssClass($options, 'navbar-fixed-top');
85 | }
86 | else
87 | {
88 | Html::addCssClass($options, 'navbar-static-top');
89 | }
90 |
91 | return $options;
92 | }
93 |
94 | /**
95 | * Adds actions tag options
96 | * @param array $options given options
97 | */
98 | private static function _actionsOptions($options)
99 | {
100 | Html::addCssClass($options, 'page-actions');
101 |
102 | return $options;
103 | }
104 |
105 | /**
106 | * Adds top tag options
107 | * @param array $options given options
108 | */
109 | private static function _topOptions($options)
110 | {
111 | Html::addCssClass($options, 'page-top');
112 |
113 | return $options;
114 | }
115 |
116 | /**
117 | * Adds topmenu tag options
118 | * @param array $options given options
119 | */
120 | private static function _topmenuOptions($options)
121 | {
122 | Html::addCssClass($options, 'top-menu');
123 |
124 | return $options;
125 | }
126 |
127 | /**
128 | * Adds container tag options
129 | * @param array $options given options
130 | */
131 | private static function _containerOptions($options)
132 | {
133 | Html::addCssClass($options, 'container');
134 |
135 | return $options;
136 | }
137 |
138 | /**
139 | * Adds clearfix tag options
140 | * @param array $options given options
141 | */
142 | private static function _clearfixOptions($options)
143 | {
144 | Html::addCssClass($options, 'clearfix');
145 |
146 | return $options;
147 | }
148 |
149 | }
150 |
--------------------------------------------------------------------------------
/traits/HtmlTrait.php:
--------------------------------------------------------------------------------
1 | $condition) {
43 | if (strpos($url, $file) !== false) {
44 | unset($options['conditions']);
45 | return static::conditionalComment(static::tag('link', '', $options), $condition);
46 | }
47 | }
48 | }
49 | unset($options['conditions']);
50 |
51 | return static::tag('link', '', $options);
52 | }
53 |
54 | /**
55 | * Generates a script tag that refers to an external JavaScript file.
56 | * @param string $url the URL of the external JavaScript file. This parameter will be processed by [[\yii\helpers\Url::to()]].
57 | * @param array $options the tag options in terms of name-value pairs. These will be rendered as
58 | * the attributes of the resulting tag. The values will be HTML-encoded using [[encode()]].
59 | * If a value is null, the corresponding attribute will not be rendered.
60 | * See [[renderTagAttributes()]] for details on how attributes are being rendered.
61 | * @return string the generated script tag
62 | * @see \yii\helpers\Url::to()
63 | */
64 | public static function jsFile($url, $options = [])
65 | {
66 | $options['src'] = Url::to($url);
67 | if (!empty($options['conditions'])) {
68 | foreach ($options['conditions'] as $file => $condition) {
69 | if (strpos($url, $file) !== false) {
70 | unset($options['conditions']);
71 | return static::conditionalComment(static::tag('script', '', $options), $condition);
72 | }
73 | }
74 | }
75 | unset($options['conditions']);
76 |
77 | return static::tag('script', '', $options);
78 | }
79 |
80 | /**
81 | * Generates conditional comments such as ''.
82 | * @param $content string the commented content
83 | * @param $condition string condition. Can contain 'if...' or ''
84 | * @return string the generated result
85 | */
86 | public static function conditionalComment($content, $condition)
87 | {
88 | $condition = strpos($condition, '') !== false ? '';
93 |
94 | return implode("\n", $lines);
95 | }
96 |
97 | /**
98 | * @inheritdoc
99 | */
100 | public static function dropDownList($name, $selection = null, $items = [], $options = [], $standardSelect = false)
101 | {
102 | if (!$standardSelect) {
103 | Select2Asset::register(\Yii::$app->view);
104 |
105 | self::addCssClass($options, static::$_clsSelect2);
106 |
107 | self::addData($options, 'placeholder', '-');
108 | }
109 |
110 | return parent::dropDownList($name, $selection, $items, $options);
111 | }
112 |
113 | /**
114 | * @inheritdoc
115 | */
116 | public static function activeDropDownList($model, $attribute, $items, $options = [], $standardSelect = false)
117 | {
118 | if (!$standardSelect) {
119 | Select2Asset::register(\Yii::$app->view);
120 |
121 | self::addCssClass($options, static::$_clsSelect2);
122 |
123 | self::addData($options, 'placeholder', '-');
124 | }
125 |
126 | return parent::activeDropDownList($model, $attribute, $items, $options);
127 | }
128 |
129 | /**
130 | * Adds data attribute to element options
131 | * @param type $key
132 | * @param type $value
133 | * @param type $replace
134 | */
135 | protected static function addData(&$options, $key, $value, $replace = false)
136 | {
137 | $placeholder = ArrayHelper::getValue($options, sprintf('data.%s', $key), null);
138 |
139 | if (null === $placeholder || $replace) {
140 | $options['data'][$key] = $value;
141 | }
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/widgets/Accordion.php:
--------------------------------------------------------------------------------
1 | [
21 | * [
22 | * 'header' => 'Item 1',
23 | * 'content' => 'Content 1...',
24 | * // open its content by default
25 | * 'contentOptions' => ['class' => 'in'],
26 | * 'type' => Accordion::ITEM_TYPE_SUCCESS,
27 | * ],
28 | * [
29 | * 'header' => 'Item 2',
30 | * 'content' => 'Content 2...',
31 | * ],
32 | * ],
33 | * 'itemConfig' => ['showIcon' => true],
34 | *]);
35 | * ```
36 | *
37 | * @see http://getbootstrap.com/javascript/#collapse
38 | */
39 | class Accordion extends Widget
40 | {
41 | // Item types
42 | const ITEM_TYPE_DEFAULT = 'default';
43 | const ITEM_TYPE_SUCCESS = 'success';
44 | const ITEM_TYPE_DANGER = 'danger';
45 | const ITEM_TYPE_WARNING = 'warning';
46 | const ITEM_TYPE_INFO = 'info';
47 |
48 | /**
49 | * @var array list of groups in the collapse widget. Each array element represents a single
50 | * group with the following structure:
51 | *
52 | * ```php
53 | * [
54 | * // required, the header (HTML) of the group
55 | * 'header' => 'Item 1',
56 | * // required, the content (HTML) of the group
57 | * 'content' => '',
58 | * // optional the HTML attributes of the content group
59 | * 'contentOptions' => [],
60 | * // optional, the HTML attributes of the group
61 | * 'options' => [],
62 | * // optional, the item type. Valid values are 'default', 'success', 'danger', 'warning', 'info'
63 | * // Determines color of the item.
64 | * 'type' => '',
65 | * ]
66 | * ```
67 | */
68 | public $items = [];
69 | /**
70 | * @var array the default configuration used by item.
71 | */
72 | public $itemConfig = [];
73 |
74 | /**
75 | * Initializes the widget.
76 | */
77 | public function init()
78 | {
79 | parent::init();
80 | Html::addCssClass($this->options, 'panel-group accordion');
81 | }
82 |
83 | /**
84 | * Renders the widget.
85 | */
86 | public function run()
87 | {
88 | echo Html::beginTag('div', $this->options) . "\n";
89 | echo $this->renderItems() . "\n";
90 | echo Html::endTag('div') . "\n";
91 | $this->registerPlugin('collapse');
92 | }
93 |
94 | /**
95 | * Renders collapsible items as specified on [[items]].
96 | * @return string the rendering result
97 | * @throws InvalidConfigException.
98 | */
99 | public function renderItems()
100 | {
101 | $items = [];
102 | $index = 0;
103 | foreach ($this->items as $item) {
104 | if (!isset($item['header'])) {
105 | throw new InvalidConfigException("The 'header' option is required.");
106 | }
107 | if (!isset($item['content'])) {
108 | throw new InvalidConfigException("The 'content' option is required.");
109 | }
110 |
111 | $options = ArrayHelper::getValue($item, 'options', []);
112 | $type = ArrayHelper::getValue($item, 'type', self::ITEM_TYPE_DEFAULT);
113 | Html::addCssClass($options, 'panel panel-' . $type);
114 | $items[] = Html::tag('div', $this->renderItem(array_merge($this->itemConfig, $item), ++$index), $options);
115 | }
116 |
117 | return implode("\n", $items);
118 | }
119 |
120 | /**
121 | * Renders a single collapsible item group
122 | * @param array $item a single item from [[items]]
123 | * @param integer $index the item index as each item group content must have an id
124 | * @return string the rendering result
125 | * @throws InvalidConfigException
126 | */
127 | protected function renderItem($item, $index)
128 | {
129 | $options = ArrayHelper::getValue($item, 'options', []);
130 | $type = ArrayHelper::getValue($item, 'type', self::ITEM_TYPE_DEFAULT);
131 | Html::addCssClass($options, 'panel panel-' . $type);
132 | $id = $this->options['id'] . '-collapse' . $index;
133 | $options = ArrayHelper::getValue($item, 'contentOptions', []);
134 | $options['id'] = $id;
135 | Html::addCssClass($options, 'panel-collapse collapse');
136 | $styled = '';
137 | if (ArrayHelper::getValue($item, 'showIcon', false)) {
138 | if (preg_match('/[^\w]*in[^\w]*/', $options['class'])) {
139 | $styled = 'accordion-toggle-styled';
140 | } else {
141 | $styled = 'accordion-toggle-styled collapsed';
142 | }
143 | }
144 | $headerToggle = Html::a(
145 | $item['header'],
146 | '#' . $id,
147 | [
148 | 'class' => 'accordion-toggle ' . $styled,
149 | 'data-toggle' => 'collapse',
150 | 'data-parent' => '#' . $this->options['id']
151 | ]
152 | ) . "\n";
153 |
154 | $header = Html::tag('h4', $headerToggle, ['class' => 'panel-title']);
155 | $content = Html::tag('div', $item['content'], ['class' => 'panel-body']) . "\n";
156 |
157 | $group = [];
158 | $group[] = Html::tag('div', $header, ['class' => 'panel-heading']);
159 | $group[] = Html::tag('div', $content, $options);
160 |
161 | return implode("\n", $group);
162 | }
163 | }
164 |
--------------------------------------------------------------------------------
/widgets/ActionColumn.php:
--------------------------------------------------------------------------------
1 | 'text-center'];
18 |
19 | /**
20 | * @var array the HTML options for the data cell tags.
21 | */
22 | public $contentOptions = ['class' => 'text-center'];
23 |
24 | /**
25 | * @var string the template that is used to render the content in each data cell.
26 | */
27 | public $template = '{update}';
28 |
29 | /**
30 | * @var string the icon for the view button.
31 | */
32 | public $viewButtonIcon = 'icon-eye';
33 |
34 | /**
35 | * @var string the icon for the update button.
36 | */
37 | public $updateButtonIcon = 'icon-pencil';
38 |
39 | /**
40 | * @var string the icon for the delete button.
41 | */
42 | public $deleteButtonIcon = 'icon-trash';
43 |
44 | /**
45 | * @var string the icon for the delete button.
46 | */
47 | public $resetButtonIcon = 'icon-close';
48 |
49 | /**
50 | * @var mixed array pager settings or false to disable pager
51 | */
52 | public $pageSizeOptions = [20 => 20, 50 => 50];
53 |
54 | /**
55 | * @var string btn view class
56 | */
57 | public $btnViewClass = 'action-view';
58 |
59 | /**
60 | * @var string btn update class
61 | */
62 | public $btnUpdateClass = 'action-update';
63 |
64 | /**
65 | * @var string btn delete class
66 | */
67 | public $btnDeleteClass = 'action-delete';
68 |
69 | /**
70 | * @var mixed filter reset route
71 | */
72 | public $routeFilterReset = null;
73 |
74 | /**
75 | * Initializes the default button rendering callbacks.
76 | */
77 | protected function initDefaultButtons()
78 | {
79 | if (!isset($this->buttons['view']))
80 | {
81 | $this->buttons['view'] = function ($url, $model, $key) {
82 | return Html::a('', $url, [
83 | 'title' => \Yii::t('yii', 'View'),
84 | 'data-pjax' => '0',
85 | 'class' => $this->btnViewClass,
86 | ]);
87 | };
88 | }
89 | if (!isset($this->buttons['update']))
90 | {
91 | $this->buttons['update'] = function ($url, $model, $key) {
92 | return Html::a('', $url, [
93 | 'title' => \Yii::t('yii', 'Update'),
94 | 'data-pjax' => '0',
95 | 'class' => $this->btnUpdateClass,
96 | ]);
97 | };
98 | }
99 | if (!isset($this->buttons['delete']))
100 | {
101 | $this->buttons['delete'] = function ($url, $model, $key) {
102 | return Html::a('', $url, [
103 | 'title' => \Yii::t('yii', 'Delete'),
104 | 'data-confirm' => \Yii::t('yii', 'Are you sure you want to delete this item?'),
105 | 'data-method' => 'post',
106 | 'data-pjax' => '0',
107 | 'class' => $this->btnDeleteClass,
108 | ]);
109 | };
110 | }
111 | }
112 |
113 | /**
114 | * @inheritdoc
115 | */
116 | protected function renderHeaderCellContent()
117 | {
118 | if (!$this->routeFilterReset)
119 | {
120 | $route = \Yii::$app->controller->getRoute();
121 |
122 | if (!\yii\helpers\StringHelper::startsWith($route, '/'))
123 | {
124 | $route = '/'.$route;
125 | }
126 |
127 | $this->routeFilterReset = [$route];
128 | }
129 |
130 | return Html::a('', $this->routeFilterReset, [
131 | 'title' => \Yii::t('yii', 'Reset filter'),
132 | 'data-pjax' => '0',
133 | ]);
134 | }
135 |
136 | /**
137 | * Renders the filter cell content.
138 | * The default implementation simply renders a space.
139 | * This method may be overridden to customize the rendering of the filter cell (if any).
140 | * @return string the rendering result
141 | */
142 | protected function renderFilterCellContent()
143 | {
144 | if (!$this->pageSizeOptions)
145 | {
146 | return parent::renderFilterCellContent();
147 | }
148 |
149 | return Html::dropDownList($this->grid->dataProvider->pagination->pageSizeParam, $this->grid->dataProvider->pagination->pageSize, $this->pageSizeOptions);
150 | }
151 | }
--------------------------------------------------------------------------------
/widgets/ActiveField.php:
--------------------------------------------------------------------------------
1 | options['tag']) ? $this->options['tag'] : 'div') . "\n";
32 | }
33 |
34 | /**
35 | * Generates a icon for input.
36 | * @param array $options icon options.
37 | * The options have following structure:
38 | * ```php
39 | * [
40 | * 'icon' => 'fa fa-bookmark-o',
41 | * 'position' => ActiveField::ICON_POSITION_LEFT,
42 | * ]
43 | * ```
44 | * @return static the field object itself
45 | */
46 | public function icon($options = [])
47 | {
48 | $icon = ArrayHelper::remove($options, 'icon', null);
49 | if ($icon)
50 | {
51 | $position = ArrayHelper::remove($options, 'position', self::ICON_POSITION_LEFT);
52 | if ($position != self::ICON_POSITION_RIGHT)
53 | {
54 | $position = '';
55 | }
56 | $this->parts['{input}'] = Html::tag('i', '', ['class' => $icon]) . "\n" . $this->parts['{input}'];
57 | $this->parts['{input}'] = Html::tag('div', $this->parts['{input}'], ['class' => 'input-icon ' . $position]);
58 | }
59 |
60 | return $this;
61 | }
62 |
63 | /**
64 | * Generates a groupAddon for input.
65 | * GroupAddon similar to [[icon()]].
66 | * @param array $options icon options.
67 | * The options have following structure:
68 | * ```php
69 | * [
70 | * 'icon' => 'fa fa-bookmark-o',
71 | * 'position' => ActiveField::ICON_POSITION_LEFT,
72 | * ]
73 | * ```
74 | * @return static the field object itself
75 | */
76 | public function groupAddon($options = [])
77 | {
78 | $icon = ArrayHelper::remove($options, 'icon', null);
79 | if ($icon)
80 | {
81 | $addon = Html::tag('span', Html::tag('i', '', ['class' => $icon]), ['class' => 'input-group-addon']);
82 | $position = ArrayHelper::remove($options, 'position', self::ICON_POSITION_LEFT);
83 | if ($position == self::ICON_POSITION_RIGHT)
84 | {
85 | $this->parts['{input}'] .= "\n" . $addon;
86 | }
87 | else
88 | {
89 | $this->parts['{input}'] = $addon . "\n" . $this->parts['{input}'];
90 | }
91 | $this->parts['{input}'] = Html::tag('div', $this->parts['{input}'], ['class' => 'input-group']);
92 | }
93 |
94 | return $this;
95 | }
96 |
97 | /**
98 | * Generates a tag that contains error.
99 | * @param $error string the error to use.
100 | * @param array $options the tag options in terms of name-value pairs. It will be merged with [[errorOptions]].
101 | * @return static the field object itself
102 | */
103 | public function staticError($error, $options = [])
104 | {
105 | $options = array_merge($this->errorOptions, $options);
106 | $tag = isset($options['tag']) ? $options['tag'] : 'div';
107 | unset($options['tag']);
108 | $this->parts['{error}'] = Html::tag($tag, $error, $options);
109 |
110 | return $this;
111 | }
112 |
113 | /**
114 | * Generates spinner component.
115 | * @param array $options spinner options
116 | * @return $this
117 | */
118 | public function spinner($options = [])
119 | {
120 | $this->parts['{input}'] = Spinner::widget(array_merge($options, ['model' => $this->model, 'attribute' => $this->attribute]));
121 |
122 | return $this;
123 | }
124 |
125 | /**
126 | * Generates dateRangePicker component [[DateRangePicker]].
127 | * @param array $options dateRangePicker options
128 | * @return $this
129 | */
130 | public function dateRangePicker($options = [])
131 | {
132 | if ($this->form->type == ActiveForm::TYPE_VERTICAL)
133 | {
134 | //$options = array_merge($options, ['options' => ['style' => 'display:table-cell;']]);
135 | $options = array_merge($options, ['options' => ['class' => 'show']]);
136 | }
137 | $this->parts['{input}'] = DateRangePicker::widget(array_merge($options, ['model' => $this->model, 'attribute' => $this->attribute]));
138 |
139 | return $this;
140 | }
141 |
142 | /**
143 | * Generates dateRangePicker component [[DateRangePicker]].
144 | * @param array $options dateRangePicker options
145 | * @return $this
146 | */
147 | public function datePicker($options = [])
148 | {
149 | /* if ($this->form->type == ActiveForm::TYPE_VERTICAL) {
150 | //$options = array_merge($options, ['options' => ['style' => 'display:table-cell;']]);
151 | $options = array_merge($options, ['options' => ['class' => 'show']]);
152 | } */
153 | $this->parts['{input}'] = DatePicker::widget(array_merge($options, ['model' => $this->model, 'attribute' => $this->attribute]));
154 |
155 | return $this;
156 | }
157 |
158 | /**
159 | * Generates select2 component [[Select2]].
160 | * @param array $options select2 options
161 | * @return $this
162 | */
163 | public function select2($options = [])
164 | {
165 | $this->parts['{input}'] = Select2::widget(array_merge($options, ['model' => $this->model, 'attribute' => $this->attribute]));
166 |
167 | return $this;
168 | }
169 |
170 | /**
171 | * Generates multiSelect component [[MultiSelect]].
172 | * @param array $options multiSelect options
173 | * @return $this
174 | */
175 | public function multiSelect($options = [])
176 | {
177 | $this->parts['{input}'] = MultiSelect::widget(array_merge($options, ['model' => $this->model, 'attribute' => $this->attribute]));
178 |
179 | return $this;
180 | }
181 |
182 | public function range($options = [])
183 | {
184 | $this->parts['{input}'] = IonRangeSlider::widget(array_merge($options, ['model' => $this->model, 'attribute' => $this->attribute]));
185 |
186 | return $this;
187 | }
188 |
189 | }
190 |
--------------------------------------------------------------------------------
/widgets/ActiveForm.php:
--------------------------------------------------------------------------------
1 | ActiveForm::BUTTONS_POSITION_LEFT,
58 | * //optional, vertical position
59 | * 'position' => ActiveForm::BUTTONS_POSITION_BOTTOM,
60 | * //optional, array of buttons
61 | * 'items' => [
62 | * Button::widget('label' => 'Save', 'options' => ['type' => 'submit']),
63 | * Button::widget('label' => 'Back'),
64 | * ],
65 | * // optional, the HTML attributes (name-value pairs) for the form actions tag.
66 | * 'options' => ['class' => 'fluid']
67 | * ]
68 | * ```
69 | */
70 | public $buttons = [];
71 |
72 | /**
73 | * @var array the default configuration used by [[field()]] when creating a new field object.
74 | */
75 | public $fieldConfig = [];
76 |
77 | /**
78 | * @var bool indicates whether the tag 'form' is rendered.
79 | * In case 'true' widget renders 'div' instead 'form'.
80 | */
81 | public $fake = false;
82 |
83 | /**
84 | * Initializes the widget.
85 | * This renders the form open tag.
86 | */
87 | public function init()
88 | {
89 | if (!isset($this->options['id']))
90 | {
91 | $this->options['id'] = $this->getId();
92 | }
93 |
94 | switch ($this->type)
95 | {
96 | case self::TYPE_HORIZONTAL:
97 | if ($this->stripped)
98 | {
99 | Html::addCssClass($this->options, 'form-row-stripped');
100 | }
101 | if ($this->separated)
102 | {
103 | Html::addCssClass($this->options, 'form-row-seperated');
104 | }
105 | if ($this->bordered)
106 | {
107 | Html::addCssClass($this->options, 'form-bordered');
108 | }
109 | Html::addCssClass($this->options, 'form-horizontal');
110 | $this->fieldConfig = ArrayHelper::merge([
111 | 'labelOptions' => ['class' => 'col-md-3 control-label'],
112 | 'template' => "{label}\n" . Html::tag('div', "{input}\n{error}\n{hint}", ['class' => 'col-md-9']),
113 | ], $this->fieldConfig);
114 | break;
115 | case self::TYPE_INLINE:
116 | Html::addCssClass($this->options, 'form-inline');
117 | $this->fieldConfig = ArrayHelper::merge([
118 | 'labelOptions' => ['class' => 'sr-only'],
119 | ], $this->fieldConfig);
120 | break;
121 | }
122 | if (!isset($this->fieldConfig['class']))
123 | {
124 | $this->fieldConfig['class'] = ActiveField::className();
125 | }
126 | if ($this->fake)
127 | {
128 | echo Html::beginTag('div', $this->options);
129 | }
130 | else
131 | {
132 | echo Html::beginForm($this->action, $this->method, $this->options);
133 | }
134 | echo $this->renderActions(self::BUTTONS_POSITION_TOP);
135 | echo Html::beginTag('div', ['class' => 'form-body']);
136 | }
137 |
138 | /**
139 | * Runs the widget.
140 | * This registers the necessary javascript code and renders the form close tag.
141 | */
142 | public function run()
143 | {
144 | echo Html::endTag('div');
145 | echo $this->renderActions(self::BUTTONS_POSITION_BOTTOM);
146 | if (!empty($this->attributes))
147 | {
148 | $id = $this->options['id'];
149 | $options = Json::encode($this->getClientOptions());
150 | $attributes = Json::encode($this->attributes);
151 | $view = $this->getView();
152 | ActiveFormAsset::register($view);
153 | $view->registerJs("jQuery('#$id').yiiActiveForm($attributes, $options);");
154 | }
155 | if ($this->fake)
156 | {
157 | echo Html::endTag('div');
158 | }
159 | else
160 | {
161 | echo Html::endForm();
162 | }
163 | }
164 |
165 | /**
166 | * Generates a form field.
167 | * A form field is associated with a model and an attribute. It contains a label, an input and an error message
168 | * and use them to interact with end users to collect their inputs for the attribute.
169 | * @param Model $model the data model
170 | * @param string $attribute the attribute name or expression. See [[Html::getAttributeName()]] for the format
171 | * about attribute expression.
172 | * @param array $options the additional configurations for the field object
173 | * @return ActiveField the created ActiveField object
174 | * @see fieldConfig
175 | */
176 | public function field($model, $attribute, $options = [])
177 | {
178 | return parent::field($model, $attribute, $options);
179 | }
180 |
181 | protected function renderActions($currentPosition)
182 | {
183 | $position = ArrayHelper::getValue($this->buttons, 'position', self::BUTTONS_POSITION_BOTTOM);
184 | if (!empty($this->buttons['items']) && $position == $currentPosition)
185 | {
186 | $actionsOptions = ArrayHelper::getValue($this->buttons, 'options', []);
187 | Html::addCssClass($actionsOptions, 'form-actions');
188 | if ($position == self::BUTTONS_POSITION_TOP)
189 | {
190 | Html::addCssClass($actionsOptions, 'top');
191 | }
192 | if (isset($this->buttons['align']) && $this->buttons['align'] == self::BUTTONS_ALIGN_RIGHT)
193 | {
194 | Html::addCssClass($actionsOptions, 'right');
195 | }
196 | $rowOptions = [];
197 | $buttons = implode("\n", $this->buttons['items']);
198 | switch ($this->type)
199 | {
200 | case self::TYPE_HORIZONTAL:
201 | Html::addCssClass($actionsOptions, 'fluid');
202 | preg_match('#col-md-(\d+)#', $this->fieldConfig['labelOptions']['class'], $matches);
203 | if (isset($matches[1]))
204 | {
205 | $offset = $matches[1];
206 | Html::addCssClass($rowOptions, 'col-md-offset-' . $offset);
207 | Html::addCssClass($rowOptions, 'col-md-' . 12 - $offset);
208 | $buttons = Html::tag('div', $buttons, $rowOptions);
209 | }
210 | break;
211 | }
212 |
213 | return Html::tag('div', $buttons, $actionsOptions);
214 | }
215 |
216 | return '';
217 | }
218 |
219 | }
220 |
--------------------------------------------------------------------------------
/widgets/Alert.php:
--------------------------------------------------------------------------------
1 | 'Say hello...',
22 | * 'closeButton' => [
23 | * 'label' => '×',
24 | * 'tag' => 'a',
25 | * 'type' => Alert::TYPE_DANGER,
26 | * ],
27 | * ]);
28 | * ```
29 | *
30 | * The following example will show the content enclosed between the [[begin()]]
31 | * and [[end()]] calls within the alert box:
32 | *
33 | * ```php
34 | * Alert::begin([
35 | * 'type' => Alert::TYPE_DANGER,
36 | * 'closeButton' => ['label' => '×'],
37 | * ]);
38 | *
39 | * echo 'Say hello...';
40 | *
41 | * Alert::end();
42 | * ```
43 | */
44 | class Alert extends \yii\bootstrap\Alert {
45 |
46 | // type
47 | const TYPE_SUCCESS = 'success';
48 | const TYPE_INFO = 'info';
49 | const TYPE_WARNING = 'warning';
50 | const TYPE_DANGER = 'danger';
51 |
52 | /**
53 | * @var string the note type.
54 | * Valid values are 'success', 'info', 'warning', 'danger'.
55 | */
56 | public $type = self::TYPE_SUCCESS;
57 |
58 | /**
59 | * @var boolean when set, alert has a larger block size.
60 | */
61 | public $block = true;
62 |
63 | /**
64 | * Initializes the widget.
65 | */
66 | public function init()
67 | {
68 | Html::addCssClass($this->options, 'alert-' . $this->type);
69 | if ($this->block)
70 | {
71 | Html::addCssClass($this->options, 'alert-block');
72 | }
73 | parent::init();
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/widgets/Badge.php:
--------------------------------------------------------------------------------
1 | 'NEW',
18 | * 'type' => Badge::TYPE_SUCCESS,
19 | * 'round'
20 | * ]);
21 | *
22 | * @package dlds\metronic\widgets
23 | */
24 | class Badge extends \yii\base\Widget
25 | {
26 | // type
27 | const TYPE_DEFAULT = 'default';
28 | const TYPE_GRAY = 'default';
29 | const TYPE_SUCCESS = 'success';
30 | const TYPE_WARNING = 'warning';
31 | const TYPE_DANGER = 'danger';
32 | const TYPE_INFO = 'info';
33 | /**
34 | * @var string the badge label
35 | */
36 | public $label;
37 | /**
38 | * @var string the badge type
39 | * Valid values '', 'default', 'success', 'warning', 'danger', 'info'
40 | */
41 | public $type = self::TYPE_DEFAULT;
42 | /**
43 | * @var bool Indicates whether badge is rounded or not.
44 | */
45 | public $round = true;
46 |
47 | /**
48 | * Executes the widget.
49 | */
50 | public function run()
51 | {
52 | $options = [];
53 | Html::addCssClass($options, 'badge');
54 | if (!$this->round) {
55 | Html::addCssClass($options, 'badge-roundless');
56 | }
57 | Html::addCssClass($options, 'badge-' . $this->type);
58 |
59 | echo Html::tag('span', $this->label, $options);
60 | }
61 | }
--------------------------------------------------------------------------------
/widgets/Breadcrumbs.php:
--------------------------------------------------------------------------------
1 | [
27 | * ['label' => 'Sample Post', 'url' => ['post/edit', 'id' => 1]],
28 | * 'Edit',
29 | * ],
30 | * ]);
31 | * ```
32 | *
33 | * Because breadcrumbs usually appears in nearly every page of a website, you may consider placing it in a layout view.
34 | * You can use a view parameter (e.g. `$this->params['breadcrumbs']`) to configure the links in different
35 | * views. In the layout view, you assign this view parameter to the [[links]] property like the following:
36 | *
37 | * ```php
38 | * // $this is the view object currently being used
39 | * echo Breadcrumbs::widget([
40 | * 'links' => isset($this->params['breadcrumbs']) ? $this->params['breadcrumbs'] : [],
41 | * ]);
42 | * ```
43 | */
44 | class Breadcrumbs extends \yii\widgets\Breadcrumbs
45 | {
46 | /**
47 | * @var string the template used to render each inactive item in the breadcrumbs. The token `{link}`
48 | * will be replaced with the actual HTML link for each inactive item.
49 | */
50 | public $itemTemplate = "{link}\n";
51 | /**
52 | * @var string the template used to render each active item in the breadcrumbs. The token `{link}`
53 | * will be replaced with the actual HTML link for each active item.
54 | */
55 | public $activeItemTemplate = "{link}\n";
56 | /**
57 | * @var array|string
58 | */
59 | public $actions;
60 |
61 | public function init()
62 | {
63 | parent::init();
64 | Html::addCssClass($this->options, 'page-breadcrumb');
65 | }
66 |
67 |
68 | public function run()
69 | {
70 | if (empty($this->links)) {
71 | return;
72 | }
73 | $links = [];
74 |
75 | if ($this->actions !== null) {
76 | Html::addCssClass($this->actions['dropdown']['options'], 'pull-right');
77 | if (is_string($this->actions)) {
78 | $links[] = $this->actions;
79 | } else if (is_array($this->actions)) {
80 | $links[] = ButtonDropdown::widget($this->actions);
81 | } else {
82 | throw new InvalidConfigException('Actions must be of type "string" or "array".');
83 | }
84 | }
85 |
86 | if ($this->homeLink === null) {
87 | $links[] = $this->renderItem([
88 | 'label' => Yii::t('yii', 'Home'),
89 | 'url' => Yii::$app->homeUrl,
90 | ], $this->itemTemplate);
91 | } elseif ($this->homeLink !== false) {
92 | $links[] = $this->renderItem($this->homeLink, $this->itemTemplate);
93 | }
94 | foreach ($this->links as $link) {
95 | if (!is_array($link)) {
96 | $link = ['label' => $link];
97 | }
98 | $links[] = $this->renderItem($link, isset($link['url']) ? $this->itemTemplate : $this->activeItemTemplate);
99 | }
100 | echo Html::tag($this->tag, implode('', $links), $this->options);
101 | }
102 |
103 | /**
104 | * Renders a single breadcrumb item.
105 | * @param array $link the link to be rendered. It must contain the "label" element. The "url" element is optional.
106 | * @param string $template the template to be used to rendered the link. The token "{link}" will be replaced by the link.
107 | * @return string the rendering result
108 | * @throws InvalidConfigException if `$link` does not have "label" element.
109 | */
110 | protected function renderItem($link, $template)
111 | {
112 | if (isset($link['label'])) {
113 | $label = $this->encodeLabels ? Html::encode($link['label']) : $link['label'];
114 | } else {
115 | throw new InvalidConfigException('The "label" element is required for each link.');
116 | }
117 |
118 | $icon = ArrayHelper::getValue($link, 'icon', '');
119 | if ($icon) {
120 | $icon = Html::tag('i', '', ['class' => 'fa ' . $icon]) . ' ';
121 | }
122 | if (isset($link['url'])) {
123 | return strtr($template, ['{link}' => $icon . Html::a($label, $link['url'])]);
124 | } else {
125 | return strtr($template, ['{link}' => $icon . $label]);
126 | }
127 | }
128 | }
--------------------------------------------------------------------------------
/widgets/Button.php:
--------------------------------------------------------------------------------
1 | 'Action',
22 | * 'icon' => 'fa fa-bookmark-o',
23 | * 'iconPosition' => Button::ICON_POSITION_LEFT,
24 | * 'size' => Button::SIZE_SMALL,
25 | * 'disabled' => false,
26 | * 'block' => false,
27 | * 'type' => Button::TYPE_M_BLUE,
28 | * ]);
29 | * ```
30 | */
31 | class Button extends \yii\bootstrap\Button {
32 |
33 | /**
34 | * Button bootstrap types
35 | */
36 | const TYPE_DEFAULT = '';
37 | const TYPE_PRIMARY = 'primary';
38 | const TYPE_INFO = 'info';
39 | const TYPE_SUCCESS = 'success';
40 | const TYPE_WARNING = 'warning';
41 | const TYPE_DANGER = 'danger';
42 | const TYPE_INVERSE = 'inverse';
43 | const TYPE_LINK = 'link';
44 | const TYPE_CIRCLE = 'circle';
45 |
46 | /**
47 | * Button sizes
48 | */
49 | const SIZE_MINI = 'xs';
50 | const SIZE_SMALL = 'sm';
51 | const SIZE_LARGE = 'lg';
52 |
53 | /**
54 | * Icon positions
55 | */
56 | const ICON_POSITION_LEFT = 'left';
57 | const ICON_POSITION_RIGHT = 'right';
58 |
59 | /**
60 | * @var string The button size.
61 | * Valid values are 'xs', 'sm', 'lg'.
62 | */
63 | public $size;
64 |
65 | /**
66 | * @var string The button type.
67 | * Valid values for metronic styles are 'default', 'red', 'blue', 'green', 'yellow', 'purple', 'dark'.
68 | * Valid values for bootstrap styles are 'primary', 'info', 'success', 'warning', 'danger', 'inverse', 'link'.
69 | */
70 | public $type = self::TYPE_DEFAULT;
71 |
72 | /**
73 | * @var string color
74 | */
75 | public $color = 'btn-default';
76 |
77 | /**
78 | * @var string The button icon.
79 | */
80 | public $icon;
81 |
82 | /**
83 | * @var string Icon position.
84 | * Valid values are 'left', 'right'.
85 | */
86 | public $iconPosition = self::ICON_POSITION_LEFT;
87 |
88 | /**
89 | * @var bool Indicates whether button is disabled or not.
90 | */
91 | public $disabled = false;
92 |
93 | /**
94 | * @var bool Indicates whether the button should span the full width of the a parent.
95 | */
96 | public $block = false;
97 |
98 | /**
99 | * @var bool Indicates whether the dropdown shoud expand on hover.
100 | */
101 | public $hover = false;
102 |
103 | /**
104 | * @var array sizes
105 | */
106 | private $_sizes = [
107 | self::SIZE_MINI,
108 | self::SIZE_SMALL,
109 | self::SIZE_LARGE,
110 | ];
111 |
112 | /**
113 | * Initializes the widget.
114 | */
115 | public function init()
116 | {
117 | parent::init();
118 |
119 | if (static::TYPE_DEFAULT !== $this->type)
120 | {
121 | Html::addCssClass($this->options, sprintf('btn-%s', $this->type));
122 | }
123 |
124 | Html::addCssClass($this->options, $this->color);
125 |
126 | if (in_array($this->size, $this->_sizes))
127 | {
128 | Html::addCssClass($this->options, 'btn-' . $this->size);
129 | }
130 |
131 | if ($this->disabled === true)
132 | {
133 | Html::addCssClass($this->options, 'disabled');
134 | }
135 |
136 | if ($this->block === true)
137 | {
138 | Html::addCssClass($this->options, 'btn-block');
139 | }
140 |
141 | $this->options['type'] = 'button';
142 | }
143 |
144 | /**
145 | * Renders the widget.
146 | */
147 | public function run()
148 | {
149 | $label = $this->encodeLabel ? Html::encode($this->label) : $this->label;
150 |
151 | if ($this->icon !== null)
152 | {
153 | $icon = Html::tag('i', '', ['class' => $this->icon]);
154 | $label = strcasecmp($this->iconPosition, self::ICON_POSITION_LEFT) === 0 ? sprintf('%s %s', $icon, $label) : sprintf('%s %s', $label, $icon);
155 | }
156 |
157 | echo Html::tag($this->tagName, $label, $this->options);
158 |
159 | $this->registerPlugin('button');
160 | }
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/widgets/ButtonDropdown.php:
--------------------------------------------------------------------------------
1 | 'Action',
23 | * 'button' => [
24 | * 'icon' => 'fa fa-bookmark-o',
25 | * 'iconPosition' => Button::ICON_POSITION_LEFT,
26 | * 'size' => Button::SIZE_SMALL,
27 | * 'disabled' => false,
28 | * 'block' => false,
29 | * 'type' => Button::TYPE_M_BLUE,
30 | * ],
31 | * 'dropdown' => [
32 | * 'items' => [
33 | * ['label' => 'DropdownA', 'url' => '/'],
34 | * ['label' => 'DropdownB', 'url' => '#'],
35 | * ],
36 | * ],
37 | * ]);
38 | * ```
39 | *
40 | * */
41 | class ButtonDropdown extends \yii\bootstrap\ButtonDropdown {
42 |
43 | /**
44 | * @var array The configuration array for [[Button]].
45 | */
46 | public $button = [];
47 |
48 | /**
49 | * @var bool Indicates whether the dropdown shoud expand on hover.
50 | */
51 | public $hover = false;
52 |
53 | /**
54 | * Inits ButtonDropdown
55 | */
56 | public function init()
57 | {
58 | parent::init();
59 |
60 | $this->options['data-toggle'] = 'dropdown';
61 |
62 | if ($this->hover === true)
63 | {
64 | $this->options['data-hover'] = 'dropdown';
65 | }
66 |
67 | if ($this->encodeLabel)
68 | {
69 | $this->label = Html::encode($this->label);
70 | }
71 |
72 | $this->options['data-close-others'] = 'true';
73 |
74 | Html::addCssClass($this->options, 'btn');
75 |
76 | Html::addCssClass($this->options, 'dropdown-toggle');
77 | }
78 |
79 | /**
80 | * Renders the widget.
81 | */
82 | public function run()
83 | {
84 | echo Html::tag('div', sprintf('%s%s', $this->renderButton(), $this->renderDropdown()), ['class' => 'btn-group']);
85 | }
86 |
87 | /**
88 | * Renders the button.
89 | * @return string the rendering result
90 | */
91 | protected function renderButton()
92 | {
93 | $label = Html::tag('span', $this->label, ['class' => 'hidden-sm hidden-xs']);
94 |
95 | if ($this->split)
96 | {
97 | $leftBtn = Button::widget($a = ArrayHelper::merge($this->button, [
98 | 'label' => $label,
99 | 'encodeLabel' => false,
100 | 'tagName' => $this->tagName,
101 | ]));
102 |
103 |
104 | $rightBtn = Button::widget(ArrayHelper::merge($this->button, [
105 | 'label' => '',
106 | 'encodeLabel' => false,
107 | 'options' => $this->options,
108 | 'tagName' => $this->tagName,
109 | ]));
110 | }
111 | else
112 | {
113 | $label .= ' ';
114 |
115 | if (!isset($this->options['href']))
116 | {
117 | $this->options['href'] = '#';
118 | }
119 |
120 | $leftBtn = Button::widget(ArrayHelper::merge($this->button, [
121 | 'label' => $label,
122 | 'encodeLabel' => false,
123 | 'options' => $this->options,
124 | 'tagName' => $this->tagName,
125 | ]));
126 |
127 | $rightBtn = '';
128 | }
129 |
130 | return sprintf('%s%s', $leftBtn, $rightBtn);
131 | }
132 |
133 | /**
134 | * Renders the dropdown
135 | * @return string the rendering result
136 | */
137 | protected function renderDropdown()
138 | {
139 | $config = $this->dropdown;
140 | $config['clientOptions'] = false;
141 | return Dropdown::widget($config);
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/widgets/ButtonGroup.php:
--------------------------------------------------------------------------------
1 | true,
21 | * 'buttons' => [
22 | * ['label' => 'A'],
23 | * ['label' => 'B'],
24 | * ]
25 | * ]);
26 | *
27 | * // a button group with an item as a string
28 | * echo ButtonGroup::widget([
29 | * 'buttons' => [
30 | * Button::widget(['label' => 'A']),
31 | * ['label' => 'B'],
32 | * ]
33 | * ]);
34 | * ```
35 | */
36 | class ButtonGroup extends \yii\bootstrap\ButtonGroup
37 | {
38 | /**
39 | * @var bool Indicates whether the button group appears vertically stacked.
40 | */
41 | public $stacked = false;
42 |
43 | /**
44 | * Initializes the widget.
45 | */
46 | public function init()
47 | {
48 | if ($this->stacked === true) {
49 | Html::addCssClass($this->options, 'btn-group-vertical');
50 | } else {
51 | Html::addCssClass($this->options, 'btn-group');
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/widgets/CheckboxList.php:
--------------------------------------------------------------------------------
1 | [
22 | * 'full_name',
23 | * [
24 | * 'name' => 'city',
25 | * 'label' => 'Location',
26 | * ]
27 | * ],
28 | * 'model' => $filterModel,
29 | * 'attribute' => 'columns',
30 | * ]);
31 | * ```
32 | */
33 | class CheckboxList extends InputWidget
34 | {
35 | /**
36 | * @var array list of checkbox items.
37 | * Each item must be either as string like the name checkbox
38 | * or as array with following special options:
39 | * - name, required, item name
40 | * - label, optional, item label
41 | * Item can not belong to the model.
42 | */
43 | public $items = [];
44 | /**
45 | * @var string the model attribute that this widget is associated with.
46 | * This model attribute contains list of checkboxes name, separated $separator value.
47 | */
48 | public $attribute;
49 | /**
50 | * @var string separator values
51 | */
52 | public $separator = ',';
53 | /**
54 | * @var array the HTML attributes for items.
55 | */
56 | public $itemOptions = [];
57 | /**
58 | * @var array items name, that will be checked.
59 | */
60 | private $_checked = [];
61 |
62 | /**
63 | * Initializes the widget.
64 | */
65 | public function init()
66 | {
67 | parent::init();
68 | $items = [];
69 | if ($this->hasModel()) {
70 | $this->_checked = array_map('trim', explode(',', $this->model->{$this->attribute}));
71 | foreach ($this->items as $item) {
72 | $input = [];
73 | if (is_string($item)) {
74 | $input['name'] = $item;
75 | $input['label'] = $this->model->getAttributeLabel($item);
76 | } else {
77 | if (!isset($item['name'])) {
78 | throw new InvalidConfigException('Option "name" is required.');
79 | }
80 | $input['name'] = $item['name'];
81 | $input['label'] = isset($item['label']) ? $item['label'] : $this->model->getAttributeLabel(
82 | $item['name']
83 | );
84 | }
85 | $items[] = $input;
86 | }
87 | } else {
88 | $this->_checked = array_map('trim', explode(',', $this->value));
89 | foreach ($this->items as $item) {
90 | $input = [];
91 | if (is_string($item)) {
92 | $input['name'] = $item;
93 | $input['label'] = Inflector::camel2words($item);
94 | } else {
95 | if (!isset($item['name'])) {
96 | throw new InvalidConfigException('Option "name" is required.');
97 | }
98 | $input['name'] = $item['name'];
99 | $input['label'] = isset($item['label']) ? $item['label'] : Inflector::camel2words($item['name']);
100 | }
101 | $items[] = $input;
102 | }
103 | }
104 |
105 | $this->items = $items;
106 | }
107 |
108 | /**
109 | * Executes the widget.
110 | */
111 | public function run()
112 | {
113 | if ($this->hasModel()) {
114 | $hiddenInput = Html::activeHiddenInput($this->model, $this->attribute);
115 | $inputId = Html::getInputId($this->model, $this->attribute);
116 | } else {
117 | $hiddenInput = Html::textInput($this->name, $this->name);
118 | $inputId = $this->name;
119 | }
120 |
121 | $items = [];
122 | usort($this->items, function($a, $b){
123 | $aKey = array_search($a['name'], $this->_checked);
124 | $bKey = array_search($b['name'], $this->_checked);
125 | if ($aKey == $bKey) {
126 | return 0;
127 | }
128 |
129 | return ($aKey > $bKey) ? 1 : -1;
130 | });
131 | Html::addCssClass($this->itemOptions, 'btn btn-xs default');
132 | foreach ($this->items as $item) {
133 | $checkbox = Html::checkbox($item['name'], in_array($item['name'], $this->_checked));
134 | $items[] = Html::tag('span', $checkbox . ' ' . $item['label'], $this->itemOptions);
135 | }
136 |
137 | echo Html::beginTag('div', $this->options);
138 | echo Sortable::widget([
139 | 'items' => $items,
140 | 'options' => ['tag' => 'div'],
141 | 'itemOptions' => ['tag' => 'span'],
142 | 'clientOptions' => ['cursor' => 'move',
143 | 'start' => new JsExpression('function(e, ui){
144 | ui.placeholder.height(ui.item.height());
145 | ui.placeholder.width(ui.item.width());
146 | }'),
147 | 'update' => new JsExpression("function(e, ui){
148 | var values = $.map($('#{$this->options['id']} input:checkbox:checked'),
149 | function(item){ return $(item).attr('name')});
150 | $('#{$inputId}').val(values.join('{$this->separator}'));
151 | }"),
152 | ],
153 | ]);
154 | echo $hiddenInput;
155 | echo Html::endTag('div');
156 | $this->registerJs($inputId);
157 | }
158 |
159 | protected function registerJs($inputId)
160 | {
161 | $this->view->registerJs("
162 | ;(function($){
163 | $('#{$this->options['id']}').on('change', 'input:checkbox', function(){
164 | var values = $.map($('#{$this->options['id']} input:checkbox:checked'),
165 | function(item){ return $(item).attr('name')});
166 | $('#{$inputId}').val(values.join('{$this->separator}'));
167 | });
168 | })(jQuery);
169 | ", View::POS_READY);
170 | }
171 | }
--------------------------------------------------------------------------------
/widgets/DatePicker.php:
--------------------------------------------------------------------------------
1 | 'ru',
24 | * 'model' => $model,
25 | * 'attribute' => 'country',
26 | * 'clientOptions' => [
27 | * 'dateFormat' => 'yy-mm-dd',
28 | * ],
29 | * ]);
30 | * ```
31 | *
32 | * The following example will use the name property instead:
33 | *
34 | * ```php
35 | * echo DatePicker::widget([
36 | * 'language' => 'ru',
37 | * 'name' => 'country',
38 | * 'clientOptions' => [
39 | * 'dateFormat' => 'yy-mm-dd',
40 | * ],
41 | * ]);
42 | * ```
43 | *
44 | * @see http://api.jqueryui.com/datepicker/
45 | * @author Alexander Kochetov
46 | * @since 2.0
47 | */
48 | class DatePicker extends InputWidget {
49 |
50 | /**
51 | * @var string the locale ID (eg 'fr', 'de') for the language to be used by the date picker.
52 | * If this property set to false, I18N will not be involved. That is, the date picker will show in English.
53 | */
54 | public $language = false;
55 |
56 | /**
57 | * @var boolean If true, shows the widget as an inline calendar and the input as a hidden field.
58 | */
59 | public $inline = false;
60 |
61 | /**
62 | * @var array the HTML attributes for the container tag. This is only used when [[inline]] is true.
63 | */
64 | public $containerOptions = [];
65 |
66 | /**
67 | * Initializes the widget.
68 | */
69 | public function init()
70 | {
71 | parent::init();
72 | if ($this->inline && !isset($this->containerOptions['id']))
73 | {
74 | $this->containerOptions['id'] = $this->options['id'] . '-container';
75 | }
76 | else
77 | {
78 | Html::addCssClass($this->options, 'form-control form-control-inline');
79 | }
80 | }
81 |
82 | /**
83 | * Renders the widget.
84 | */
85 | public function run()
86 | {
87 | $contents = [];
88 | if ($this->inline)
89 | {
90 | if ($this->hasModel())
91 | {
92 | $contents[] = Html::activeHiddenInput($this->model, $this->attribute, $this->options);
93 | }
94 | else
95 | {
96 | $contents[] = Html::hiddenInput($this->name, $this->value, $this->options);
97 | }
98 | $contents[] = Html::tag('div', '', $this->containerOptions);
99 | }
100 | else
101 | {
102 | if ($this->hasModel())
103 | {
104 | $contents[] = Html::activeTextInput($this->model, $this->attribute, $this->options);
105 | }
106 | else
107 | {
108 | $contents[] = Html::textInput($this->name, $this->value, $this->options);
109 | }
110 | }
111 | echo implode("\n", $contents);
112 | if ($this->language)
113 | {
114 | DatePickerAsset::$extraJs[] = 'plugins/bootstrap-datepicker-extended/js/locales/bootstrap-datepicker.' . $this->language . '.js';
115 | $this->clientOptions['language'] = $this->language;
116 | }
117 | DatePickerAsset::register($this->view);
118 | $this->registerPlugin('datepicker');
119 | if ($this->inline)
120 | {
121 | $this->view->registerJs("
122 | !(function($){
123 | var el = $('#{$this->options['id']}'),
124 | val = el.val(),
125 | container = $('#{$this->containerOptions['id']}');
126 | container.on('changeDate', function(e){
127 | el.val(e.format());
128 | });
129 | if(val) {
130 | container.datepicker('update', new Date(Date.parse(val)));
131 | }
132 | })(jQuery);
133 | ", View::POS_READY);
134 | }
135 | }
136 |
137 | /**
138 | * Registers a specific Bootstrap plugin and the related events
139 | * @param string $name the name of the Bootstrap plugin
140 | */
141 | protected function registerPlugin($name)
142 | {
143 | $view = $this->getView();
144 | $id = $this->inline ? $this->containerOptions['id'] : $this->options['id'];
145 | if ($this->clientOptions !== false)
146 | {
147 | $options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions);
148 | $js = "jQuery('#$id').$name($options);";
149 | $view->registerJs($js);
150 | }
151 | if (!empty($this->clientEvents))
152 | {
153 | $js = [];
154 | foreach ($this->clientEvents as $event => $handler)
155 | {
156 | $js[] = "jQuery('#$id').on('$event', $handler);";
157 | }
158 | $view->registerJs(implode("\n", $js));
159 | }
160 | }
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/widgets/Decorator.php:
--------------------------------------------------------------------------------
1 | $model,
26 | * 'attributes' => [
27 | * 'title', // title attribute (in plain text)
28 | * 'description:html', // description attribute in HTML
29 | * [ // the owner name of the model
30 | * 'label' => 'Owner',
31 | * 'value' => $model->owner->name,
32 | * ],
33 | * ],
34 | * ]);
35 | * ~~~
36 | */
37 | class DetailView extends \yii\widgets\DetailView
38 | {
39 | /**
40 | * @var string|callback the template used to render a single attribute. If a string, the token `{label}`
41 | * and `{value}` will be replaced with the label and the value of the corresponding attribute.
42 | * If a callback (e.g. an anonymous function), the signature must be as follows:
43 | *
44 | * ~~~
45 | * function ($attribute, $index, $widget)
46 | * ~~~
47 | *
48 | * where `$attribute` refer to the specification of the attribute being rendered, `$index` is the zero-based
49 | * index of the attribute in the [[attributes]] array, and `$widget` refers to this widget instance.
50 | */
51 | public $template = '
52 |
{label}
53 |
{value}
54 |
';
55 | }
56 |
--------------------------------------------------------------------------------
/widgets/DraggablePortlets.php:
--------------------------------------------------------------------------------
1 | view);
46 | echo Html::beginTag('div', ['class' => "row {$this->cssRowClasses}", 'id' => 'sortable_portlets']);
47 | $this->renderColumns();
48 | echo Html::endTag('div');
49 | }
50 |
51 | private function renderColumns(){
52 | foreach ($this->columns as $aColumn){
53 | if (!array_key_exists('items', $aColumn)) {
54 | throw new InvalidConfigException(
55 | "The 'items' option is required."
56 | );
57 | }
58 |
59 | echo Html::beginTag('div', ['class' => 'col-md-4 column sortable']);
60 |
61 | $options = [];
62 | if (array_key_exists('tools', $aColumn)){
63 | $options['tools'] = $aColumn['tools'];
64 | }
65 |
66 | $this->renderItems($aColumn['items'], $options);
67 | if (!(array_key_exists('appendEmptyLastElement', $aColumn) && $aColumn['appendEmptyLastElement'] === false) ){
68 | $this->renderEmptyPortlet();
69 | }
70 | echo Html::endTag('div');
71 | }
72 | }
73 |
74 | private function renderItems($items, $options){
75 | foreach ($items as $key => $item) {
76 | if (!ArrayHelper::remove($item, 'visible', true)) {
77 | continue;
78 | }
79 |
80 | if (!is_string($key) && !array_key_exists('itemTitle', $item)) {
81 | throw new InvalidConfigException(
82 | "The 'itemTitle' option is required."
83 | );
84 | }
85 | if (is_string($item)) {
86 | $item = ['content' => $item];
87 | }
88 |
89 | Portlet::begin(array_merge([
90 | 'title' => $item['itemTitle'],
91 | 'options' => [
92 | 'class' => 'portlet-sortable',
93 | ],
94 | 'headerOptions' => [
95 | 'class' => 'ui-sortable-handle',
96 | ],
97 | ], $options));
98 |
99 | Portlet::end();
100 | }
101 | }
102 |
103 | private function renderEmptyPortlet(){
104 | echo Html::tag('div', '', ['class' => 'portlet portlet-sortable-empty']);
105 | }
106 |
107 |
108 | }
--------------------------------------------------------------------------------
/widgets/DropZone.php:
--------------------------------------------------------------------------------
1 | options['url'])){
36 | $this->options['url'] = $this->uploadUrl; // Set the url
37 | }
38 |
39 | // Define the element that should be used as click trigger to select files.
40 | if (!isset($this->options['previewsContainer'])){
41 | $this->options['previewsContainer'] = '#' . $this->previewsContainer;
42 | }
43 |
44 | // Define the element that should be used as click trigger to select files.
45 | if (!isset($this->options['clickable'])){
46 | $this->options['clickable'] = true;
47 | }
48 |
49 | if (!isset($this->options['cssClasses'])){
50 | $this->options['cssClasses'] = 'dropzone';
51 | }
52 |
53 | $this->autoDiscover = $this->autoDiscover===false ? 'false' : 'true';
54 |
55 | if(\Yii::$app->getRequest()->enableCsrfValidation){
56 | $this->options['headers'][\yii\web\Request::CSRF_HEADER] = \Yii::$app->getRequest()->getCsrfToken();
57 | $this->options['params'][\Yii::$app->getRequest()->csrfParam] = \Yii::$app->getRequest()->getCsrfToken();
58 | }
59 | $this->registerAssets();
60 | }
61 |
62 | public function run()
63 | {
64 | return Html::tag('div', $this->renderDropzone(), ['id' => $this->dropzoneContainer, 'class' => $this->options['cssClasses']]);
65 | }
66 |
67 | private function renderDropzone()
68 | {
69 | $data = Html::tag('div', '', ['id' => $this->previewsContainer,'class' => 'dropzone-previews']);
70 | return $data;
71 | }
72 |
73 | /**
74 | * Registers the needed assets
75 | */
76 | public function registerAssets()
77 | {
78 | $view = $this->getView();
79 | $js = 'Dropzone.autoDiscover = ' . $this->autoDiscover . '; var ' . $this->id . ' = new Dropzone("div#' . $this->dropzoneContainer . '", ' . Json::encode($this->options) . ');';
80 | if (!empty($this->clientEvents)) {
81 | foreach ($this->clientEvents as $event => $handler) {
82 | $js .= "$this->id.on('$event', $handler);";
83 | }
84 | }
85 | $view->registerJs($js);
86 | DropZoneAsset::register($view);
87 | }
88 | }
--------------------------------------------------------------------------------
/widgets/Dropdown.php:
--------------------------------------------------------------------------------
1 | 'Dropdown title',
22 | * 'more' => ['label' => 'xxx', 'url' => '/', 'icon' => 'm-icon-swapright'],
23 | * 'scroller' => ['height' => 200],
24 | * 'items' => [
25 | * ['label' => 'Level 1 - Dropdown A', 'url' => '#'],
26 | * '',
27 | * '',
28 | * ['label' => 'Level 1 - Dropdown B', 'url' => '#'],
29 | * ],
30 | * ]);
31 | *
32 | */
33 | class Dropdown extends \yii\bootstrap\Dropdown
34 | {
35 |
36 | public const LINK_TYPE_LINK = 'a';
37 |
38 | public const LINK_TYPE_CHECKBOX = 'checkbox';
39 |
40 | /**
41 | * @var string the dropdown title
42 | */
43 | public $title;
44 |
45 | /**
46 | * @var array the dropdown last item options
47 | * with the following structure:
48 | * ```php
49 | * [
50 | * // optional, item label
51 | * 'label' => 'Show all messages',
52 | * // optional, item icon
53 | * 'icon' => 'm-icon-swapright',
54 | * // optional, item url
55 | * 'url' => '/',
56 | * ]
57 | * ```
58 | */
59 | public $more = [];
60 |
61 | /**
62 | * @var array the dropdown item options
63 | * is an array of the following structure:
64 | * ```php
65 | * [
66 | * // required, height of the body portlet as a px
67 | * 'height' => 150,
68 | * // optional, HTML attributes of the scroller
69 | * 'options' => [],
70 | * // optional, footer of the scroller. May contain string or array(the
71 | * options of Link component)
72 | * 'footer' => [
73 | * 'label' => 'Show all',
74 | * ],
75 | * ]
76 | * ```
77 | */
78 | public $scroller = [];
79 |
80 | /**
81 | * @var bool if we should use pull-right menu
82 | */
83 | public $pullRight = false;
84 |
85 | /**
86 | * @var bool if this is a drop-up
87 | */
88 | public $dropUp = false;
89 |
90 | public function init()
91 | {
92 |
93 | Html::addCssClass($this->options, 'dropdown-menu-list');
94 | if ($this->dropUp) {
95 | Html::addCssClass($this->options, 'bottom-up');
96 | }
97 | if ($this->pullRight) {
98 | Html::addCssClass($this->options, 'pull-right');
99 | }
100 | if (count($this->scroller) > 0) {
101 | Html::addCssClass($this->options, 'scroller');
102 | }
103 |
104 | parent::init();
105 | }
106 |
107 | /**
108 | * Executes the widget.
109 | */
110 | public function run()
111 | {
112 |
113 | echo $this->renderItems($this->items);
114 | }
115 |
116 | /**
117 | * Renders menu items.
118 | *
119 | * @param array $items the menu items to be rendered
120 | *
121 | * @return string the rendering result.
122 | * @throws InvalidConfigException if the label option is not specified in
123 | * one of the items.
124 | */
125 | protected function renderItems($items, $options = [])
126 | {
127 | $lines = [];
128 | if ($this->title) {
129 | $lines[] = Html::tag('li', Html::tag('p', $this->title));
130 | }
131 |
132 | if (!empty($this->scroller)) {
133 | if (!isset($this->scroller['height'])) {
134 | throw new InvalidConfigException("The 'height' option of Scroller is required.");
135 | }
136 | $lines[] = Html::beginTag('li');
137 | $lines[] = Html::beginTag('ul', [
138 | 'style' => 'height: ' . $this->scroller['height'] . 'px;',
139 | 'class' => $this->options['class'],
140 | ]
141 | );
142 | }
143 |
144 | foreach ($items as $i => $item) {
145 | if (isset($item['visible']) && !$item['visible']) {
146 | unset($items[$i]);
147 | continue;
148 | }
149 | if (is_string($item)) {
150 | $lines[] = $item;
151 | continue;
152 | }
153 |
154 | if (in_array('divider', $item)) {
155 | $lines[] = Html::tag('li', '', ['class' => 'divider']);
156 | continue;
157 | }
158 |
159 | if (!isset($item['label'])) {
160 | throw new InvalidConfigException("The 'label' option is required.");
161 | }
162 | $label = $this->encodeLabels ? Html::encode($item['label']) : $item['label'];
163 |
164 | $icon = ArrayHelper::getValue($item, 'icon', null);
165 | if ($icon) {
166 | $label = Html::tag('i', '',
167 | ['alt' => $label, 'class' => $icon]) . ' ' . $label;
168 | }
169 | $label .= ArrayHelper::getValue($item, 'badge', '');
170 | $options = ArrayHelper::getValue($item, 'options', []);
171 | $linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);
172 | $linkOptions['tabindex'] = '-1';
173 |
174 | if (ArrayHelper::getValue($item, 'linkType',
175 | self::LINK_TYPE_LINK) == self::LINK_TYPE_LINK) {
176 | $content = Html::a($label,
177 | ArrayHelper::getValue($item, 'url', '#'), $linkOptions);
178 | } else {
179 | $content = Html::checkbox($label, true, $linkOptions);
180 | }
181 | $lines[] = Html::tag('li', $content, $options);
182 | }
183 |
184 | if (!empty($this->scroller)) {
185 | $lines[] = Html::endTag('ul');
186 | $lines[] = Html::endTag('li');
187 | }
188 |
189 | if (!empty($this->more)) {
190 | $url = ArrayHelper::getValue($this->more, 'url', '#');
191 | $text = ArrayHelper::getValue($this->more, 'label', '');
192 | $icon = ArrayHelper::getValue($this->more, 'icon', '');
193 | if ($icon) {
194 | $icon = Html::tag('i', '', ['class' => $icon]);
195 | }
196 | $lines[] = Html::tag('li',
197 | Html::tag('a', $text . $icon, ['href' => $url]),
198 | ['class' => 'external']);
199 | }
200 |
201 | return Html::tag('ul', implode("\n", $lines), $this->options);
202 | }
203 |
204 | }
205 |
--------------------------------------------------------------------------------
/widgets/DropdownContent.php:
--------------------------------------------------------------------------------
1 | 'Action',
21 | * 'dropdown' => 'Content',
22 | * ]);
23 | * ```
24 | */
25 | class DropdownContent extends ButtonDropdown
26 | {
27 | /**
28 | * @var string the button label
29 | */
30 | public $label = 'Button';
31 | /**
32 | * @var array the HTML attributes of the button.
33 | * @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
34 | */
35 | public $options = [];
36 | /**
37 | * @var string the dropdown content.
38 | */
39 | public $dropdown = '';
40 |
41 | /**
42 | * Executes the widget.
43 | */
44 | public function run()
45 | {
46 | echo Html::beginTag('div', ['class' => 'btn-group']);
47 | echo $this->renderButton() . "\n" . $this->renderDropdown();
48 | echo Html::endTag('div');
49 |
50 | $this->registerPlugin('button');
51 |
52 | }
53 |
54 | /**
55 | * Generates the button dropdown.
56 | * @return string the rendering result.
57 | */
58 | protected function renderButton()
59 | {
60 | Html::addCssClass($this->options, 'btn');
61 | $label = $this->label;
62 | if ($this->encodeLabel) {
63 | $label = Html::encode($label);
64 | }
65 | if ($this->split) {
66 | $options = $this->options;
67 | $this->options['data-toggle'] = 'dropdown';
68 | Html::addCssClass($this->options, 'dropdown-toggle');
69 | $splitButton = BButton::widget([
70 | 'label' => '',
71 | 'encodeLabel' => false,
72 | 'options' => $this->options,
73 | 'view' => $this->getView(),
74 | ]);
75 | } else {
76 | $label .= ' ';
77 | $options = $this->options;
78 | if (!isset($options['href'])) {
79 | $options['href'] = '#';
80 | }
81 | Html::addCssClass($options, 'dropdown-toggle');
82 | $options['data-toggle'] = 'dropdown';
83 | $splitButton = '';
84 | }
85 |
86 | return BButton::widget([
87 | 'tagName' => $this->tagName,
88 | 'label' => $label,
89 | 'options' => $options,
90 | 'encodeLabel' => false,
91 | 'view' => $this->getView(),
92 | ]) . "\n" . $splitButton;
93 | }
94 |
95 | /**
96 | * Gets dropdown content.
97 | * @return string the rendering result.
98 | */
99 | protected function renderDropdown()
100 | {
101 | return Html::tag('div', $this->dropdown, ['class' => 'dropdown-menu']);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/widgets/GridView.php:
--------------------------------------------------------------------------------
1 | {summary}
\n{pager}
";
21 |
22 | /**
23 | * @var boolean indicates if grid is sortable
24 | */
25 | public $sortable = false;
26 |
27 | /**
28 | * Inits widget
29 | */
30 | public function init()
31 | {
32 | parent::init();
33 |
34 | $this->initPager();
35 |
36 | $this->initVisible();
37 |
38 | $this->initSortable();
39 |
40 | //GridViewAsset::register($this->view);
41 | }
42 |
43 | /**
44 | * Renders the data models for the grid view.
45 | */
46 | public function renderItems()
47 | {
48 | /*
49 | $content = array_filter([
50 | $this->renderCaption(),
51 | $this->renderColumnGroup(),
52 | $this->showHeader ? $this->renderTableHeader() : false,
53 | $this->showFooter ? $this->renderTableFooter() : false,
54 | $this->renderTableBody(),
55 | ]);
56 |
57 | $table = Html::tag('table', implode("\n", $content), $this->tableOptions);
58 | if ($this->responsive)
59 | {
60 | $table = Html::tag('div', $table, ['class' => 'table-responsive']);
61 | }
62 | else
63 | {
64 | $table = Html::tag('div', $table, ['class' => 'table-scrollable']);
65 | }
66 |
67 | return $table;
68 | *
69 | */
70 | return parent::renderItems();
71 | }
72 |
73 | /**
74 | * Inits pager
75 | */
76 | protected function initPager()
77 | {
78 | $this->pager['firstPageLabel'] = Html::tag('i', '', [
79 | 'class' => 'fa fa-angle-double-left',
80 | ]);
81 |
82 | $this->pager['lastPageLabel'] = Html::tag('i', '', [
83 | 'class' => 'fa fa-angle-double-right',
84 | ]);
85 |
86 | $this->pager['prevPageLabel'] = Html::tag('i', '', [
87 | 'class' => 'fa fa-angle-left',
88 | ]);
89 |
90 | $this->pager['nextPageLabel'] = Html::tag('i', '', [
91 | 'class' => 'fa fa-angle-right',
92 | ]);
93 | }
94 |
95 | protected function initVisible()
96 | {
97 | $columns = $this->getStorageColumns();
98 | if (empty($columns))
99 | {
100 | return;
101 | }
102 | foreach ($this->columns as $i => $column)
103 | {
104 | if (array_search($i, $columns) === false)
105 | {
106 | unset($this->columns[$i]);
107 | }
108 | }
109 | }
110 |
111 | /**
112 | * Inits sortable behavior on gridview
113 | */
114 | protected function initSortable()
115 | {
116 | $route = ArrayHelper::getValue($this->sortable, 'url', false);
117 |
118 | if ($route)
119 | {
120 | $url = Url::toRoute($route);
121 |
122 | $options = json_encode(ArrayHelper::getValue($this->sortable, 'options', []));
123 |
124 | $view = $this->getView();
125 | $view->registerJs("jQuery('#{$this->id}').SortableGridView('{$url}', {$options});");
126 | GridViewSortableAsset::register($view);
127 | }
128 | }
129 |
130 | protected function getStorageColumns()
131 | {
132 | return [];
133 | }
134 | }
--------------------------------------------------------------------------------
/widgets/InputWidget.php:
--------------------------------------------------------------------------------
1 | hasModel() && $this->name === null) {
41 | throw new InvalidConfigException("Either 'name', or 'model' and 'attribute' properties must be specified.");
42 | }
43 | if (!isset($this->options['id'])) {
44 | $this->options['id'] = $this->hasModel() ? Html::getInputId($this->model, $this->attribute) : $this->getId();
45 | }
46 | parent::init();
47 | }
48 |
49 | /**
50 | * @return boolean whether this widget is associated with a data model.
51 | */
52 | protected function hasModel()
53 | {
54 | return $this->model instanceof Model && $this->attribute !== null;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/widgets/IonRangeSlider.php:
--------------------------------------------------------------------------------
1 | 'ionRangeSlider',
23 | * 'clientOptions' => [
24 | * 'min' => 0,
25 | * 'max' => 5000,
26 | * 'from' => 1000, // default value
27 | * 'to' => 4000, // default value
28 | * 'type' => 'double',
29 | * 'step' => 1,
30 | * 'prefix' => "$",
31 | * 'prettify' => false,
32 | * 'hasGrid' => true
33 | * ],
34 | * ]);
35 | * ```
36 | * @see https://github.com/IonDen/ion.rangeSlider
37 | */
38 | class IonRangeSlider extends InputWidget {
39 |
40 | /**
41 | * Types
42 | */
43 | const TYPE_SINGLE = 'single';
44 | const TYPE_DOUBLE = 'double';
45 | /**
46 | * @var string separator values
47 | */
48 | public $separator = ';';
49 |
50 | /**
51 | * Executes the widget.
52 | */
53 | public function run()
54 | {
55 | if ($this->hasModel())
56 | {
57 | $values = explode($this->separator, $this->model->{$this->attribute});
58 | if (count($values) == 2)
59 | {
60 | $this->clientOptions['from'] = (int) $values[0];
61 | $this->clientOptions['to'] = (int) $values[1];
62 | }
63 | echo Html::activeTextInput($this->model, $this->attribute, $this->options);
64 | }
65 | else
66 | {
67 | $values = explode($this->separator, $this->value);
68 | if (count($values) == 2)
69 | {
70 | $this->clientOptions['from'] = (int) $values[0];
71 | $this->clientOptions['to'] = (int) $values[1];
72 | }
73 | echo Html::textInput($this->name, $this->value, $this->options);
74 | }
75 | IonRangeSliderAsset::register($this->view);
76 | $this->registerPlugin('ionRangeSlider');
77 | }
78 |
79 | }
80 |
--------------------------------------------------------------------------------
/widgets/Link.php:
--------------------------------------------------------------------------------
1 | 'Link',
21 | * 'url' => 'http://yii2metronic.icron.org/',
22 | * 'icon' => 'm-icon-swapright m-icon-gray',
23 | * 'iconPosition' => Link::ICON_POSITION_LEFT,
24 | * ]);
25 | * ```
26 | */
27 | class Link extends Widget {
28 |
29 | // Icon position
30 | const ICON_POSITION_LEFT = 'left';
31 | const ICON_POSITION_RIGHT = 'right';
32 |
33 | /**
34 | * @var string The button label
35 | */
36 | public $label;
37 |
38 | /**
39 | * @var bool Whether the label should be HTML-encoded
40 | */
41 | public $encodeLabel = true;
42 |
43 | /**
44 | * @var string The link url
45 | */
46 | public $url = '#';
47 |
48 | /**
49 | * @var string The button icon
50 | */
51 | public $icon = 'm-icon-swapright m-icon-gray';
52 |
53 | /**
54 | * @var string Icon position
55 | * Valid values are 'left', 'right'
56 | */
57 | public $iconPosition = self::ICON_POSITION_RIGHT;
58 |
59 | /**
60 | * Label options
61 | */
62 | public $labelOptions = [];
63 |
64 | /**
65 | * Initializes the widget.
66 | * @throws InvalidConfigException
67 | */
68 | public function init()
69 | {
70 | if ($this->label === null)
71 | {
72 | throw new InvalidConfigException("The 'label' option is required.");
73 | }
74 |
75 | if ($this->url === null)
76 | {
77 | $this->url = '#';
78 | }
79 | }
80 |
81 | /**
82 | * Renders the widget.
83 | */
84 | public function run()
85 | {
86 | $icon = ($this->icon === null) ? '' : Html::tag('i', '', ['class' => $this->icon]);
87 | $label = Html::tag('span', Html::encode($this->label), $this->labelOptions);
88 |
89 | if (strcasecmp($this->iconPosition, self::ICON_POSITION_LEFT) === 0)
90 | {
91 | $content = sprintf('%s %s', $icon, $label);
92 | }
93 | else
94 | {
95 | $content = sprintf('%s %s', $label, $icon);
96 | }
97 | echo Html::a($content, $this->url, $this->options);
98 | }
99 |
100 | }
101 |
--------------------------------------------------------------------------------
/widgets/ListView.php:
--------------------------------------------------------------------------------
1 | initSortable();
36 | }
37 |
38 | /**
39 | * Inits sortable behavior
40 | */
41 | protected function initSortable()
42 | {
43 | $route = ArrayHelper::getValue($this->sortable, 'url', false);
44 |
45 | if ($route)
46 | {
47 | $url = Url::toRoute($route);
48 |
49 | if (ArrayHelper::keyExists('class', $this->itemOptions))
50 | {
51 | $this->itemOptions['class'] = sprintf('%s %s', $this->itemOptions['class'], self::SORTABLE_ITEM_CLASS);
52 | }
53 | else
54 | {
55 | $this->itemOptions['class'] = self::SORTABLE_ITEM_CLASS;
56 | }
57 |
58 | $options = json_encode(ArrayHelper::getValue($this->sortable, 'options', []));
59 |
60 | $view = $this->getView();
61 | $view->registerJs("jQuery('#{$this->id}').SortableListView('{$url}', {$options});");
62 |
63 | $reload = ArrayHelper::getValue($this->sortable, 'reload', false);
64 |
65 | if ($reload)
66 | {
67 | $view->registerJs("jQuery('#{$this->id}').on('sortableSuccess', $reload)", \yii\web\View::POS_END);
68 | }
69 |
70 | ListViewSortableAsset::register($view);
71 | }
72 | }
73 | }
--------------------------------------------------------------------------------
/widgets/MultiSelect.php:
--------------------------------------------------------------------------------
1 | 'select1',
19 | * 'data' => ['1' => 'Item 1', '2' => 'Item 2'],
20 | * ]);
21 | * ```
22 | *
23 | * @see http://loudev.com/
24 | */
25 | class MultiSelect extends InputWidget
26 | {
27 | /**
28 | * @var bool indicates whether the multiSelect is disabled or not.
29 | */
30 | public $disabled;
31 | /**
32 | * @var array the option data items. The array keys are option values, and the array values
33 | * are the corresponding option labels. The array can also be nested (i.e. some array values are arrays too).
34 | * For each sub-array, an option group will be generated whose label is the key associated with the sub-array.
35 | * If you have a list of data models, you may convert them into the format described above using
36 | * [[\yii\helpers\ArrayHelper::map()]].
37 | */
38 | public $data = [];
39 |
40 | /**
41 | * Initializes the widget.
42 | */
43 | public function init()
44 | {
45 | parent::init();
46 | $this->options['multiple'] = true;
47 | if ($this->disabled) {
48 | $this->options['disabled'] = true;
49 | }
50 | Html::addCssClass($this->options, 'multi-select');
51 | }
52 | /**
53 | * Executes the widget.
54 | */
55 | public function run()
56 | {
57 | if ($this->hasModel()) {
58 | echo Html::activeDropDownList($this->model, $this->attribute, $this->data, $this->options, true);
59 | } else {
60 | echo Html::dropDownList($this->name, $this->value, $this->data, $this->options, true);
61 | }
62 | MultiSelectAsset::register($this->view);
63 | $this->registerPlugin('multiSelect');
64 | }
65 |
66 |
67 | }
--------------------------------------------------------------------------------
/widgets/Nav.php:
--------------------------------------------------------------------------------
1 | [
24 | * [
25 | * 'icon' => 'fa fa-warning',
26 | * 'badge' => Badge::widget(['label' => 'New', 'round' => false]),
27 | * 'label' => 'Home',
28 | * 'url' => ['site/index'],
29 | * 'linkOptions' => [...],
30 | * ],
31 | * [
32 | * 'label' => 'Dropdown',
33 | * 'items' => [
34 | * ['label' => 'Level 1 - Dropdown A', 'url' => '#'],
35 | * '',
36 | * '',
37 | * ['label' => 'Level 1 - Dropdown B', 'url' => '#'],
38 | * ],
39 | * ],
40 | * ],
41 | * ]);
42 | * ```
43 | *
44 | * Note: Multilevel dropdowns beyond Level 1 are not supported in Bootstrap 3.
45 | */
46 | class Nav extends \yii\bootstrap\Nav {
47 |
48 | /**
49 | * Positions
50 | */
51 | const POS_DEFAULT = '';
52 | const POS_LEFT = 'pull-left';
53 | const POS_RIGHT = 'pull-right';
54 |
55 | /**
56 | * Types
57 | */
58 | const TYPE_DEFAULT = '';
59 | const TYPE_NOTIFICATION = 'notification';
60 | const TYPE_INBOX = 'inbox';
61 | const TYPE_TASKS = 'tasks';
62 | const TYPE_USER = 'user';
63 |
64 | /**
65 | * Navbars
66 | */
67 | const NAVBAR_DEFAULT = 'navbar-nav';
68 | const NAVBAR_NONE = '';
69 |
70 | /**
71 | * Items
72 | */
73 | const ITEM_DIVIDER = 'divider';
74 |
75 | /**
76 | * Tags
77 | */
78 | const TAG_LINK = 'a';
79 |
80 | /**
81 | * @var array list of items in the nav widget. Each array element represents a single
82 | * menu item which can be either a string or an array with the following structure:
83 | *
84 | * - label: string, required, the nav item label.
85 | * - icon: string, optional, the nav item icon.
86 | * - badge: array, optional
87 | * - url: optional, the item's URL. Defaults to "#".
88 | * - visible: boolean, optional, whether this menu item is visible. Defaults to true.
89 | * - linkOptions: array, optional, the HTML attributes of the item's link.
90 | * - options: array, optional, the HTML attributes of the item container (LI).
91 | * - active: boolean, optional, whether the item should be on active state or not.
92 | * - items: array|string, optional, the configuration array for creating a [[Dropdown]] widget,
93 | * or a string representing the dropdown menu. Note that Bootstrap does not support sub-dropdown menus.
94 | *
95 | * If a menu item is a string, it will be rendered directly without HTML encoding.
96 | */
97 | public $items = [];
98 |
99 | /**
100 | * @var string the nav position
101 | */
102 | public $position = self::POS_DEFAULT;
103 |
104 | /**
105 | * @var string dropdownType
106 | */
107 | public $dropdownType = self::TYPE_DEFAULT;
108 |
109 | /**
110 | * @var string navbar holder
111 | */
112 | public $navbar = self::NAVBAR_DEFAULT;
113 |
114 | /**
115 | * Initializes the widget.
116 | */
117 | public function init()
118 | {
119 | Html::addCssClass($this->options, $this->navbar);
120 | Html::addCssClass($this->options, $this->position);
121 | parent::init();
122 | }
123 |
124 | /**
125 | * Renders a widget's item.
126 | * @param string|array $item the item to render.
127 | * @return string the rendering result.
128 | * @throws InvalidConfigException
129 | */
130 | public function renderItem($item)
131 | {
132 | if (is_string($item))
133 | {
134 | return $item;
135 | }
136 |
137 | if (in_array(self::ITEM_DIVIDER, $item, true))
138 | {
139 | return Html::tag('li', '', ['class' => self::ITEM_DIVIDER]);
140 | }
141 |
142 | $items = ArrayHelper::getValue($item, 'items');
143 |
144 | if ($items === null)
145 | {
146 | return parent::renderItem($item);
147 | }
148 |
149 | if (!isset($item['label']) && !isset($item['icon']))
150 | {
151 | throw new InvalidConfigException("The 'label' option is required.");
152 | }
153 |
154 | $dropdownType = ArrayHelper::getValue($item, 'dropdownType', self::TYPE_DEFAULT);
155 | $options = ArrayHelper::getValue($item, 'options', []);
156 |
157 | Html::addCssClass($options, 'dropdown');
158 |
159 | if ($dropdownType !== self::TYPE_DEFAULT)
160 | {
161 | if ($dropdownType !== self::TYPE_USER)
162 | {
163 | Html::addCssClass($options, 'dropdown-extended');
164 | }
165 |
166 | Html::addCssClass($options, 'dropdown-'.$dropdownType);
167 |
168 | if (Metronic::getComponent() && Metronic::HEADER_DROPDOWN_DARK === Metronic::getComponent()->headerDropdown)
169 | {
170 | Html::addCssClass($options, 'dropdown-dark');
171 | }
172 | }
173 |
174 | if (isset($item['active']))
175 | {
176 | $active = ArrayHelper::remove($item, 'active', false);
177 | }
178 | else
179 | {
180 | $active = $this->isItemActive($item);
181 | }
182 |
183 | if ($active)
184 | {
185 | Html::addCssClass($options, 'active');
186 | }
187 |
188 | return Html::tag('li', sprintf('%s%s', $this->_getLinkTag($item), $this->_getDropdownTag($item)), $options);
189 | }
190 |
191 | /**
192 | * Retrieves link tag
193 | * @param array $item given item
194 | * @return string link
195 | */
196 | private function _getLinkTag($item)
197 | {
198 | $dropdownType = ArrayHelper::getValue($item, 'dropdownType', self::TYPE_DEFAULT);
199 |
200 | if ($dropdownType !== self::TYPE_DEFAULT)
201 | {
202 | $label = $item['label'];
203 | }
204 | else
205 | {
206 | $label = $this->encodeLabels ? Html::encode($item['label']) : $item['label'];
207 | }
208 |
209 | $icon = ArrayHelper::getValue($item, 'icon', null);
210 |
211 | if ($icon)
212 | {
213 | $label = Html::tag('i', '', ['alt' => $label, 'class' => $icon]);
214 | }
215 |
216 | $label .= ArrayHelper::getValue($item, 'badge', '');
217 |
218 | $linkOptions = ArrayHelper::getValue($item, 'linkOptions', []);
219 |
220 | $linkOptions['data-toggle'] = 'dropdown';
221 | $linkOptions['data-hover'] = 'dropdown';
222 | $linkOptions['data-close-others'] = 'true';
223 |
224 | Html::addCssClass($linkOptions, 'dropdown-toggle');
225 |
226 | $tag = ArrayHelper::getValue($item, 'tag', 'a');
227 |
228 | $url = ArrayHelper::getValue($item, 'url', false);
229 |
230 | if (!$url)
231 | {
232 | if (self::TAG_LINK == $tag)
233 | {
234 | $linkOptions['href'] = 'javascript:;';
235 | }
236 |
237 | return Html::tag($tag, $label, $linkOptions);
238 | }
239 |
240 | if (self::TAG_LINK == $tag)
241 | {
242 | $linkOptions['href'] = Url::toRoute(ArrayHelper::getValue($item, 'url', '#'));
243 | }
244 |
245 | return Html::tag($tag, $label, $linkOptions);
246 | }
247 |
248 | /**
249 | * Retrieves items tag
250 | * @param array $item given parent item
251 | * @return Dropdown widget
252 | */
253 | private function _getDropdownTag($item)
254 | {
255 | $dropdownType = ArrayHelper::getValue($item, 'dropdownType', self::TYPE_DEFAULT);
256 |
257 | $items = ArrayHelper::getValue($item, 'items', null);
258 |
259 | if ($items !== null && is_array($items))
260 | {
261 | if ($dropdownType === self::TYPE_DEFAULT || $dropdownType === self::TYPE_USER)
262 | {
263 | $options = ['class' => 'dropdown-menu-default'];
264 | }
265 | else
266 | {
267 | $options = ['class' => sprintf('%s %s', 'dropdown-menu-default extended', $dropdownType)];
268 | }
269 |
270 | if ($this->activateItems)
271 | {
272 | $items = $this->isChildActive($items, $active);
273 | }
274 |
275 | $items = Dropdown::widget([
276 | 'title' => ArrayHelper::getValue($item, 'title', ''),
277 | 'more' => ArrayHelper::getValue($item, 'more', []),
278 | 'scroller' => ArrayHelper::getValue($item, 'scroller', []),
279 | 'items' => $items,
280 | 'encodeLabels' => $this->encodeLabels,
281 | 'clientOptions' => false,
282 | 'options' => $options,
283 | ]);
284 | }
285 |
286 | return $items;
287 | }
288 |
289 | /**
290 | * Renders user item.
291 | * @param $label string User label
292 | * @param $photo string User photo url
293 | * @return string the rendering result
294 | */
295 | public static function userItem($label, $photo)
296 | {
297 | $lines = [];
298 | $lines[] = Html::tag('span', $label, ['class' => 'username username-hide-on-mobile']);
299 | $lines[] = Html::img($photo, ['alt' => $label, 'class' => 'img-circle']);
300 | return implode("\n", $lines);
301 | }
302 | }
--------------------------------------------------------------------------------
/widgets/NavBar.php:
--------------------------------------------------------------------------------
1 | 'NavBar Test',
27 | * 'brandLogoUrl' => '/img/logo.png',
28 | * ]);
29 | * echo Nav::widget([
30 | * 'items' => [
31 | * ['label' => 'Home', 'url' => ['/site/index']],
32 | * ['label' => 'About', 'url' => ['/site/about']],
33 | * ],
34 | * ]);
35 | * NavBar::end();
36 | * ```
37 | *
38 | * @see http://twitter.github.io/bootstrap/components.html#navbar
39 | */
40 | class NavBar extends \yii\bootstrap\NavBar {
41 |
42 | /**
43 | * @var string the url to logo of the brand.
44 | */
45 | public $brandLogoUrl;
46 |
47 | /**
48 | * @var string the url to logo of the brand.
49 | */
50 | public $brandWrapperOptions;
51 |
52 | /**
53 | * Initializes the widget.
54 | */
55 | public function init()
56 | {
57 | if (!isset($this->options['id']))
58 | {
59 | $this->options['id'] = $this->getId();
60 | }
61 |
62 | echo Html::beginTag('div', $this->options);
63 | echo Html::beginTag('div', ['class' => 'page-header-inner']);
64 |
65 | Html::addCssClass($this->brandWrapperOptions, 'page-logo');
66 | echo Html::beginTag('div', $this->brandWrapperOptions);
67 | echo $this->renderBrand();
68 | echo $this->renderToggleButton();
69 | echo Html::endTag('div');
70 | }
71 |
72 | /**
73 | * Executes the widget.
74 | */
75 | public function run()
76 | {
77 | echo Html::endTag('div');
78 | echo Html::endTag('div');
79 | }
80 |
81 | /**
82 | * Renders toggle button
83 | * @return string the rendering result
84 | */
85 | protected function renderToggleButton()
86 | {
87 | return Html::tag('div', '', ['class' => 'menu-toggler sidebar-toggler']);
88 | }
89 |
90 | /**
91 | * Renders Brand
92 | * @return string the rendering result
93 | */
94 | protected function renderBrand()
95 | {
96 | if ($this->brandLogoUrl)
97 | {
98 | $content = Html::img($this->brandLogoUrl, ['class' => 'logo-default', 'alt' => $this->brandLabel]);
99 | }
100 | else
101 | {
102 | $content = $this->brandLabel;
103 | }
104 |
105 | $this->brandOptions['href'] = $this->brandUrl;
106 |
107 | return Html::tag('a', $content, $this->brandOptions);
108 | }
109 |
110 | }
111 |
--------------------------------------------------------------------------------
/widgets/Note.php:
--------------------------------------------------------------------------------
1 | 'Success! Some Header Goes Here',
18 | * 'body' => 'Duis mollis, est non commodo luctus',
19 | * 'type' => Note::TYPE_INFO,
20 | * ]);
21 | * ```
22 | *
23 | * The following example will show the content enclosed between the [[begin()]]
24 | * and [[end()]] calls within the alert box:
25 | * ```php
26 | * Note::begin(['type' => Note::TYPE_DANGER]);
27 | * echo 'Some title and body';
28 | * Note::end();
29 | * ```
30 | */
31 | class Note extends Widget {
32 |
33 | const TYPE_DANGER = 'danger';
34 | const TYPE_INFO = 'info';
35 | const TYPE_SUCCESS = 'success';
36 | const TYPE_WARNING = 'warning';
37 |
38 | /**
39 | * @var string the note title
40 | */
41 | public $title;
42 |
43 | /**
44 | * @var string the note body
45 | */
46 | public $body;
47 |
48 | /**
49 | * @var string the note type.
50 | * Valid values are 'danger', 'info', 'success', 'warning'.
51 | */
52 | public $type = self::TYPE_SUCCESS;
53 |
54 | /**
55 | * Initializes the widget.
56 | */
57 | public function init()
58 | {
59 | parent::init();
60 | Html::addCssClass($this->options, 'note note-'.$this->type);
61 | echo Html::beginTag('div', $this->options);
62 | echo $this->renderTitle();
63 | }
64 |
65 | /**
66 | * Executes the widget.
67 | */
68 | public function run()
69 | {
70 | echo $this->renderBody();
71 | echo Html::endTag('div');
72 | }
73 |
74 | /**
75 | * Renders title
76 | * @return string the rendering result
77 | */
78 | public function renderTitle()
79 | {
80 | return !empty($this->title) ? Html::tag('h4', $this->title, ['class' => 'block']) : '';
81 | }
82 |
83 | /**
84 | * Renders body
85 | * @return string the rendering result
86 | */
87 | public function renderBody()
88 | {
89 | return !empty($this->body) ? Html::tag('p', $this->body) : '';
90 | }
91 | }
--------------------------------------------------------------------------------
/widgets/Notification.php:
--------------------------------------------------------------------------------
1 | 'Success! Some Header Goes Here',
22 | * 'body' => 'Duis mollis, est non commodo luctus',
23 | * 'type' => Notification::TYPE_INFO,
24 | * 'openButton' => [
25 | * 'type' => Button::TYPE_M_GREEN,
26 | * 'label' => 'Notification',
27 | * 'icon' => 'fa fa-bell-o',
28 | * ]
29 | * ]);
30 | * ```
31 | *
32 | * The following example will show the content enclosed between the [[begin()]]
33 | * and [[end()]] calls within the alert box:
34 | * ```php
35 | * Notification::begin(['type' => Notification::TYPE_DANGER]);
36 | * echo 'Some title and body';
37 | * Notification::end();
38 | * ```
39 | * @see https://github.com/CodeSeven/toastr
40 | */
41 | class Notification extends Widget
42 | {
43 | // type
44 | const TYPE_ERROR = 'error';
45 | const TYPE_INFO = 'info';
46 | const TYPE_SUCCESS = 'success';
47 | const TYPE_WARNING = 'warning';
48 | // position
49 | const POSITION_TOP_RIGHT = 'toast-top-right';
50 | const POSITION_BOTTOM_RIGHT = 'toast-bottom-right';
51 | const POSITION_BOTTOM_LEFT = 'toast-bottom-left';
52 | const POSITION_TOP_LEFT = 'toast-top-left';
53 | const POSITION_TOP_CENTER = 'toast-top-center';
54 | const POSITION_BOTTOM_CENTER = 'toast-bottom-center';
55 | const POSITION_FULL_WIDTH = 'toast-top-full-width';
56 | // easing
57 | const EASING_LINEAR = 'linear';
58 | const EASING_SWING = 'swing';
59 |
60 | /**
61 | * @var string the notification title
62 | */
63 | public $title = '';
64 | /**
65 | * @var string the notification body
66 | */
67 | public $body = '';
68 | /**
69 | * @var string the notification type.
70 | * Valid values are 'danger', 'info', 'success', 'warning'.
71 | */
72 | public $type = self::TYPE_SUCCESS;
73 | /**
74 | * @var array the configuration array for [[Button]].
75 | */
76 | public $openButton = [];
77 |
78 | /**
79 | * Executes the widget.
80 | */
81 | public function init()
82 | {
83 | parent::init();
84 | $this->initOptions();
85 | ob_start();
86 | ob_implicit_flush(false);
87 | }
88 |
89 | public function run()
90 | {
91 | $this->body .= ob_get_clean();
92 | if (!empty($this->openButton)) {
93 | /** @var Button $widget */
94 | $js = 'toastr.options = ' . Json::encode($this->clientOptions) . ';';
95 | $this->view->registerJs($js, View::POS_READY);
96 | $this->initOpenButton();
97 | } else {
98 | return null;
99 | }
100 | NotificationAsset::register($this->view);
101 | }
102 |
103 | /**
104 | * Initializes the widget options.
105 | * This method sets the default values for various options.
106 | */
107 | public function initOptions()
108 | {
109 | $defaultOptions = [
110 | 'closeButton'=> true,
111 | 'debug'=> false,
112 | 'positionClass'=> 'toast-top-right',
113 | 'onclick'=> null,
114 | 'showDuration'=> '1000',
115 | 'hideDuration'=> '1000',
116 | 'timeOut'=> '5000',
117 | 'extendedTimeOut'=> '1000',
118 | 'showEasing'=> 'swing',
119 | 'hideEasing'=> 'linear',
120 | 'showMethod'=> 'fadeIn',
121 | 'hideMethod'=> 'fadeOut'
122 | ];
123 |
124 | $this->clientOptions = array_merge($defaultOptions, $this->clientOptions);
125 | }
126 |
127 | /**
128 | * Initializes the widget Button options.
129 | * This method sets the default values for various options.
130 | */
131 | public function initOpenButton()
132 | {
133 | $widget = Button::begin($this->openButton);
134 | $msg = "'{$this->body}', '{$this->title}'";
135 | $jsOpen = 'toastr.' . $this->type . '(' . $msg . ')';
136 | if(!isset($widget->clientEvents['click'])) {
137 | $widget->clientEvents['click'] = "function(){{$jsOpen};}";
138 | }
139 | $widget->run();
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/widgets/Panel.php:
--------------------------------------------------------------------------------
1 | 'fa fa-bell-o',
22 | * 'title' => 'Title Panel',
23 | * ]);
24 | * echo 'Body portlet';
25 | * Panel::end();
26 | *
27 | *
28 | * @see http://yii2metronic.icron.org/components.html#portlet
29 | * @author icron.org
30 | * @since 1.0
31 | */
32 | class Panel extends Widget {
33 |
34 | /**
35 | * Types
36 | */
37 | const TYPE_DEFAULT = 'panel-default';
38 |
39 | /**
40 | * @var string The portlet title
41 | */
42 | public $title;
43 |
44 | /**
45 | * @var string The portlet icon
46 | */
47 | public $icon;
48 |
49 | /**
50 | * @var string The portlet type
51 | * Valid values are 'box', 'solid', ''
52 | */
53 | public $type = self::TYPE_DEFAULT;
54 |
55 | /**
56 | * @var string The portlet color
57 | * Valid values are 'light-blue', 'blue', 'red', 'yellow', 'green', 'purple', 'light-grey', 'grey'
58 | */
59 | public $color = '';
60 |
61 | /**
62 | * @var array The HTML attributes for the widget container
63 | */
64 | public $options = [];
65 |
66 | /**
67 | * @var array The HTML attributes for the widget body container
68 | */
69 | public $bodyOptions = [];
70 |
71 | /**
72 | * @var array The HTML attributes for the widget body container
73 | */
74 | public $headerOptions = [];
75 |
76 | /**
77 | * Initializes the widget.
78 | */
79 | public function init()
80 | {
81 | parent::init();
82 |
83 | Html::addCssClass($this->options, trim(sprintf('panel %s', $this->type)));
84 | echo Html::beginTag('div', $this->options);
85 |
86 | $this->_renderTitle();
87 |
88 | Html::addCssClass($this->bodyOptions, 'panel-body');
89 | echo Html::beginTag('div', $this->bodyOptions);
90 | }
91 |
92 | /**
93 | * Renders the widget.
94 | */
95 | public function run()
96 | {
97 | echo Html::endTag('div'); // End panel body
98 | echo Html::endTag('div'); // End panel div
99 | }
100 |
101 | /**
102 | * Renders portlet title
103 | */
104 | private function _renderTitle()
105 | {
106 | if (false !== $this->title)
107 | {
108 | Html::addCssClass($this->headerOptions, 'panel-heading');
109 |
110 | echo Html::beginTag('div', $this->headerOptions);
111 |
112 | echo Html::beginTag('div', ['class' => $this->pushFontColor('panel-title')]);
113 |
114 | if ($this->icon)
115 | {
116 | echo Html::tag('i', '', ['class' => $this->icon]);
117 | }
118 |
119 | echo Html::tag('span', $this->title);
120 |
121 | echo Html::endTag('div');
122 |
123 | echo Html::endTag('div');
124 | }
125 | }
126 |
127 | /**
128 | * Retrieves font color
129 | */
130 | protected function getFontColor()
131 | {
132 | if ($this->color)
133 | {
134 | return sprintf('font-%s', $this->color);
135 | }
136 |
137 | return '';
138 | }
139 |
140 | /**
141 | * Pushes font color to given string
142 | */
143 | protected function pushFontColor($string)
144 | {
145 | $color = $this->getFontColor();
146 |
147 | if ($color)
148 | {
149 | return sprintf('%s %s', $string, $color);
150 | }
151 |
152 | return $string;
153 | }
154 |
155 | }
156 |
--------------------------------------------------------------------------------
/widgets/Portlet.php:
--------------------------------------------------------------------------------
1 | 'fa fa-bell-o',
25 | * 'title' => 'Title Portlet',
26 | * ]);
27 | * echo 'Body portlet';
28 | * Portlet::end();
29 | *
30 | * // Portlet with tools, actions, scroller, events and remote content
31 | * Portlet::begin([
32 | * 'title' => 'Extended Portlet',
33 | * 'scroller' => [
34 | * 'height' => 150,
35 | * 'footer' => ['label' => 'Show all', 'url' => '#'],
36 | * ],
37 | * 'clientOptions' => [
38 | * 'loadSuccess' => new \yii\web\JsExpression('function(){ console.log("load success"); }'),
39 | * 'remote' => '/?r=site/about',
40 | * ],
41 | * 'clientEvents' => [
42 | * 'close.mr.portlet' => 'function(e) { console.log("portlet closed"); e.preventDefault(); }'
43 | * ],
44 | * 'tools' => [
45 | * Portlet::TOOL_RELOAD,
46 | * Portlet::TOOL_MINIMIZE,
47 | * Portlet::TOOL_CLOSE,
48 | * ],
49 | * ]);
50 | * ```
51 | *
52 | * @see http://yii2metronic.icron.org/components.html#portlet
53 | * @author icron.org
54 | * @since 1.0
55 | */
56 | class Portlet extends Widget
57 | {
58 |
59 | /**
60 | * Types
61 | */
62 | const TYPE_LIGHT = 'light';
63 | const TYPE_NONE = '';
64 |
65 | /**
66 | * Tools
67 | */
68 | const TOOL_MINIMIZE = 'collapse';
69 | const TOOL_MODAL = 'modal';
70 | const TOOL_RELOAD = 'reload';
71 | const TOOL_CLOSE = 'remove';
72 |
73 | /**
74 | * @var string The portlet title
75 | */
76 | public $title;
77 |
78 | /**
79 | * @var string The portlet title helper
80 | */
81 | public $helper;
82 |
83 | /**
84 | * @var string The portlet icon
85 | */
86 | public $icon;
87 |
88 | /**
89 | * @var string The portlet type
90 | * Valid values are 'box', 'solid', ''
91 | */
92 | public $type = self::TYPE_LIGHT;
93 |
94 | /**
95 | * @var string The portlet color
96 | * Valid values are 'light-blue', 'blue', 'red', 'yellow', 'green', 'purple', 'light-grey', 'grey'
97 | */
98 | public $color = '';
99 |
100 | /**
101 | * @var string The portlet background color
102 | */
103 | public $background = '';
104 |
105 | /**
106 | * @var array List of actions, where each element must be specified as a string.
107 | */
108 | public $actions = [];
109 |
110 | /**
111 | * @var array The portlet tools
112 | * Valid values are 'collapse', 'modal', 'reload', 'remove'
113 | */
114 | public $tools = [];
115 |
116 | /**
117 | * @var array Scroller options
118 | * is an array of the following structure:
119 | * ```php
120 | * [
121 | * // required, height of the body portlet as a px
122 | * 'height' => 150,
123 | * // optional, HTML attributes of the scroller
124 | * 'options' => [],
125 | * // optional, footer of the scroller. May contain string or array(the options of Link component)
126 | * 'footer' => [
127 | * 'label' => 'Show all',
128 | * ],
129 | * ]
130 | * ```
131 | */
132 | public $scroller = [];
133 |
134 | /**
135 | * @var Ribbon[]
136 | */
137 | public $ribbons = [];
138 |
139 | /**
140 | * @var bool Whether the portlet should be bordered
141 | */
142 | public $bordered = false;
143 |
144 | /**
145 | * @var array The HTML attributes for the widget container
146 | */
147 | public $options = [];
148 |
149 | /**
150 | * @var array The HTML attributes for the widget body container
151 | */
152 | public $bodyOptions = [];
153 |
154 | /**
155 | * @var array The HTML attributes for the widget body container
156 | */
157 | public $headerOptions = [];
158 |
159 | /**
160 | * @var string tag title name
161 | */
162 | public $tagTitle = 'h1';
163 |
164 | /**
165 | * Initializes the widget.
166 | */
167 | public function init()
168 | {
169 | parent::init();
170 |
171 | Html::addCssClass($this->options, trim(sprintf('portlet %s %s', $this->type, $this->background)));
172 | if (count($this->ribbons)>0) {
173 | Html::addCssClass($this->options, 'mt-element-ribbon portlet-fit');
174 | }
175 | echo Html::beginTag('div', $this->options);
176 |
177 |
178 | if (count($this->ribbons)>0) {
179 | $this->renderRibbon();
180 | }
181 |
182 | $this->renderTitle();
183 |
184 | Html::addCssClass($this->bodyOptions, 'portlet-body');
185 | echo Html::beginTag('div', $this->bodyOptions);
186 |
187 | $this->renderScrollerBegin();
188 | }
189 |
190 | /**
191 | * Renders the widget.
192 | */
193 | public function run()
194 | {
195 | $this->renderScrollerEnd();
196 |
197 | echo Html::endTag('div'); // End portlet body
198 | echo Html::endTag('div'); // End portlet div
199 | //$loader = Html::img(Metronic::getAssetsUrl($this->view) . '/img/loading-spinner-grey.gif');
200 | //$this->clientOptions['loader'] = ArrayHelper::getValue($this->clientOptions, 'loader', $loader);
201 | //$this->registerPlugin('portlet');
202 | }
203 |
204 | protected function renderRibbon()
205 | {
206 | /** @var Ribbon $r */
207 | foreach($this->ribbons as $r) {
208 | print $r->run();
209 | }
210 | }
211 |
212 | /**
213 | * Renders portlet title
214 | */
215 | protected function renderTitle()
216 | {
217 | if (false !== $this->title) {
218 |
219 | Html::addCssClass($this->headerOptions, 'portlet-title');
220 |
221 | echo Html::beginTag('div', $this->headerOptions);
222 |
223 | echo Html::beginTag('div', ['class' => 'caption']);
224 |
225 | if ($this->icon) {
226 | echo Html::tag('i', '', ['class' => $this->pushFontColor($this->icon)]);
227 | }
228 |
229 | echo Html::tag($this->tagTitle, $this->title, ['class' => $this->pushFontColor('caption-subject')]);
230 |
231 | if ($this->helper) {
232 | echo Html::tag('span', $this->helper, ['class' => 'caption-helper']);
233 | }
234 |
235 | echo Html::endTag('div');
236 |
237 | echo Html::endTag('div');
238 | }
239 | }
240 |
241 | /**
242 | * Renders portlet tools
243 | */
244 | protected function renderTools()
245 | {
246 | if (!empty($this->tools)) {
247 | $tools = [];
248 | foreach ($this->tools as $tool) {
249 | $class = '';
250 | switch ($tool) {
251 | case self::TOOL_CLOSE :
252 | $class = 'remove';
253 | break;
254 |
255 | case self::TOOL_MINIMIZE :
256 | $class = 'collapse';
257 | break;
258 |
259 | case self::TOOL_RELOAD :
260 | $class = 'reload';
261 | break;
262 | }
263 | $tools[] = Html::tag('a', '', ['class' => $class, 'href' => '']);
264 | }
265 |
266 | echo Html::tag('div', implode("\n", $tools), ['class' => 'tools']);
267 | }
268 | }
269 |
270 | /**
271 | * Renders portlet actions
272 | */
273 | protected function renderActions()
274 | {
275 | if (!empty($this->actions)) {
276 | echo Html::tag('div', implode("\n", $this->actions), ['class' => 'actions']);
277 | }
278 | }
279 |
280 | /**
281 | * Renders scroller begin
282 | * @throws InvalidConfigException
283 | */
284 | protected function renderScrollerBegin()
285 | {
286 | if (!empty($this->scroller)) {
287 | if (!isset($this->scroller['height'])) {
288 | throw new InvalidConfigException("The 'height' option of the scroller is required.");
289 | }
290 | $options = ArrayHelper::getValue($this->scroller, 'options', []);
291 | echo Html::beginTag(
292 | 'div', ArrayHelper::merge(
293 | ['class' => 'scroller', 'data-always-visible' => '1', 'data-rail-visible' => '0'], $options, ['style' => 'height:' . $this->scroller['height'] . 'px;']
294 | )
295 | );
296 | }
297 | }
298 |
299 | /**
300 | * Renders scroller end
301 | */
302 | protected function renderScrollerEnd()
303 | {
304 | if (!empty($this->scroller)) {
305 | echo Html::endTag('div');
306 | $footer = ArrayHelper::getValue($this->scroller, 'footer', '');
307 | if (!empty($footer)) {
308 | echo Html::beginTag('div', ['class' => 'scroller-footer']);
309 | if (is_array($footer)) {
310 | echo Html::tag('div', Link::widget($footer), ['class' => 'pull-right']);
311 | } elseif (is_string($footer)) {
312 | echo $footer;
313 | }
314 | echo Html::endTag('div');
315 | }
316 | }
317 | }
318 |
319 | /**
320 | * Retrieves font color
321 | */
322 | protected function getFontColor()
323 | {
324 | if ($this->color) {
325 | return sprintf('font-%s', $this->color);
326 | }
327 |
328 | return '';
329 | }
330 |
331 | /**
332 | * Pushes font color to given string
333 | */
334 | protected function pushFontColor($string)
335 | {
336 | $color = $this->getFontColor();
337 |
338 | if ($color) {
339 | return sprintf('%s %s', $string, $color);
340 | }
341 |
342 | return $string;
343 | }
344 |
345 | }
346 |
--------------------------------------------------------------------------------
/widgets/Ribbon.php:
--------------------------------------------------------------------------------
1 |
16 | * @since 1.1
17 | */
18 | class Ribbon extends Widget {
19 |
20 | const TYPE_DEFAULT = 'ribbon-color-default';
21 | const TYPE_PRIMARY = 'ribbon-color-primary';
22 | const TYPE_INFO = 'ribbon-color-info';
23 | const TYPE_SUCCESS = 'ribbon-color-success';
24 | const TYPE_DANGER = 'ribbon-color-danger';
25 | const TYPE_WARNING = 'ribbon-color-warning';
26 |
27 | public $vertical = false;
28 |
29 | public $right = false;
30 |
31 | public $shadow = false;
32 |
33 | public $rounded = false;
34 |
35 | public $bordered = false;
36 |
37 | public $square_border = false;
38 |
39 | public $dashed = false;
40 |
41 | public $clipped = false;
42 |
43 | public $bookmark = false;
44 |
45 | public $color = self::TYPE_DEFAULT;
46 |
47 | public $title = '';
48 |
49 | public $icon = '';
50 |
51 | public $options = [];
52 |
53 | /**
54 | * Renders the widget.
55 | */
56 | public function run()
57 | {
58 | Html::addCssClass($this->options, 'ribbon');
59 |
60 | Html::addCssClass($this->options, $this->color);
61 |
62 | if ($this->vertical) {
63 | Html::addCssClass($this->options, ($this->right ? 'ribbon-vertical-right' : 'ribbon-vertical-left'));
64 | } else {
65 | if ($this->right) {
66 | Html::addCssClass($this->options, 'ribbon-right');
67 | }
68 | }
69 |
70 | if ($this->shadow) {
71 | Html::addCssClass($this->options, 'ribbon-shadow');
72 | }
73 |
74 | if ($this->rounded) {
75 | Html::addCssClass($this->options, 'ribbon-round');
76 | }
77 | if ($this->square_border) {
78 | Html::addCssClass($this->options, 'ribbon-border');
79 | } else {
80 | if ($this->bordered) {
81 | if ($this->vertical) {
82 | Html::addCssClass($this->options, $this->dashed ? 'ribbon-border-dash-ver' : 'ribbon-border-ver');
83 | } else {
84 | Html::addCssClass($this->options, $this->dashed ? 'ribbon-border-dash-hor' : 'ribbon-border-hor');
85 | }
86 | }
87 | }
88 |
89 | if ($this->clipped) {
90 | Html::addCssClass($this->options, 'ribbon-clip ribbon-sub');
91 | }
92 |
93 | if ($this->bookmark) {
94 | Html::addCssClass($this->options, 'ribbon-bookmark');
95 | }
96 |
97 | $content = $this->_renderSub() . $this->_renderTitle();
98 | echo Html::tag('div', $content, $this->options);
99 | }
100 |
101 | private function _renderSub() {
102 | if ($this->clipped) {
103 | return Html::tag('div', '', ['class'=>'ribbon-sub ribbon-clip']);
104 | }
105 | if ($this->bookmark) {
106 | return Html::tag('div', '', ['class'=>'ribbon-sub ribbon-bookmark']);
107 | }
108 | }
109 |
110 | private function _renderTitle() {
111 | $html = '';
112 | if ($this->icon)
113 | {
114 | $html .= Html::tag('i', '', ['class' => $this->icon]);
115 | $html .= ' ';
116 | }
117 | $html.= Html::tag('span', $this->title);
118 | return $html;
119 | }
120 | }
--------------------------------------------------------------------------------
/widgets/Select2.php:
--------------------------------------------------------------------------------
1 | 'select',
21 | * 'data' => ['1' => 'Item 1', '2' => 'Item 2'],
22 | * 'multiple' => true,
23 | * ]);
24 | * ```
25 | *
26 | * @see http://ivaynberg.github.io/select2/
27 | */
28 | class Select2 extends InputWidget
29 | {
30 | /**
31 | * @var bool indicates whether to display a dropdown select box or use it for tagging
32 | */
33 | public $asDropdownList = true;
34 | /**
35 | * @var bool indicates whether the select2 is disabled or not.
36 | */
37 | public $disabled = false;
38 | /**
39 | * @var array the option data items. The array keys are option values, and the array values
40 | * are the corresponding option labels. The array can also be nested (i.e. some array values are arrays too).
41 | * For each sub-array, an option group will be generated whose label is the key associated with the sub-array.
42 | * If you have a list of data models, you may convert them into the format described above using
43 | * [[\yii\helpers\ArrayHelper::map()]].
44 | */
45 | public $data = [];
46 | /**
47 | * @var bool indicates whether the select2 is multiple or not.
48 | */
49 | public $multiple = false;
50 |
51 | /**
52 | * Initializes the widget.
53 | */
54 | public function init()
55 | {
56 | parent::init();
57 | Html::addCssClass($this->options, 'form-control');
58 | if ($this->multiple) {
59 | $this->options['multiple'] = 'multiple';
60 | }
61 | if ($this->disabled) {
62 | $this->options['disabled'] = true;
63 | }
64 | }
65 |
66 | /**
67 | * Executes the widget.
68 | */
69 | public function run()
70 | {
71 | if ($this->hasModel()) {
72 | if ($this->asDropdownList) {
73 | echo Html::activeDropDownList($this->model, $this->attribute, $this->data, $this->options);
74 | } else {
75 | if (!isset($this->clientOptions['query']) && !isset($this->clientOptions['ajax']) && !isset($this->clientOptions['data'])) {
76 | throw new InvalidConfigException('Must be set at least one of the client options: query, data, ajax.');
77 | }
78 | echo Html::activeHiddenInput($this->model, $this->attribute, $this->options);
79 | }
80 | } else {
81 | if ($this->asDropdownList) {
82 | echo Html::dropDownList($this->name, $this->value, $this->data, $this->options);
83 | } else {
84 | if (!isset($this->clientOptions['query']) && !isset($this->clientOptions['ajax']) && !isset($this->clientOptions['data'])) {
85 | throw new InvalidConfigException('Must be set at least one of the options Select2: query, data, ajax.');
86 | }
87 | echo Html::hiddenInput($this->name, $this->value, $this->options);
88 | }
89 | }
90 | Select2Asset::register($this->view);
91 | $this->registerPlugin('select2');
92 | }
93 | }
--------------------------------------------------------------------------------
/widgets/Spinner.php:
--------------------------------------------------------------------------------
1 | $model,
19 | * 'attribute' => 'country',
20 | * 'size' => Spinner::SIZE_SMALL,
21 | * 'buttonsLocation' => Spinner::BUTTONS_LOCATION_VERTICAL,
22 | * 'clientOptions' => ['step' => 2],
23 | * 'clientEvents' => ['changed' => 'function(event, value){ console.log(value);}'],
24 | * ]);
25 | * ```
26 | *
27 | * The following example will use the name property instead:
28 | *
29 | * ```php
30 | * echo Spinner::widget([
31 | * 'name' => 'country',
32 | * 'clientOptions' => ['step' => 2],
33 | * ]);
34 | *```
35 | *
36 | * @see http://exacttarget.github.io/fuelux/#spinner
37 | * @author
38 | */
39 | class Spinner extends InputWidget
40 | {
41 | // position
42 | const BUTTONS_LOCATION_VERTICAL = 'vertical';
43 | const BUTTONS_LOCATION_SIDES = 'sides';
44 | // size
45 | const SIZE_XSMALL = 'xsmall';
46 | const SIZE_SMALL = 'small';
47 | const SIZE_MEDIUM = 'medium';
48 | const SIZE_LARGE = 'large';
49 | /**
50 | * @var string Spinner size
51 | */
52 | public $size = self::SIZE_SMALL;
53 | /**
54 | * @var array the configuration array for [[Button]].
55 | */
56 | public $buttonsConfig = ['type' => Button::TYPE_M_BLUE];
57 | /**
58 | * @var array the HTML attributes for the input element.
59 | */
60 | public $inputOptions = [];
61 | /**
62 | * @var string The buttons location.
63 | * Valid values are 'vertical', 'sides'
64 | */
65 | public $buttonsLocation = self::BUTTONS_LOCATION_VERTICAL;
66 | /**
67 | * Executes the widget.
68 | */
69 | public function run()
70 | {
71 | Html::addCssClass($this->inputOptions, 'spinner-input form-control');
72 | $this->buttonsConfig = array_merge(['label' => ''], $this->buttonsConfig);
73 | if ($this->hasModel()) {
74 | $input = Html::activeTextInput($this->model, $this->attribute, $this->inputOptions);
75 | } else {
76 | $input = Html::textInput($this->name, $this->value, $this->inputOptions);
77 | }
78 | if ($this->buttonsLocation == self::BUTTONS_LOCATION_VERTICAL) {
79 | $this->buttonsConfig = array_merge($this->buttonsConfig, ['size' => Button::SIZE_MINI]);
80 | }
81 | $btnUp = Button::widget(
82 | array_merge($this->buttonsConfig, [
83 | 'icon' => 'fa fa-angle-up',
84 | 'options' => ['class' => 'spinner-up']
85 | ])
86 | );
87 | $btnDown = Button::widget(
88 | array_merge($this->buttonsConfig, [
89 | 'icon' => 'fa fa-angle-down',
90 | 'options' => ['class' => 'spinner-down']
91 | ])
92 | );
93 |
94 | if ($this->buttonsLocation == self::BUTTONS_LOCATION_VERTICAL) {
95 | $spinner = $input . Html::tag('div', $btnUp . $btnDown, ['class' => 'spinner-buttons input-group-btn btn-group-vertical']);
96 | } else {
97 | $spinner = Html::tag('div', $btnUp . $input . $btnDown, ['class' => 'spinner-buttons input-group-btn']);
98 | }
99 | echo Html::tag('div' , Html::tag('div', $spinner, ['class' => 'input-group input-' . $this->size]), $this->options);
100 | SpinnerAsset::register($this->view);
101 | $this->registerPlugin('spinner');
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/widgets/StepsLine.php:
--------------------------------------------------------------------------------
1 | view);
49 | return implode("\n", [
50 | Html::beginTag('div', ['class' => 'mt-element-step']),
51 | Html::beginTag('div', ['class' => "row {$this->cssRowClasses}"]),
52 | $this->renderItems(),
53 | Html::endTag('div'),
54 | Html::endTag('div')
55 | ]);
56 | }
57 |
58 | /**
59 | * Renders wizard items as specified on [[items]].
60 | * @return string the rendering result.
61 | * @throws InvalidConfigException.
62 | */
63 | public function renderItems()
64 | {
65 | $contents = [];
66 | $n = 1;
67 | $numberOfItems = count($this->items);
68 |
69 | switch ($numberOfItems){
70 | case 3:
71 | $this->cssColClass = 'col-md-4';
72 | break;
73 | case 4:
74 | $this->cssColClass = 'col-md-3';
75 | break;
76 | default:
77 | throw new InvalidConfigException(
78 | "Only three and four steps are supported by this widget. Your actual item count is $numberOfItems"
79 | );
80 | }
81 |
82 | foreach ($this->items as $key => $item) {
83 | $itemCssColClass = $this->cssColClass;
84 |
85 | if (!ArrayHelper::remove($item, 'visible', true)) {
86 | continue;
87 | }
88 |
89 | if (!is_string($key) && !array_key_exists('itemTitle', $item)) {
90 | throw new InvalidConfigException(
91 | "The 'itemTitle' option is required."
92 | );
93 | }
94 | if (is_string($item)) {
95 | $item = ['content' => $item];
96 | }
97 |
98 | if (!array_key_exists('itemIcon', $item)){
99 | $item['itemIcon'] = $n;
100 | }
101 |
102 | if (!array_key_exists('itemContent', $item)){
103 | $item['itemContent'] = '';
104 | }
105 |
106 | if (array_key_exists('itemUrl', $item) && empty($item['itemUrl'])){
107 | unset($item['itemUrl']);
108 | }
109 |
110 | switch ($n){
111 | case 1:
112 | $itemCssColClass .= ' first';
113 | break;
114 | case $numberOfItems:
115 | $itemCssColClass .= ' last';
116 | break;
117 | default:
118 | $itemCssColClass .= '';
119 |
120 | }
121 |
122 | if (array_key_exists('itemActive', $item)){
123 | $itemCssColClass .= ' ' . $item['itemActive'];
124 | }
125 |
126 | if (array_key_exists('itemDone', $item)){
127 | $itemCssColClass .= ' ' . $item['itemDone'];
128 | }
129 |
130 | $item['cssClassesCol'] = $itemCssColClass;
131 |
132 | $contents[] = $this->renderItem($item);
133 |
134 | $n++;
135 | }
136 |
137 | return implode("\n", $contents);
138 | }
139 |
140 | private function renderItem($item = []){
141 | $lines = [];
142 |
143 | $lines[] = Html::beginTag('div', [
144 | 'class' => "{$item['cssClassesCol']} mt-step-col"
145 | ]);
146 |
147 | $iconTag = Html::tag('div', $item['itemIcon'], ['class' => "mt-step-number {$this->cssItemIconClasses}"]);
148 |
149 | if (isset($item['itemUrl'])){
150 | $iconTag = Html::a($iconTag, $item['itemUrl']);
151 | }
152 |
153 | $lines[] = $iconTag;
154 | $lines[] = Html::tag('div', $item['itemTitle'], ['class' => "mt-step-title {$this->cssItemTitleClasses}"]);
155 | $lines[] = Html::tag('div', $item['itemContent'], ['class' => "mt-step-content {$this->cssItemContentClasses}"]);
156 | $lines[] = Html::endTag('div');
157 |
158 | return implode("\n", $lines);
159 | }
160 | }
--------------------------------------------------------------------------------
/widgets/Tabs.php:
--------------------------------------------------------------------------------
1 | [
22 | * [
23 | * 'label' => 'One',
24 | * 'content' => 'Anim pariatur cliche...',
25 | * 'active' => true
26 | * ],
27 | * [
28 | * 'label' => 'Two',
29 | * 'content' => 'Anim pariatur cliche...',
30 | * 'headerOptions' => [...],
31 | * 'options' => ['id' => 'myveryownID'],
32 | * ],
33 | * [
34 | * 'label' => 'Dropdown',
35 | * 'items' => [
36 | * [
37 | * 'label' => 'DropdownA',
38 | * 'content' => 'DropdownA, Anim pariatur cliche...',
39 | * ],
40 | * [
41 | * 'label' => 'DropdownB',
42 | * 'content' => 'DropdownB, Anim pariatur cliche...',
43 | * ],
44 | * ],
45 | * ],
46 | * ],
47 | * ]);
48 | * ```
49 | *
50 | */
51 | class Tabs extends \yii\bootstrap\Tabs {
52 |
53 | // Tab placements.
54 | const PLACEMENT_ABOVE = 'above';
55 | const PLACEMENT_BELOW = 'below';
56 | const PLACEMENT_LEFT = 'left';
57 | const PLACEMENT_RIGHT = 'right';
58 | // Tab type
59 | const NAV_TYPE_TABS = 'nav-tabs';
60 | const NAV_TYPE_PILLS = 'nav-pills';
61 |
62 | /**
63 | * @var string, specifies the Bootstrap tab styling.
64 | * Valid values 'nav-tabs', 'nav-pills'
65 | */
66 | public $navType = self::NAV_TYPE_TABS;
67 |
68 | /**
69 | * @var string the placement of the tabs.
70 | * Valid values are 'above', 'below', 'left' and 'right'.
71 | */
72 | public $placement = self::PLACEMENT_ABOVE;
73 |
74 | /**
75 | * @var bool Indicates whether tabs is styled for Metronic.
76 | */
77 | public $styled = true;
78 |
79 | /**
80 | * @var bool Indicates whether tabs is justified.
81 | */
82 | public $justified = false;
83 |
84 | /**
85 | * Initializes the widget.
86 | */
87 | public function init()
88 | {
89 | if ($this->justified)
90 | {
91 | Html::addCssClass($this->options, 'nav-justified');
92 | }
93 |
94 | Html::addCssClass($this->options, 'nav ' . $this->navType);
95 | parent::init();
96 | }
97 |
98 | /**
99 | * Renders the widget.
100 | */
101 | public function run()
102 | {
103 | $classWrap = ['tabs-' . $this->placement];
104 | if ($this->styled)
105 | {
106 | $classWrap[] = 'tabbable-custom';
107 | if ($this->justified)
108 | {
109 | $classWrap[] = 'nav-justified';
110 | }
111 | }
112 | else
113 | {
114 | $classWrap[] = 'tabbable';
115 | }
116 | echo Html::beginTag('div', ['class' => implode(' ', $classWrap)]);
117 | echo parent::run();
118 | echo Html::endTag('div');
119 | }
120 |
121 | /**
122 | * Renders tab items as specified on [[items]].
123 | * @return string the rendering result.
124 | * @throws InvalidConfigException.
125 | */
126 | protected function renderItems()
127 | {
128 | $headers = [];
129 | $panes = [];
130 |
131 | if (!$this->hasActiveTab() && !empty($this->items))
132 | {
133 | $this->items[0]['active'] = true;
134 | }
135 |
136 | foreach ($this->items as $n => $item)
137 | {
138 | if (!isset($item['label']))
139 | {
140 | throw new InvalidConfigException("The 'label' option is required.");
141 | }
142 | $label = $this->encodeLabels ? Html::encode($item['label']) : $item['label'];
143 | $headerOptions = array_merge($this->headerOptions, ArrayHelper::getValue($item, 'headerOptions', []));
144 |
145 | if (isset($item['items']))
146 | {
147 | if ($this->styled)
148 | {
149 | throw new InvalidConfigException("The 'styled' not support dropdown items. Please, set 'styled' to false.");
150 | }
151 | $label .= ' ';
152 | Html::addCssClass($headerOptions, 'dropdown');
153 |
154 | if ($this->renderDropdown(count($item['items']), $item['items'], $panes))
155 | {
156 | Html::addCssClass($headerOptions, 'active');
157 | }
158 |
159 | $header = Html::a($label, "#", ['class' => 'dropdown-toggle', 'data-toggle' => 'dropdown']) . "\n"
160 | . Dropdown::widget(['items' => $item['items'], 'clientOptions' => false]);
161 | }
162 | elseif (isset($item['content']))
163 | {
164 | $options = array_merge($this->itemOptions, ArrayHelper::getValue($item, 'options', []));
165 | $options['id'] = ArrayHelper::getValue($options, 'id', $this->options['id'] . '-tab' . $n);
166 |
167 | Html::addCssClass($options, 'tab-pane');
168 | if (ArrayHelper::remove($item, 'active'))
169 | {
170 | Html::addCssClass($options, 'active');
171 | Html::addCssClass($headerOptions, 'active');
172 | }
173 | $header = Html::a($label, '#' . $options['id'], ['data-toggle' => 'tab']);
174 | $panes[] = Html::tag('div', $item['content'], $options);
175 | }
176 | else
177 | {
178 | throw new InvalidConfigException("Either the 'content' or 'items' option must be set.");
179 | }
180 |
181 | $headers[] = Html::tag('li', $header, $headerOptions);
182 | }
183 |
184 | $headers = Html::tag('ul', implode("\n", $headers), $this->options);
185 | $panes = Html::tag('div', implode("\n", $panes), ['class' => 'tab-content']);
186 |
187 | return ($this->placement == self::PLACEMENT_BELOW) ? ($panes . "\n" . $headers) : ($headers . "\n" . $panes);
188 | }
189 |
190 | }
191 |
--------------------------------------------------------------------------------
/widgets/TagInput.php:
--------------------------------------------------------------------------------
1 | 'auto',
35 | ];
36 |
37 | /**
38 | * @inheritdoc
39 | */
40 | public function init()
41 | {
42 | $this->pluginOptions = ArrayHelper::merge($this->pluginDefaults, $this->pluginOptions);
43 |
44 | parent::init();
45 | }
46 |
47 | /**
48 | * Executes the widget.
49 | */
50 | public function run()
51 | {
52 | $this->registerJs();
53 |
54 | TagInputAsset::register($this->view);
55 |
56 | return parent::run();
57 | }
58 |
59 | /**
60 | * Registeres JS
61 | */
62 | protected function registerJs()
63 | {
64 | $this->view->registerJs("
65 | !(function($){
66 | var el = $('#{$this->options['id']}');
67 |
68 | el.tagsInput(".Json::encode($this->pluginOptions).");
69 |
70 | })(jQuery);
71 | ", \yii\web\View::POS_READY);
72 | }
73 | }
--------------------------------------------------------------------------------
/widgets/TextInputWidget.php:
--------------------------------------------------------------------------------
1 | hasModel()) {
28 | echo Html::activeTextInput($this->model, $this->attribute, $this->options);
29 | } else {
30 | echo Html::textInput($this->name, $this->value, $this->options);
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/widgets/Tree.php:
--------------------------------------------------------------------------------
1 | [
85 | 'wholerow',
86 | ],
87 | 'core' => [
88 | 'themes' => [
89 | 'responsive' => false,
90 | 'icons' => false
91 | ],
92 | ],
93 | ];
94 |
95 | /**
96 | * Inits widget
97 | */
98 | public function init()
99 | {
100 | $this->jsTree();
101 | }
102 |
103 | /**
104 | * Runs widget
105 | */
106 | public function run()
107 | {
108 | $builder = \dlds\metronic\builders\TreeBuilder::instance($this->items, array(
109 | 'treeTag' => $this->listTag,
110 | 'itemTag' => $this->itemTag,
111 | 'levelAttr' => $this->levelAttr,
112 | 'contentCallback' => $this->contentCallback,
113 | 'treeHtmlOptions' => function() {
114 | return $this->getTreeOptions();
115 | },
116 | 'itemHtmlOptions' => function($id) {
117 | return $this->getItemOptions($id);
118 | },
119 | 'contentHtmlOptions' => function() {
120 | return $this->getContentOptions();
121 | },
122 | ));
123 |
124 | echo $this->renderTree($builder->build());
125 | }
126 |
127 | /**
128 | * Retrieves tree html options
129 | * @return array tree html options
130 | */
131 | protected function getTreeOptions()
132 | {
133 | return array(
134 | 'class' => $this->listClass,
135 | );
136 | }
137 |
138 | /**
139 | * Retrieves item html options
140 | * @param array $id passed item id
141 | */
142 | protected function getItemOptions($id)
143 | {
144 | return array(
145 | 'class' => $this->itemClass,
146 | 'data-id' => $id,
147 | 'data-jstree' => json_encode([
148 | 'selected' => $this->isItemAssigned($id),
149 | ]),
150 | );
151 | }
152 |
153 | /**
154 | * Retrieves content html options
155 | * @return type
156 | */
157 | protected function getContentOptions()
158 | {
159 | return array(
160 | 'class' => $this->contentClass,
161 | );
162 | }
163 |
164 | /**
165 | * Indicates if item is currently assigned to model
166 | * @param int $id given item id
167 | */
168 | protected function isItemAssigned($id)
169 | {
170 | if (null === $this->_assignedItems)
171 | {
172 | $this->_assignedItems = $this->pullAssignedItems();
173 | }
174 |
175 | return in_array($id, $this->_assignedItems);
176 | }
177 |
178 | /**
179 | * Pulls assigned items from model
180 | */
181 | protected function pullAssignedItems()
182 | {
183 | if (is_string($this->model{$this->attribute}))
184 | {
185 | return explode(',', $this->model{$this->attribute});
186 | }
187 |
188 | return (array) $this->model{$this->attribute};
189 | }
190 |
191 | /**
192 | * Renders output
193 | * @param string $tree
194 | */
195 | protected function renderTree($tree)
196 | {
197 | $this->treeOptions = array_merge(['id' => $this->id], $this->treeOptions);
198 | $html = Html::beginTag('div', $this->treeOptions);
199 |
200 | $html .= $tree;
201 |
202 | $html .= Html::endTag('div');
203 |
204 | if ($this->checkable)
205 | {
206 | $html .= $this->renderHiddenField();
207 | }
208 |
209 | return $html;
210 | }
211 |
212 | /**
213 | * Renders hidden form field
214 | */
215 | protected function renderHiddenField()
216 | {
217 | if ($this->hasModel())
218 | {
219 | return Html::activeInput('hidden', $this->model, $this->attribute, ['id' => $this->getHiddenFieldId()]);
220 | }
221 |
222 | return Html::input('hidden', $this->name, $this->value, ['id' => $this->getHiddenFieldId()]);
223 | }
224 |
225 | /**
226 | * Registres JS files
227 | */
228 | protected function jsTree()
229 | {
230 | if ($this->checkable)
231 | {
232 | $this->defaultTreeOptions = ArrayHelper::merge($this->defaultTreeOptions, [
233 | 'plugins' => [
234 | 'checkbox'
235 | ],
236 | 'checkbox' => [
237 | 'keep_selected_style' => false,
238 | 'three_state' => false,
239 | 'cascade' => ''
240 | ]
241 | ]);
242 | }
243 |
244 | $treeOptions = json_encode(ArrayHelper::merge($this->defaultTreeOptions, $this->treeOptions));
245 |
246 | $view = $this->getView();
247 | $view->registerJs("jQuery('#{$this->id}').jstree({$treeOptions});");
248 | $this->registerAdditionalJs();
249 | TreeAsset::register($view);
250 | }
251 |
252 | protected function registerAdditionalJs()
253 | {
254 | $view = $this->getView();
255 |
256 | if ($this->checkable)
257 | {
258 | $view->registerJs("jQuery('#{$this->id}').on('changed.jstree', function (e, data) {
259 | var i, j, r = [];
260 |
261 | for (i = 0, j = data.selected.length; i < j; i++) {
262 | r.push(data.instance.get_node(data.selected[i]).data.id);
263 | }
264 |
265 | jQuery('#{$this->getHiddenFieldId()}').val(r.join(','));
266 | });");
267 | }
268 |
269 | $view->registerJs("jQuery('#{$this->id}').on('select_node.jstree', function (e, data) {
270 | var \$this = $(this);
271 | \$this.jstree('open_node', data.node);
272 | var ParentNode = \$this.jstree('get_parent', data.node);
273 | \$this.jstree('select_node', ParentNode);
274 | });");
275 |
276 | $view->registerJs("jQuery('#{$this->id}').on('deselect_node.jstree', function (e, data) {
277 | var \$this = $(this);
278 | \$this.jstree('open_node', data.node);
279 | var ChildrenNodes = jQuery.makeArray(\$this.jstree('get_children_dom', data.node));
280 | \$this.jstree('deselect_node', ChildrenNodes);
281 | \$this.jstree('close_node', data.node);
282 | });");
283 | }
284 |
285 | /**
286 | * Retrieves hidden field id
287 | */
288 | private function getHiddenFieldId()
289 | {
290 | $formName = $this->model ? $this->model->formName() : 'jstree-form';
291 | return strtolower(sprintf('%s-%s', $formName, $this->attribute));
292 | }
293 | }
294 | ?>
295 |
--------------------------------------------------------------------------------
/widgets/Widget.php:
--------------------------------------------------------------------------------
1 |
16 | * @since 1.0
17 | */
18 | class Widget extends \yii\bootstrap\Widget
19 | {
20 | /**
21 | * @var array the HTML attributes for the widget container tag.
22 | */
23 | public $options = [];
24 | /**
25 | * @var array the options for the underlying Metronic JS plugin.
26 | * Please refer to the corresponding Metronic plugin Web page for possible options.
27 | * For example, [this page](http://yii2metronic.icron.org/javascript.html#portlet) shows
28 | * how to use the "Portlet" plugin and the supported options (e.g. "loadSuccess").
29 | */
30 | public $clientOptions = [];
31 | /**
32 | * @var array the event handlers for the underlying Metronic JS plugin.
33 | * Please refer to the corresponding Metronic plugin Web page for possible events.
34 | * For example, [this page](http://yii2metronic.icron.org/javascript.html#portlet) shows
35 | * how to use the "Portlet" plugin and the supported events (e.g. "close.mr.portlet").
36 | */
37 | public $clientEvents = [];
38 |
39 | /**
40 | * Registers a specific Bootstrap plugin and the related events
41 | * @param string $name the name of the Bootstrap plugin
42 | */
43 | protected function registerPlugin($name)
44 | {
45 | $view = $this->getView();
46 | $id = $this->options['id'];
47 | if ($this->clientOptions !== false) {
48 | $options = empty($this->clientOptions) ? '' : Json::encode($this->clientOptions);
49 | $js = "jQuery('#$id').$name($options);";
50 | $view->registerJs($js);
51 | }
52 | if (!empty($this->clientEvents)) {
53 | $js = [];
54 | foreach ($this->clientEvents as $event => $handler) {
55 | $js[] = "jQuery('#$id').on('$event', $handler);";
56 | }
57 | $view->registerJs(implode("\n", $js));
58 | }
59 | }
60 | }
61 |
--------------------------------------------------------------------------------