1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace Ajax\common; |
4
|
|
|
|
5
|
|
|
use Ajax\common\html\HtmlDoubleElement; |
6
|
|
|
use Ajax\semantic\html\elements\HtmlButton; |
7
|
|
|
use Ajax\semantic\widgets\datatable\PositionInTable; |
8
|
|
|
use Ajax\semantic\html\collections\menus\HtmlMenu; |
9
|
|
|
use Ajax\semantic\widgets\base\FieldAsTrait; |
10
|
|
|
use Ajax\semantic\html\elements\HtmlButtonGroups; |
11
|
|
|
use Ajax\semantic\widgets\base\InstanceViewer; |
12
|
|
|
use Ajax\semantic\html\modules\HtmlDropdown; |
13
|
|
|
use Ajax\service\JArray; |
14
|
|
|
use Ajax\service\Javascript; |
15
|
|
|
use Ajax\semantic\html\collections\form\HtmlForm; |
16
|
|
|
use Ajax\JsUtils; |
17
|
|
|
use Ajax\semantic\html\collections\form\HtmlFormField; |
18
|
|
|
use Ajax\semantic\html\collections\form\traits\FormTrait; |
19
|
|
|
use Ajax\common\html\BaseWidget; |
20
|
|
|
use Ajax\semantic\html\modules\HtmlModal; |
21
|
|
|
use Ajax\common\html\traits\BaseHooksTrait; |
22
|
|
|
|
23
|
|
|
abstract class Widget extends HtmlDoubleElement { |
24
|
|
|
use FieldAsTrait,FormTrait,BaseHooksTrait; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var string classname |
28
|
|
|
*/ |
29
|
|
|
protected $_model; |
30
|
|
|
protected $_modelInstance; |
31
|
|
|
/** |
32
|
|
|
* @var InstanceViewer |
33
|
|
|
*/ |
34
|
|
|
protected $_instanceViewer; |
35
|
|
|
/** |
36
|
|
|
* @var HtmlMenu |
37
|
|
|
*/ |
38
|
|
|
protected $_toolbar; |
39
|
|
|
/** |
40
|
|
|
* @var string |
41
|
|
|
*/ |
42
|
|
|
protected $_toolbarPosition; |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @var boolean |
46
|
|
|
*/ |
47
|
|
|
protected $_edition; |
48
|
|
|
|
49
|
|
|
/** |
50
|
|
|
* @var HtmlForm |
51
|
|
|
*/ |
52
|
|
|
protected $_form; |
53
|
|
|
|
54
|
|
|
protected $_generated; |
55
|
|
|
|
56
|
|
|
protected $_hasRules; |
57
|
|
|
|
58
|
|
|
|
59
|
|
|
public function __construct($identifier,$model,$modelInstance=NULL) { |
60
|
|
|
parent::__construct($identifier); |
61
|
|
|
$this->_template="%wrapContentBefore%%content%%wrapContentAfter%"; |
62
|
|
|
$this->setModel($model); |
63
|
|
|
if(isset($modelInstance)){ |
64
|
|
|
$this->show($modelInstance); |
65
|
|
|
} |
66
|
|
|
$this->_generated=false; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
protected function _init($instanceViewer,$contentKey,$content,$edition){ |
70
|
|
|
$this->_instanceViewer=$instanceViewer; |
71
|
|
|
$this->content=[$contentKey=>$content]; |
72
|
|
|
$this->_self=$content; |
73
|
|
|
$this->_toolbarPosition=PositionInTable::BEFORETABLE; |
74
|
|
|
$this->_edition=$edition; |
75
|
|
|
} |
76
|
|
|
|
77
|
|
|
/** |
78
|
|
|
* @param int|string $fieldName |
79
|
|
|
* @return int|string|boolean |
80
|
|
|
*/ |
81
|
|
|
protected function _getIndex($fieldName){ |
82
|
|
|
$index=$fieldName; |
83
|
|
|
if(\is_string($fieldName)){ |
84
|
|
|
$fields=$this->_instanceViewer->getVisibleProperties(); |
85
|
|
|
$index=\array_search($fieldName, $fields); |
86
|
|
|
} |
87
|
|
|
return $index; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
protected function _getFieldIdentifier($prefix,$name=""){ |
91
|
|
|
return $this->identifier."-{$prefix}-".$this->_instanceViewer->getIdentifier(); |
92
|
|
|
} |
93
|
|
|
|
94
|
|
|
protected function _getFieldName($index){ |
95
|
|
|
return $this->_instanceViewer->getFieldName($index); |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
protected function _getFieldCaption($index){ |
99
|
|
|
return $this->_instanceViewer->getCaption($index); |
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
abstract protected function _setToolbarPosition($table,$captions=NULL); |
103
|
|
|
|
104
|
|
|
public function show($modelInstance){ |
105
|
|
|
if(\is_array($modelInstance)){ |
106
|
|
|
$modelInstance=\json_decode(\json_encode($modelInstance), FALSE); |
107
|
|
|
} |
108
|
|
|
$this->_modelInstance=$modelInstance; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
public function getModel() { |
112
|
|
|
return $this->_model; |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
public function setModel($_model) { |
116
|
|
|
$this->_model=$_model; |
117
|
|
|
return $this; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
public function getInstanceViewer() { |
121
|
|
|
return $this->_instanceViewer; |
122
|
|
|
} |
123
|
|
|
|
124
|
|
|
public function setInstanceViewer($_instanceViewer) { |
125
|
|
|
$this->_instanceViewer=$_instanceViewer; |
126
|
|
|
return $this; |
127
|
|
|
} |
128
|
|
|
|
129
|
|
|
abstract public function getHtmlComponent(); |
130
|
|
|
|
131
|
|
|
public function setAttached($value=true){ |
132
|
|
|
return $this->getHtmlComponent()->setAttached($value); |
133
|
|
|
} |
134
|
|
|
|
135
|
|
|
/** |
136
|
|
|
* Associates a $callback function after the compilation of the field at $index position |
137
|
|
|
* The $callback function can take the following arguments : $field=>the compiled field, $instance : the active instance of the object, $index: the field position |
138
|
|
|
* @param int $index postion of the compiled field |
139
|
|
|
* @param callable $callback function called after the field compilation |
140
|
|
|
* @return Widget |
141
|
|
|
*/ |
142
|
|
|
public function afterCompile($index,$callback){ |
143
|
|
|
$index=$this->_getIndex($index); |
144
|
|
|
$this->_instanceViewer->afterCompile($index, $callback); |
145
|
|
|
return $this; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
public function setColor($color){ |
149
|
|
|
return $this->getHtmlComponent()->setColor($color); |
150
|
|
|
} |
151
|
|
|
|
152
|
|
|
|
153
|
|
|
public function setCaptions($captions){ |
154
|
|
|
$this->_instanceViewer->setCaptions($captions); |
155
|
|
|
return $this; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
public function setCaption($index,$caption){ |
159
|
|
|
$this->_instanceViewer->setCaption($this->_getIndex($index), $caption); |
160
|
|
|
return $this; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
public function setFields($fields){ |
164
|
|
|
$this->_instanceViewer->setVisibleProperties($fields); |
165
|
|
|
return $this; |
166
|
|
|
} |
167
|
|
|
|
168
|
|
|
public function addField($field,$key=null){ |
169
|
|
|
$this->_instanceViewer->addField($field,$key); |
170
|
|
|
return $this; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
public function addFields($fields){ |
174
|
|
|
$this->_instanceViewer->addFields($fields); |
175
|
|
|
return $this; |
176
|
|
|
} |
177
|
|
|
|
178
|
|
|
public function countFields(){ |
179
|
|
|
return $this->_instanceViewer->visiblePropertiesCount(); |
180
|
|
|
} |
181
|
|
|
|
182
|
|
|
public function addMessage($attributes=NULL,$fieldName="message"){ |
183
|
|
|
$this->_instanceViewer->addField($fieldName); |
184
|
|
|
$count=$this->_instanceViewer->visiblePropertiesCount(); |
185
|
|
|
return $this->fieldAsMessage($count-1,$attributes); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
public function addErrorMessage(){ |
189
|
|
|
return $this->addMessage(["error"=>true],"message"); |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
public function insertField($index,$field,$key=null){ |
193
|
|
|
$index=$this->_getIndex($index); |
194
|
|
|
$this->_instanceViewer->insertField($index, $field,$key); |
195
|
|
|
return $this; |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
public function insertInField($index,$field,$key=null){ |
199
|
|
|
$index=$this->_getIndex($index); |
200
|
|
|
$this->_instanceViewer->insertInField($index, $field,$key); |
201
|
|
|
return $this; |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* Defines the function which displays the field value |
206
|
|
|
* @param int|string $index index or name of the field to display |
207
|
|
|
* @param callable $callback function parameters are : $value : the field value, $instance : the active instance of model, $fieldIndex : the field index, $rowIndex : the row index |
208
|
|
|
* @return Widget |
209
|
|
|
*/ |
210
|
|
|
public function setValueFunction($index,$callback){ |
211
|
|
|
$index=$this->_getIndex($index); |
212
|
|
|
$this->_instanceViewer->setValueFunction($index, $callback); |
213
|
|
|
return $this; |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
public function setIdentifierFunction($callback){ |
217
|
|
|
$this->_instanceViewer->setIdentifierFunction($callback); |
218
|
|
|
return $this; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
/** |
222
|
|
|
* @return \Ajax\semantic\html\collections\menus\HtmlMenu |
223
|
|
|
*/ |
224
|
|
|
public function getToolbar(){ |
225
|
|
|
if(isset($this->_toolbar)===false){ |
226
|
|
|
$this->_toolbar=new HtmlMenu("toolbar-".$this->identifier); |
227
|
|
|
} |
228
|
|
|
return $this->_toolbar; |
229
|
|
|
} |
230
|
|
|
|
231
|
|
|
/** |
232
|
|
|
* Adds a new element in toolbar |
233
|
|
|
* @param mixed $element |
234
|
|
|
* @param callable $callback function to call on $element |
235
|
|
|
* @return \Ajax\common\html\HtmlDoubleElement |
236
|
|
|
*/ |
237
|
|
|
public function addInToolbar($element,$callback=NULL){ |
238
|
|
|
$tb=$this->getToolbar(); |
239
|
|
|
if($element instanceof BaseWidget){ |
240
|
|
|
if($element->getIdentifier()===""){ |
241
|
|
|
$element->setIdentifier("tb-item-".$this->identifier."-".$tb->count()); |
242
|
|
|
} |
243
|
|
|
} |
244
|
|
|
if(isset($callback)){ |
245
|
|
|
if(\is_callable($callback)){ |
246
|
|
|
$callback($element); |
247
|
|
|
} |
248
|
|
|
} |
249
|
|
|
return $tb->addItem($element); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* @param string $caption |
254
|
|
|
* @param string $icon |
255
|
|
|
* @param callable $callback function($element) |
256
|
|
|
* @return \Ajax\common\html\HtmlDoubleElement |
257
|
|
|
*/ |
258
|
|
|
public function addItemInToolbar($caption,$icon=NULL,$callback=NULL){ |
259
|
|
|
$result=$this->addInToolbar($caption,$callback); |
260
|
|
|
if(isset($icon) && method_exists($result, "addIcon")) |
261
|
|
|
$result->addIcon($icon); |
262
|
|
|
return $result; |
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
/** |
266
|
|
|
* @param array $items |
267
|
|
|
* @param callable $callback function($element) |
268
|
|
|
* @return \Ajax\common\Widget |
269
|
|
|
*/ |
270
|
|
|
public function addItemsInToolbar(array $items,$callback=NULL){ |
271
|
|
|
if(JArray::isAssociative($items)){ |
272
|
|
|
foreach ($items as $icon=>$item){ |
273
|
|
|
$this->addItemInToolbar($item,$icon,$callback); |
274
|
|
|
} |
275
|
|
|
}else{ |
276
|
|
|
foreach ($items as $item){ |
277
|
|
|
$this->addItemInToolbar($item,null,$callback); |
278
|
|
|
} |
279
|
|
|
} |
280
|
|
|
return $this; |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
/** |
284
|
|
|
* @param mixed $value |
285
|
|
|
* @param array $items |
286
|
|
|
* @param callable $callback function($element) |
287
|
|
|
* @return \Ajax\common\html\HtmlDoubleElement |
288
|
|
|
*/ |
289
|
|
|
public function addDropdownInToolbar($value,$items,$callback=NULL){ |
290
|
|
|
$dd=$value; |
291
|
|
|
if (\is_string($value)) { |
292
|
|
|
$dd=new HtmlDropdown("dropdown-". $this->identifier."-".$value, $value, $items); |
293
|
|
|
} |
294
|
|
|
return $this->addInToolbar($dd,$callback); |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/** |
298
|
|
|
* @param string $caption |
299
|
|
|
* @param string $cssStyle |
300
|
|
|
* @param callable $callback function($element) |
301
|
|
|
* @return \Ajax\common\html\HtmlDoubleElement |
302
|
|
|
*/ |
303
|
|
|
public function addButtonInToolbar($caption,$cssStyle=null,$callback=NULL){ |
304
|
|
|
$bt=new HtmlButton("bt-".$caption,$caption,$cssStyle); |
305
|
|
|
return $this->addInToolbar($bt,$callback); |
306
|
|
|
} |
307
|
|
|
|
308
|
|
|
/** |
309
|
|
|
* @param array $captions |
310
|
|
|
* @param boolean $asIcon |
311
|
|
|
* @param callable $callback function($element) |
312
|
|
|
* @return \Ajax\common\html\HtmlDoubleElement |
313
|
|
|
*/ |
314
|
|
|
public function addButtonsInToolbar(array $captions,$asIcon=false,$callback=NULL){ |
315
|
|
|
$bts=new HtmlButtonGroups("",$captions,$asIcon); |
316
|
|
|
return $this->addInToolbar($bts,$callback); |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* @param string $caption |
321
|
|
|
* @param string $icon |
322
|
|
|
* @param boolean $before |
323
|
|
|
* @param boolean $labeled |
324
|
|
|
* @return \Ajax\common\html\HtmlDoubleElement |
325
|
|
|
*/ |
326
|
|
|
public function addLabelledIconButtonInToolbar($caption,$icon,$before=true,$labeled=false){ |
327
|
|
|
$bt=new HtmlButton("",$caption); |
328
|
|
|
$bt->addIcon($icon,$before,$labeled); |
329
|
|
|
return $this->addInToolbar($bt); |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
public function addSubmitInToolbar($identifier,$value,$cssStyle=NULL,$url=NULL,$responseElement=NULL,$parameters=NULL){ |
333
|
|
|
$button=new HtmlButton($identifier,$value,$cssStyle); |
334
|
|
|
$this->_buttonAsSubmit($button,"click",$url,$responseElement,$parameters); |
335
|
|
|
return $this->addInToolbar($button); |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
/** |
339
|
|
|
* Defines a callback function to call for modifying captions |
340
|
|
|
* function parameters are $captions: the captions to modify and $instance: the active model instance |
341
|
|
|
* @param callable $captionCallback |
342
|
|
|
* @return Widget |
343
|
|
|
*/ |
344
|
|
|
public function setCaptionCallback($captionCallback) { |
345
|
|
|
$this->_instanceViewer->setCaptionCallback($captionCallback); |
346
|
|
|
return $this; |
347
|
|
|
} |
348
|
|
|
|
349
|
|
|
/** |
350
|
|
|
* Makes the input fields editable |
351
|
|
|
* @param boolean $_edition |
352
|
|
|
* @return \Ajax\common\Widget |
353
|
|
|
*/ |
354
|
|
|
public function setEdition($_edition=true) { |
355
|
|
|
$this->_edition=$_edition; |
356
|
|
|
return $this; |
357
|
|
|
} |
358
|
|
|
|
359
|
|
|
/** |
360
|
|
|
* Defines the default function which displays fields value |
361
|
|
|
* @param callable $defaultValueFunction function parameters are : $name : the field name, $value : the field value ,$index : the field index, $instance : the active instance of model |
362
|
|
|
* @return \Ajax\common\Widget |
363
|
|
|
*/ |
364
|
|
|
public function setDefaultValueFunction($defaultValueFunction){ |
365
|
|
|
$this->_instanceViewer->setDefaultValueFunction($defaultValueFunction); |
366
|
|
|
return $this; |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* @return callable |
371
|
|
|
*/ |
372
|
|
|
public function getDefaultValueFunction(){ |
373
|
|
|
return $this->_instanceViewer->getDefaultValueFunction(); |
374
|
|
|
} |
375
|
|
|
|
376
|
|
|
/** |
377
|
|
|
* @param string|boolean $disable |
378
|
|
|
* @return string |
379
|
|
|
*/ |
380
|
|
|
public function jsDisabled($disable=true){ |
381
|
|
|
return "$('#".$this->identifier." .ui.input,#".$this->identifier." .ui.dropdown,#".$this->identifier." .ui.checkbox').toggleClass('disabled',".$disable.");"; |
382
|
|
|
} |
383
|
|
|
|
384
|
|
|
/** |
385
|
|
|
* @param string $caption |
386
|
|
|
* @param callable $callback function($element) |
387
|
|
|
* @return \Ajax\common\html\HtmlDoubleElement |
388
|
|
|
*/ |
389
|
|
|
public function addEditButtonInToolbar($caption,$callback=NULL){ |
390
|
|
|
$bt=new HtmlButton($this->identifier."-editBtn",$caption); |
391
|
|
|
$bt->setToggle(); |
392
|
|
|
$bt->setActive($this->_edition); |
393
|
|
|
$bt->onClick($this->jsDisabled(Javascript::prep_value("!$(event.target).hasClass('active')"))); |
394
|
|
|
return $this->addInToolbar($bt,$callback); |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
public function setToolbar(HtmlMenu $_toolbar) { |
398
|
|
|
$this->_toolbar=$_toolbar; |
399
|
|
|
return $this; |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
public function setToolbarPosition($_toolbarPosition) { |
403
|
|
|
$this->_toolbarPosition=$_toolbarPosition; |
404
|
|
|
return $this; |
405
|
|
|
} |
406
|
|
|
|
407
|
|
|
public function getForm() { |
408
|
|
|
if(!isset($this->_form)){ |
409
|
|
|
$this->_form=new HtmlForm("frm-".$this->identifier); |
410
|
|
|
$this->setEdition(true); |
411
|
|
|
} |
412
|
|
|
return $this->_form; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
public function run(JsUtils $js){ |
416
|
|
|
parent::run($js); |
417
|
|
|
if(isset($this->_form)){ |
418
|
|
|
$this->runForm($js); |
419
|
|
|
} |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
protected function runForm(JsUtils $js){ |
423
|
|
|
$fields=$this->getContentInstances(HtmlFormField::class); |
424
|
|
|
foreach ($fields as $field){ |
425
|
|
|
$this->_form->addField($field); |
426
|
|
|
} |
427
|
|
|
return $this->_form->run($js); |
428
|
|
|
} |
429
|
|
|
|
430
|
|
|
protected function _compileForm(){ |
431
|
|
|
if(isset($this->_form)){ |
432
|
|
|
$noValidate=""; |
433
|
|
|
if(\sizeof($this->_form->getValidationParams())>0) |
434
|
|
|
$noValidate="novalidate"; |
435
|
|
|
$this->wrapContent("<form class='ui form' id='frm-".$this->identifier."' name='frm-".$this->identifier."' ".$noValidate.">","</form>"); |
436
|
|
|
} |
437
|
|
|
} |
438
|
|
|
|
439
|
|
|
/** |
440
|
|
|
* Sets the parameters for the Form validation (on, inline, delay...) |
441
|
|
|
* @param array $_validationParams example : ["on"=>"blur","inline"=>true] |
442
|
|
|
* @return Widget |
443
|
|
|
* @see https://semantic-ui.com/behaviors/form.html#/settings |
444
|
|
|
*/ |
445
|
|
|
public function setValidationParams(array $_validationParams) { |
446
|
|
|
$this->getForm()->setValidationParams($_validationParams); |
447
|
|
|
return $this; |
448
|
|
|
} |
449
|
|
|
|
450
|
|
|
public function moveFieldTo($from,$to){ |
451
|
|
|
return $this->_instanceViewer->moveFieldTo($from, $to); |
452
|
|
|
} |
453
|
|
|
|
454
|
|
|
public function swapFields($index1,$index2){ |
455
|
|
|
$index1=$this->_getIndex($index1); |
456
|
|
|
$index2=$this->_getIndex($index2); |
457
|
|
|
return $this->_instanceViewer->swapFields($index1, $index2); |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
public function removeField($index){ |
461
|
|
|
$index=$this->_getIndex($index); |
462
|
|
|
$this->_instanceViewer->removeField($index); |
463
|
|
|
return $this; |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
public function asModal($header=null){ |
467
|
|
|
$modal=new HtmlModal("modal-".$this->identifier,$header); |
468
|
|
|
$modal->setContent($this); |
469
|
|
|
if(isset($this->_form)){ |
470
|
|
|
$this->_form->onSuccess($modal->jsHide()); |
471
|
|
|
} |
472
|
|
|
return $modal; |
473
|
|
|
} |
474
|
|
|
|
475
|
|
|
public function addToProperty($name, $value, $separator=" ") { |
476
|
|
|
return $this->getHtmlComponent()->addToProperty($name,$value,$separator); |
477
|
|
|
} |
478
|
|
|
/** |
479
|
|
|
* @return mixed |
480
|
|
|
*/ |
481
|
|
|
public function getModelInstance() { |
482
|
|
|
return $this->_modelInstance; |
483
|
|
|
} |
484
|
|
|
|
485
|
|
|
/** |
486
|
|
|
* @return mixed true if widget has validation rules |
487
|
|
|
*/ |
488
|
|
|
public function hasRules() { |
489
|
|
|
return $this->_hasRules; |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
|
493
|
|
|
} |
494
|
|
|
|