1
+ <?php
2
+
3
+ namespace yii2mod \editable ;
4
+
5
+ use kartik \helpers \Html ;
6
+ use yii \base \InvalidConfigException ;
7
+ use yii \db \ActiveRecordInterface ;
8
+ use yii \helpers \ArrayHelper ;
9
+ use yii \helpers \Json ;
10
+ use yii \helpers \Url ;
11
+ use yii \web \JsExpression ;
12
+ use yii \widgets \InputWidget ;
13
+ use yii2mod \editable \bundles \EditableAddressAsset ;
14
+ use yii2mod \editable \bundles \EditableBootstrapAsset ;
15
+ use yii2mod \editable \bundles \EditableComboDateAsset ;
16
+ use yii2mod \editable \bundles \EditableDatePickerAsset ;
17
+ use yii2mod \editable \bundles \EditableDateTimePickerAsset ;
18
+
19
+ /**
20
+ * Class Editable
21
+ * @package yii2mod\editable
22
+ */
23
+ class Editable extends InputWidget
24
+ {
25
+ /**
26
+ * @var string the type of input. Type of input.
27
+ */
28
+ public $ type = 'text ' ;
29
+
30
+ /**
31
+ * @var string the Mode of editable, can be popup or inline.
32
+ */
33
+ public $ mode = 'inline ' ;
34
+
35
+ /**
36
+ * @var string|array Url for submit, e.g. '/post'.
37
+ */
38
+ public $ url ;
39
+
40
+ /**
41
+ * @var array the options for the X-editable.js plugin.
42
+ */
43
+ public $ pluginOptions = [];
44
+
45
+ /**
46
+ * @var array the event handlers for the X-editable.js plugin.
47
+ */
48
+ public $ clientEvents = [];
49
+
50
+
51
+ /**
52
+ * Initializes the widget.
53
+ */
54
+ public function init ()
55
+ {
56
+ if ($ this ->url === null ) {
57
+ throw new InvalidConfigException ("You must setup the 'Url' property. " );
58
+ }
59
+ if (!isset ($ this ->options ['id ' ])) {
60
+ $ this ->options ['id ' ] = $ this ->hasModel () ? Html::getInputId ($ this ->model , $ this ->attribute ) : $ this ->getId ();
61
+ }
62
+
63
+ parent ::init ();
64
+ }
65
+
66
+ /**
67
+ * Executes the widget.
68
+ */
69
+ public function run ()
70
+ {
71
+ $ linkText = $ this ->getLinkText ();
72
+ echo Html::a ($ linkText , null , $ this ->options );
73
+ $ this ->registerClientScript ();
74
+ }
75
+
76
+ /**
77
+ * Register client script
78
+ */
79
+ protected function registerClientScript ()
80
+ {
81
+ $ view = $ this ->getView ();
82
+ switch ($ this ->type ) {
83
+ case 'address ' :
84
+ EditableAddressAsset::register ($ view );
85
+ break ;
86
+ case 'combodate ' :
87
+ EditableComboDateAsset::register ($ view );
88
+ break ;
89
+ case 'date ' :
90
+ EditableDatePickerAsset::register ($ view );
91
+ break ;
92
+ case 'datetime ' :
93
+ EditableDateTimePickerAsset::register ($ view );
94
+ break ;
95
+ default :
96
+ EditableBootstrapAsset::register ($ view );
97
+ }
98
+ $ id = ArrayHelper::remove ($ this ->pluginOptions , 'selector ' , '# ' . $ this ->options ['id ' ]);
99
+ $ id = preg_replace ('/([.])/ ' , '\\\\\\\$1 ' , $ id );
100
+
101
+ if ($ this ->hasActiveRecord () && $ this ->model ->isNewRecord ) {
102
+ $ this ->pluginOptions ['send ' ] = 'always ' ; // send to server without pk
103
+ }
104
+ $ pluginOptions = $ this ->getPluginOptions ();
105
+ $ js = "jQuery(' $ id').editable( $ pluginOptions); " ;
106
+ $ view ->registerJs ($ js );
107
+ if (!empty ($ this ->clientEvents )) {
108
+ $ this ->registerClientEvents ($ id );
109
+ }
110
+ }
111
+
112
+ /**
113
+ * Return plugin options in json format
114
+ * @return string
115
+ */
116
+ public function getPluginOptions ()
117
+ {
118
+ $ pk = ArrayHelper::getValue ($ this ->pluginOptions ,
119
+ 'pk ' ,
120
+ $ this ->hasActiveRecord () ? $ this ->model ->getPrimaryKey () : null
121
+ );
122
+ $ this ->pluginOptions ['pk ' ] = $ pk ;
123
+ $ this ->pluginOptions ['url ' ] = $ this ->url instanceof JsExpression ? $ this ->url : Url::toRoute ($ this ->url );
124
+ $ this ->pluginOptions ['type ' ] = $ this ->type ;
125
+ $ this ->pluginOptions ['mode ' ] = $ this ->mode ;
126
+ $ this ->pluginOptions ['name ' ] = $ this ->attribute ?: $ this ->name ;
127
+
128
+ return Json::encode ($ this ->pluginOptions );
129
+ }
130
+
131
+ /**
132
+ * Register client events
133
+ * @param $id
134
+ */
135
+ public function registerClientEvents ($ id )
136
+ {
137
+ $ view = $ this ->getView ();
138
+ $ js = [];
139
+ foreach ($ this ->clientEvents as $ event => $ handler ) {
140
+ $ js [] = "jQuery(' $ id').on(' $ event', $ handler); " ;
141
+ }
142
+ $ view ->registerJs (implode ("\n" , $ js ));
143
+ }
144
+
145
+ /**
146
+ * Return link text
147
+ * @return mixed|string
148
+ */
149
+ protected function getLinkText ()
150
+ {
151
+ $ value = $ this ->value ;
152
+ if ($ this ->hasModel ()) {
153
+ $ model = $ this ->model ;
154
+ if ($ value !== null ) {
155
+ if (is_string ($ value )) {
156
+ $ linkText = ArrayHelper::getValue ($ model , $ value );
157
+ } else {
158
+ $ linkText = call_user_func ($ value , $ model );
159
+ }
160
+ } else {
161
+ $ linkText = ArrayHelper::getValue ($ model , $ this ->attribute );
162
+ }
163
+ } else {
164
+ $ linkText = $ value ;
165
+ }
166
+
167
+ return $ linkText ;
168
+ }
169
+
170
+ /**
171
+ * To ensure that `getPrimaryKey()` and `getIsNewRecord()` methods are implemented in model.
172
+ * @return bool
173
+ */
174
+ protected function hasActiveRecord ()
175
+ {
176
+ return $ this ->hasModel () && $ this ->model instanceof ActiveRecordInterface;
177
+ }
178
+ }
0 commit comments