1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\jui;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\helpers\Html;
/**
* Sortable renders a sortable jQuery UI widget.
*
* For example:
*
* ```php
* echo Sortable::widget([
* 'items' => [
* 'Item 1',
* ['content' => 'Item2'],
* [
* 'content' => 'Item3',
* 'options' => ['tag' => 'li'],
* ],
* ],
* 'options' => ['tag' => 'ul'],
* 'itemOptions' => ['tag' => 'li'],
* 'clientOptions' => ['cursor' => 'move'],
* ]);
* ```
*
* @see http://api.jqueryui.com/sortable/
* @author Alexander Kochetov <creocoder@gmail.com>
* @since 2.0
*/
class Sortable extends Widget
{
/**
* @var array the HTML attributes for the widget container tag. The following special options are recognized:
*
* - tag: string, defaults to "ul", the tag name of the container tag of this widget.
*
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $options = [];
/**
* @var array list of sortable items. Each item can be a string representing the item content
* or an array of the following structure:
*
* ~~~
* [
* 'content' => 'item content',
* // the HTML attributes of the item container tag. This will overwrite "itemOptions".
* 'options' => [],
* ]
* ~~~
*/
public $items = [];
/**
* @var array list of HTML attributes for the item container tags. This will be overwritten
* by the "options" set in individual [[items]]. The following special options are recognized:
*
* - tag: string, defaults to "li", the tag name of the item container tags.
*
* @see \yii\helpers\Html::renderTagAttributes() for details on how attributes are being rendered.
*/
public $itemOptions = [];
/**
* @inheritDoc
*/
protected $clientEventMap = [
'activate' => 'sortactivate',
'beforeStop' => 'sortbeforestop',
'change' => 'sortchange',
'create' => 'sortcreate',
'deactivate' => 'sortdeactivate',
'out' => 'sortout',
'over' => 'sortover',
'receive' => 'sortreceive',
'remove' => 'sortremove',
'sort' => 'sort',
'start' => 'sortstart',
'stop' => 'sortstop',
'update' => 'sortupdate',
];
/**
* Renders the widget.
*/
public function run()
{
$options = $this->options;
$tag = ArrayHelper::remove($options, 'tag', 'ul');
echo Html::beginTag($tag, $options) . "\n";
echo $this->renderItems() . "\n";
echo Html::endTag($tag) . "\n";
$this->registerWidget('sortable');
}
/**
* Renders sortable items as specified on [[items]].
* @return string the rendering result.
* @throws InvalidConfigException.
*/
public function renderItems()
{
$items = [];
foreach ($this->items as $item) {
$options = $this->itemOptions;
$tag = ArrayHelper::remove($options, 'tag', 'li');
if (is_array($item)) {
if (!isset($item['content'])) {
throw new InvalidConfigException("The 'content' option is required.");
}
$options = array_merge($options, ArrayHelper::getValue($item, 'options', []));
$tag = ArrayHelper::remove($options, 'tag', $tag);
$items[] = Html::tag($tag, $item['content'], $options);
} else {
$items[] = Html::tag($tag, $item, $options);
}
}
return implode("\n", $items);
}
}