1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* This file is part of the fangface/yii2-concord package |
4
|
|
|
* |
5
|
|
|
* For the full copyright and license information, please view |
6
|
|
|
* the file LICENSE.md that was distributed with this source code. |
7
|
|
|
* |
8
|
|
|
* @package fangface/yii2-concord |
9
|
|
|
* @author Fangface <[email protected]> |
10
|
|
|
* @copyright Copyright (c) 2014 Fangface <[email protected]> |
11
|
|
|
* @license https://github.com/fangface/yii2-concord/blob/master/LICENSE.md MIT License |
12
|
|
|
* |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace fangface\forms; |
16
|
|
|
|
17
|
|
|
use backend\assets\BootstrapMaxlengthAsset; |
18
|
|
|
use backend\assets\BootstrapPasswordStrengthAsset; |
19
|
|
|
use backend\assets\BootstrapSwitchAsset; |
20
|
|
|
use backend\assets\ICheckAsset; |
21
|
|
|
use backend\assets\InputMaskAsset; |
22
|
|
|
use backend\models\AdminUser; |
23
|
|
|
use fangface\base\traits\AttributeSupportInterface; |
24
|
|
|
use fangface\db\ActiveRecord; |
25
|
|
|
use fangface\db\ActiveRecordReadOnlyInterface; |
26
|
|
|
use fangface\forms\ActiveField; |
27
|
|
|
use fangface\forms\ActiveForm; |
28
|
|
|
use fangface\forms\InputField; |
29
|
|
|
use fangface\widgets\WidgetTrait; |
30
|
|
|
use Yii; |
31
|
|
|
use yii\base\Model; |
32
|
|
|
use yii\base\Widget; |
33
|
|
|
use yii\db\ActiveRecord as YiiActiveRecord; |
34
|
|
|
use yii\helpers\ArrayHelper; |
35
|
|
|
use yii\helpers\Html; |
36
|
|
|
use yii\helpers\Json; |
37
|
|
|
|
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* Form Builder |
41
|
|
|
*/ |
42
|
|
|
class FormBuilder extends Widget |
43
|
|
|
{ |
44
|
|
|
use WidgetTrait; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @var ActiveForm The form that this field is associated with. |
48
|
|
|
*/ |
49
|
|
|
public $form; |
50
|
|
|
/** |
51
|
|
|
* @var Model|ActiveRecord The data model that this field is associated with |
52
|
|
|
*/ |
53
|
|
|
public $model; |
54
|
|
|
/** |
55
|
|
|
* @var array The model attributes and config for processing |
56
|
|
|
*/ |
57
|
|
|
public $attributes = []; |
58
|
|
|
/** |
59
|
|
|
* @var string name of form |
60
|
|
|
*/ |
61
|
|
|
public $formName; |
62
|
|
|
/** |
63
|
|
|
* @var boolean should model level readOnly be ignored |
64
|
|
|
*/ |
65
|
|
|
public $ignoreReadOnly = false; |
66
|
|
|
/** |
67
|
|
|
* @var boolean should model level edit locks be ignored |
68
|
|
|
*/ |
69
|
|
|
public $ignoreIsEditLocked = false; |
70
|
|
|
/** |
71
|
|
|
* @var string default checkbox plugin, options 'make-switch' or 'icheck', default is null |
72
|
|
|
*/ |
73
|
|
|
public $defaultCheckboxPlugin = null; |
74
|
|
|
/** |
75
|
|
|
* @var string which attribute field should be given the default focus |
76
|
|
|
*/ |
77
|
|
|
public $defaultFocus = null; |
78
|
|
|
/** |
79
|
|
|
* @var string which attribute field should be given the default focus and content selected |
80
|
|
|
*/ |
81
|
|
|
public $defaultFocusSelect = null; |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @var array|null holds table schema info for the current model when supported andrequired |
85
|
|
|
*/ |
86
|
|
|
private $spec = null; |
87
|
|
|
|
88
|
|
|
public function run() |
89
|
|
|
{ |
90
|
|
|
if ($this->attributes) { |
|
|
|
|
91
|
|
|
echo $this->renderFieldSet(); |
92
|
|
|
} |
93
|
|
|
parent::run(); |
94
|
|
|
} |
95
|
|
|
|
96
|
|
|
private function renderFieldSet() |
97
|
|
|
{ |
98
|
|
|
foreach ($this->attributes as $attribute => $settings) { |
99
|
|
|
echo $this->renderActiveInput($this->form, $this->model, $attribute, $settings); |
100
|
|
|
} |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
/** |
104
|
|
|
* Render ActiveField input based on provided settings |
105
|
|
|
* |
106
|
|
|
* @param ActiveForm $form |
107
|
|
|
* @param Model|ActiveRecord $model |
108
|
|
|
* @param string $attribute |
109
|
|
|
* @param array $settings |
110
|
|
|
* @return ActiveField|NULL|string |
111
|
|
|
*/ |
112
|
|
|
private function renderActiveInput($form, $model, $attribute, $settings) |
113
|
|
|
{ |
114
|
|
|
if (is_string($settings) && $settings) { |
115
|
|
|
// no settings have been provided for the attribute so $settings will be the attribute name |
116
|
|
|
$attribute = $settings; |
117
|
|
|
$settings = []; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
$settingsIn = $settings; |
121
|
|
|
|
122
|
|
|
if ($model instanceof AttributeSupportInterface) { |
123
|
|
|
//$activeConfig = $model->getAttributeConfig($attribute, 'active'); |
124
|
|
|
$activeConfig = $model->getActiveFieldSettings($attribute); |
125
|
|
|
if ($activeConfig) { |
126
|
|
|
$settings = array_merge($activeConfig, $settings); |
127
|
|
|
} |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
$spec = false; |
131
|
|
|
if ($model instanceof YiiActiveRecord) { |
132
|
|
|
if ($this->spec === null) { |
133
|
|
|
$this->spec = $this->model->getTableSchema()->columns; |
|
|
|
|
134
|
|
|
} |
135
|
|
|
if ($this->spec && isset($this->spec[$attribute])) { |
136
|
|
|
$spec = (isset($this->spec[$attribute]) ? $this->spec[$attribute] : false); |
137
|
|
|
} |
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
$type = ArrayHelper::getValue($settings, 'type', null); |
|
|
|
|
141
|
|
|
$typeAutomatic = false; |
142
|
|
|
$label = null; |
143
|
|
|
|
144
|
|
|
$items = ArrayHelper::getValue($settings, 'items', []); |
|
|
|
|
145
|
|
|
if ($items instanceof \Closure) { |
146
|
|
|
$items = $items($model, $attribute); |
147
|
|
|
} |
148
|
|
|
if (!($items)) { |
149
|
|
|
if (is_array($spec->enumValues) && $spec->enumValues) { |
|
|
|
|
150
|
|
|
foreach ($spec->enumValues as $k => $v) { |
151
|
|
|
if (is_string($v) && $v == '') { |
152
|
|
|
} else { |
153
|
|
|
$items[$v] = $v; |
154
|
|
|
} |
155
|
|
|
} |
156
|
|
|
} |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
$allowClear = false; |
160
|
|
|
|
161
|
|
|
if ($type === null && $items) { |
162
|
|
|
// we have been given items so assume a drop down list |
163
|
|
|
$type = InputField::INPUT_DROPDOWN_LIST; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
if ($type === null) { |
167
|
|
|
// try to guess the appropriate type |
168
|
|
|
switch ($attribute) |
169
|
|
|
{ |
170
|
|
|
case 'created_at': |
171
|
|
|
case 'createdAt': |
172
|
|
|
$type = InputField::INPUT_STATIC; |
173
|
|
|
$label = $model->getAttributeConfig($attribute, 'label'); |
174
|
|
|
$label = (!$label ? ArrayHelper::getValue($settings, 'label', false) : $label); |
|
|
|
|
175
|
|
|
$label = (!$label ? 'Created' : $label); |
176
|
|
|
$createAttribute = ($attribute == 'created_at' ? 'created_by' : 'createdBy'); |
177
|
|
|
if ($model->hasAttribute($createAttribute)) { |
178
|
|
|
if ($model->$createAttribute == Yii::$app->user->identity->id) { |
179
|
|
|
$settings['options']['value'] = $model->$attribute . ' by ' . Yii::$app->user->identity->display_name; |
180
|
|
|
} else { |
181
|
|
|
$createData = AdminUser::find()->select('display_name')->where(['id' => $model->$createAttribute])->limit(1)->asArray()->column(); |
182
|
|
|
$settings['options']['value'] = $model->$attribute . ' by ' . $createData[0]; |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
break; |
186
|
|
|
case 'modified_at': |
187
|
|
|
case 'modifiedAt': |
188
|
|
|
$type = InputField::INPUT_STATIC; |
189
|
|
|
$label = $model->getAttributeConfig($attribute, 'label'); |
190
|
|
|
$label = (!$label ? ArrayHelper::getValue($settings, 'label', false) : $label); |
|
|
|
|
191
|
|
|
$label = (!$label ? 'Last Modified' : $label); |
192
|
|
|
$modifiedAttribute = ($attribute == 'modified_at' ? 'modified_by' : 'modifiedBy'); |
193
|
|
|
if ($model->hasAttribute($modifiedAttribute)) { |
194
|
|
|
if ($model->$modifiedAttribute == Yii::$app->user->identity->id) { |
195
|
|
|
$settings['options']['value'] = $model->$attribute . ' by ' . Yii::$app->user->identity->display_name; |
196
|
|
|
} else { |
197
|
|
|
$modifiedData = AdminUser::find()->select('display_name')->where(['id' => $model->$modifiedAttribute])->limit(1)->asArray()->column(); |
198
|
|
|
$settings['options']['value'] = $model->$attribute . ' by ' . $modifiedData[0]; |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
break; |
202
|
|
|
case 'created_by': |
203
|
|
|
case 'createdBy': |
204
|
|
|
case 'modified_by': |
205
|
|
|
case 'modifiedBy': |
206
|
|
|
case 'id': |
207
|
|
|
$type = InputField::INPUT_STATIC; |
208
|
|
|
break; |
209
|
|
|
default: |
210
|
|
|
$type = InputField::getDefaultInputFieldType($attribute, $spec, $settings); |
|
|
|
|
211
|
|
|
if ($type) { |
212
|
|
|
$typeAutomatic = true; |
213
|
|
|
} |
214
|
|
|
} |
215
|
|
|
|
216
|
|
|
if ($type === null) { |
217
|
|
|
return ''; |
218
|
|
|
} |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
$fieldConfig = ArrayHelper::getValue($settings, 'fieldConfig', []); |
|
|
|
|
222
|
|
|
$options = ArrayHelper::getValue($settings, 'options', []); |
|
|
|
|
223
|
|
|
$hint = ArrayHelper::getValue($settings, 'hint', null); |
|
|
|
|
224
|
|
|
$icon = ArrayHelper::getValue($settings, 'icon', ($typeAutomatic && InputField::getIsIconSupportedFieldType($type) ? true : null)); |
|
|
|
|
225
|
|
|
$tooltip = ArrayHelper::getValue($settings, 'tooltip', null); |
|
|
|
|
226
|
|
|
$focus = ArrayHelper::getValue($settings, 'focus', null); |
|
|
|
|
227
|
|
|
$addon = ArrayHelper::getValue($settings, 'addon', null); |
|
|
|
|
228
|
|
|
$clear = ArrayHelper::getValue($settings, 'clear', null); |
|
|
|
|
229
|
|
|
|
230
|
|
|
$label = ($label === null ? ArrayHelper::getValue($settingsIn, 'label', $label) : $label); |
|
|
|
|
231
|
|
|
$label = ($label === null ? $this->model->getAttributeLabel($attribute) : $label); |
232
|
|
|
|
233
|
|
|
$hideuseInlineHelp = $useLabelColumn = ArrayHelper::getValue($settings, 'useInlineHelp', true); |
|
|
|
|
234
|
|
|
|
235
|
|
|
// is the current field read only |
236
|
|
|
$readOnly = false; |
237
|
|
|
if ($type == InputField::INPUT_READONLY) { |
238
|
|
|
$type = InputField::INPUT_TEXT; |
239
|
|
|
$readOnly = true; |
240
|
|
|
} elseif (!$this->ignoreReadOnly && $model instanceof ActiveRecordReadOnlyInterface && $model->getReadOnly()) { |
241
|
|
|
$readOnly = true; |
242
|
|
|
} elseif (method_exists($form, 'isEditLocked') && $form->isEditLocked()) { |
243
|
|
|
$readOnly = true; |
244
|
|
|
} elseif (!$this->ignoreIsEditLocked && method_exists($model, 'isEditLocked') && $model->isEditLocked()) { |
245
|
|
|
$readOnly = true; |
246
|
|
|
} elseif (ArrayHelper::getValue($settings, 'readonly', false)) { |
|
|
|
|
247
|
|
|
$readOnly = true; |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/* |
251
|
|
|
* apply any conversions if required or extra settings to apply |
252
|
|
|
*/ |
253
|
|
|
switch ($type) { |
254
|
|
|
case InputField::INPUT_CHECKBOX: |
255
|
|
|
if (!ArrayHelper::keyExists('class', $options)) { |
256
|
|
|
// should we apply a default checkbox style or plugin |
257
|
|
|
if ($this->defaultCheckboxPlugin !== null && $this->defaultCheckboxPlugin) { |
258
|
|
|
Html::addCssClass($options, $this->defaultCheckboxPlugin); |
259
|
|
|
} |
260
|
|
|
} |
261
|
|
|
break; |
262
|
|
|
case InputField::INPUT_CHECKBOX_BASIC: |
263
|
|
|
// revert back to basic checkbox |
264
|
|
|
$type = InputField::INPUT_CHECKBOX; |
265
|
|
|
break; |
266
|
|
|
case InputField::INPUT_CHECKBOX_ICHECK: |
267
|
|
|
// revert to basic checkbox with icheck class applied |
268
|
|
|
$type = InputField::INPUT_CHECKBOX; |
269
|
|
|
Html::addCssClass($options, 'icheck'); |
270
|
|
|
break; |
271
|
|
|
case InputField::INPUT_CHECKBOX_SWITCH: |
272
|
|
|
// revert to basic checkbox with make-switch class applied |
273
|
|
|
$type = InputField::INPUT_CHECKBOX; |
274
|
|
|
Html::addCssClass($options, 'make-switch'); |
275
|
|
|
break; |
276
|
|
|
case InputField::INPUT_DATE: |
277
|
|
|
$options['data-maxlength'] = false; |
278
|
|
|
$options['data-inputmask'] = ['alias' => 'yyyy-mm-dd']; |
279
|
|
|
$options['maxlength'] = 10; |
280
|
|
|
$addon = [ |
281
|
|
|
'append' => [ |
282
|
|
|
[ |
283
|
|
|
'class' => 'glyphicon glyphicon-th show-datepicker', |
284
|
|
|
'title' => 'Click to select date', |
285
|
|
|
], |
286
|
|
|
], |
287
|
|
|
'groupOptions' => [ |
288
|
|
|
'class' => 'date input-small', |
289
|
|
|
] |
290
|
|
|
]; |
291
|
|
|
//$options['widgetOptions']['pluginOptions']['autoclose'] = false; // optionally override plugin or widget options |
292
|
|
|
$clear = ($clear !== false ? true : $clear); |
293
|
|
|
$allowClear['input'] = 'input'; |
294
|
|
|
break; |
295
|
|
|
case InputField::INPUT_DATETIME: |
296
|
|
|
$options['data-maxlength'] = false; |
297
|
|
|
$options['data-inputmask'] = ['alias' => 'yyyy-mm-dd hh:mm:ss']; |
298
|
|
|
//$options['data-inputmask'] = ['alias' => 'yyyy-mm-dd hh:mm']; |
299
|
|
|
$options['maxlength'] = 19; |
300
|
|
|
$addon = [ |
301
|
|
|
'append' => [ |
302
|
|
|
[ |
303
|
|
|
'class' => 'glyphicon glyphicon-th show-date-time-picker', |
304
|
|
|
'title' => 'Click to select date', |
305
|
|
|
], |
306
|
|
|
], |
307
|
|
|
'groupOptions' => [ |
308
|
|
|
'class' => 'date input-medium', |
309
|
|
|
] |
310
|
|
|
]; |
311
|
|
|
//$options['widgetOptions']['pluginOptions']['autoclose'] = false; // optionally override plugin or widget options |
312
|
|
|
$clear = ($clear !== false ? true : $clear); |
313
|
|
|
$allowClear['input'] = 'input'; |
314
|
|
|
break; |
315
|
|
|
case InputField::INPUT_YEAR: |
316
|
|
|
$options['data-maxlength'] = false; |
317
|
|
|
$options['data-inputmask'] = ['mask' => '9999']; |
318
|
|
|
break; |
319
|
|
|
case InputField::INPUT_TIME: |
320
|
|
|
$options['data-maxlength'] = false; |
321
|
|
|
$options['data-inputmask'] = ['alias' => 'hh:mm:ss']; |
322
|
|
|
//$options['data-inputmask'] = ['alias' => 'hh:mm']; |
323
|
|
|
$options['maxlength'] = 8; |
324
|
|
|
$addon = [ |
325
|
|
|
'append' => [ |
326
|
|
|
[ |
327
|
|
|
'class' => 'glyphicon glyphicon-th clickable show-timepicker', |
328
|
|
|
'title' => 'Click to select time', |
329
|
|
|
], |
330
|
|
|
], |
331
|
|
|
'groupOptions' => [ |
332
|
|
|
'class' => 'input-small', |
333
|
|
|
] |
334
|
|
|
]; |
335
|
|
|
$clear = ($clear !== false ? true : $clear); |
336
|
|
|
$allowClear['input'] = 'time'; |
337
|
|
|
break; |
338
|
|
|
case InputField::INPUT_INTEGER: |
339
|
|
|
$options['data-maxlength'] = false; |
340
|
|
|
$options['data-inputmask'] = (isset($options['data-inputmask']) ? $options['data-inputmask'] : []); |
341
|
|
|
$options['maxlength'] = (isset($options['maxlength']) ? $options['maxlength'] : $spec->size + ($spec->unsigned ? 0 : 1)); |
342
|
|
|
$defaults = [ |
343
|
|
|
'alias' => 'numeric', |
344
|
|
|
'allowMinus' => !$spec->unsigned, |
345
|
|
|
'digits' => 0, |
346
|
|
|
'rightAlign' => true, |
347
|
|
|
]; |
348
|
|
|
$options['data-inputmask'] = array_merge($defaults, $options['data-inputmask']); |
349
|
|
|
$clear = ($clear !== false ? true : $clear); |
350
|
|
|
$allowClear['input'] = 'integer'; |
351
|
|
|
//$allowClear['value'] = '0'; |
352
|
|
|
break; |
353
|
|
|
case InputField::INPUT_DECIMAL: |
354
|
|
|
$options['data-maxlength'] = false; |
355
|
|
|
$options['data-inputmask'] = (isset($options['data-inputmask']) ? $options['data-inputmask'] : []); |
356
|
|
|
$options['maxlength'] = (isset($options['maxlength']) ? $options['maxlength'] : $spec->size + 1 + ($spec->unsigned ? 0 : 1)); |
357
|
|
|
$defaults = [ |
358
|
|
|
'alias' => 'decimal', |
359
|
|
|
'allowMinus' => !$spec->unsigned, |
360
|
|
|
'integerDigits' => $spec->size - $spec->scale, |
361
|
|
|
'digits' => $spec->scale, |
362
|
|
|
'rightAlign' => true, |
363
|
|
|
]; |
364
|
|
|
$options['data-inputmask'] = array_merge($defaults, $options['data-inputmask']); |
365
|
|
|
$clear = ($clear !== false ? true : $clear); |
366
|
|
|
$allowClear['input'] = 'decimal'; |
367
|
|
|
if ($spec->scale != 2) { |
368
|
|
|
$allowClear['value'] = number_format(0, $spec->scale); |
369
|
|
|
} |
370
|
|
|
break; |
371
|
|
|
case InputField::INPUT_COLOR: |
372
|
|
|
$options['data-maxlength'] = false; |
373
|
|
|
$allowClear['input'] = 'colorpicker'; |
374
|
|
|
break; |
375
|
|
|
case InputField::INPUT_MINI_COLORS: |
376
|
|
|
$options['data-maxlength'] = false; |
377
|
|
|
$allowClear['input'] = 'minicolors'; |
378
|
|
|
break; |
379
|
|
|
case InputField::INPUT_TEXT: |
380
|
|
|
case InputField::INPUT_TEXTAREA: |
381
|
|
|
$allowClear['input'] = 'input'; |
382
|
|
|
break; |
383
|
|
|
case InputField::INPUT_DROPDOWN_LIST: |
384
|
|
|
case InputField::INPUT_LIST_BOX: |
385
|
|
|
// will select first item in drop down list |
386
|
|
|
$allowClear['input'] = 'select'; |
387
|
|
|
break; |
388
|
|
|
case InputField::INPUT_SELECT2: |
389
|
|
|
case InputField::INPUT_SELECT2_MULTI: |
390
|
|
|
$allowClear['input'] = 'select2'; |
391
|
|
|
break; |
392
|
|
|
case InputField::INPUT_SELECT_PICKER: |
393
|
|
|
case InputField::INPUT_SELECT_PICKER_MULTI: |
394
|
|
|
$allowClear['input'] = 'selectpicker'; |
395
|
|
|
break; |
396
|
|
|
case InputField::INPUT_MULTISELECT: |
397
|
|
|
$allowClear['input'] = 'multiselect'; |
398
|
|
|
break; |
399
|
|
|
default: |
400
|
|
|
} |
401
|
|
|
|
402
|
|
|
/** |
403
|
|
|
* @var ActiveField $field |
404
|
|
|
*/ |
405
|
|
|
$field = $form->field($model, $attribute, $fieldConfig); |
406
|
|
|
|
407
|
|
|
switch ($type) { |
408
|
|
|
|
409
|
|
|
case InputField::INPUT_HIDDEN: |
410
|
|
|
case InputField::INPUT_STATIC: |
411
|
|
|
|
412
|
|
|
return static::getInput($field, $type, [$options], $label, $hint, $icon, $tooltip, null); |
|
|
|
|
413
|
|
|
break; |
|
|
|
|
414
|
|
|
|
415
|
|
|
case InputField::INPUT_TEXT: |
416
|
|
|
case InputField::INPUT_PASSWORD: |
417
|
|
|
case InputField::INPUT_PASSWORD_STRENGTH: |
418
|
|
|
case InputField::INPUT_TEXTAREA: |
419
|
|
|
case InputField::INPUT_INTEGER: |
420
|
|
|
case InputField::INPUT_DECIMAL: |
421
|
|
|
case InputField::INPUT_YEAR: |
422
|
|
|
case InputField::INPUT_TIME: |
423
|
|
|
case InputField::INPUT_DATE: |
424
|
|
|
case InputField::INPUT_DATETIME: |
425
|
|
|
case InputField::INPUT_COLOR: |
426
|
|
|
case InputField::INPUT_MINI_COLORS: |
427
|
|
|
|
428
|
|
|
Html::addCssClass($options, 'form-control'); |
429
|
|
|
if (ArrayHelper::getValue($settings, 'placeholder', null) !== null) { |
|
|
|
|
430
|
|
|
$options['placeholder'] = ArrayHelper::getValue($settings, 'placeholder', null); |
|
|
|
|
431
|
|
|
} |
432
|
|
|
if ($readOnly) { |
433
|
|
|
$options['disabled'] = 'disabled'; |
434
|
|
|
$clear = false; |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
$clear = ($clear === true ? true : false); // null defaults to false if still null at this stage |
438
|
|
|
if ($clear === false) { |
439
|
|
|
$allowClear = false; |
440
|
|
|
} |
441
|
|
|
|
442
|
|
|
$maxlength = ArrayHelper::getValue($options, 'maxlength', ($spec ? $spec->size : 0)); |
443
|
|
|
$inputSize = ArrayHelper::getValue($settings, 'size', InputField::INPUT_SIZE_AUTO); |
|
|
|
|
444
|
|
|
|
445
|
|
|
if ($maxlength) { |
446
|
|
|
|
447
|
|
|
$inputSize = $this->getDefaultInputSize($inputSize, $maxlength, $icon, $tooltip); |
448
|
|
|
|
449
|
|
|
if (!$readOnly) { |
450
|
|
|
|
451
|
|
|
$options['maxlength'] = $maxlength; |
452
|
|
|
if (isset($options['data-maxlength']) && !$options['data-maxlength']) { |
453
|
|
|
// do not use the plugin |
454
|
|
|
unset($options['data-maxlength']); |
455
|
|
|
} else { |
456
|
|
|
BootstrapMaxlengthAsset::register($this->getView()); |
457
|
|
|
if (!isset($options['data-maxlength']['threshold'])) { |
458
|
|
|
if ($maxlength > 99) { |
459
|
|
|
$options['data-maxlength']['threshold'] = '50'; |
460
|
|
|
} elseif ($maxlength > 50) { |
461
|
|
|
$options['data-maxlength']['threshold'] = '20'; |
462
|
|
|
} elseif ($maxlength > 10) { |
463
|
|
|
$options['data-maxlength']['threshold'] = '10'; |
464
|
|
|
} else { |
465
|
|
|
$options['data-maxlength']['threshold'] = $maxlength - 1; |
466
|
|
|
} |
467
|
|
|
} |
468
|
|
|
if (!isset($options['data-maxlength']['placement'])) { |
469
|
|
|
$options['data-maxlength']['placement'] = 'top'; |
470
|
|
|
} |
471
|
|
|
$options['data-maxlength'] = Json::encode($options['data-maxlength']); |
472
|
|
|
Html::addCssClass($options, 'bs-max-me'); |
473
|
|
|
} |
474
|
|
|
|
475
|
|
|
if ($type == InputField::INPUT_PASSWORD_STRENGTH) { |
476
|
|
|
BootstrapPasswordStrengthAsset::register($this->getView()); |
477
|
|
|
Html::addCssClass($options, 'strength-me'); |
478
|
|
|
} |
479
|
|
|
|
480
|
|
|
$options = $this->setFocus($options, $field, $attribute, $focus); |
481
|
|
|
} |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
if (isset($options['data-inputmask'])) { |
485
|
|
|
Html::addCssClass($options, 'mask-me'); |
486
|
|
|
if (isset($options['data-inputmask'])) { |
487
|
|
|
$options['data-inputmask'] = Json::encode($options['data-inputmask']); |
488
|
|
|
} |
489
|
|
|
InputMaskAsset::register($this->getView()); |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
$options = $this->applyInputSize($inputSize, $options); |
493
|
|
|
|
494
|
|
|
// by default make inputs select their own content when they get focus |
495
|
|
|
Html::addCssClass($options, 'select-me'); |
496
|
|
|
|
497
|
|
|
$options = $this->convertOptionsForWidgets($type, $options); |
498
|
|
|
|
499
|
|
|
if ($allowClear) { |
500
|
|
|
$allowClear['size'] = $inputSize; |
501
|
|
|
} |
502
|
|
|
|
503
|
|
|
return static::getInput($field, $type, [$options], $label, $hint, $icon, $tooltip, $addon, $allowClear); |
|
|
|
|
504
|
|
|
break; |
|
|
|
|
505
|
|
|
|
506
|
|
|
case InputField::INPUT_FILE: |
507
|
|
|
return static::getInput($field, $type, [$options], $label, $hint, $icon, $tooltip, $addon); |
|
|
|
|
508
|
|
|
break; |
|
|
|
|
509
|
|
|
|
510
|
|
|
case InputField::INPUT_CHECKBOX: |
511
|
|
|
$enclosedByLabel = ArrayHelper::getValue($settings, 'enclosedByLabel', false); |
|
|
|
|
512
|
|
|
$useLabelColumn = ArrayHelper::getValue($settings, 'useLabelColumn', true); |
|
|
|
|
513
|
|
|
if ($label !== null && $label) { |
514
|
|
|
$options['label'] = ($useLabelColumn ? null : $label); |
515
|
|
|
} |
516
|
|
|
$useInlineHelp = ArrayHelper::getValue($settings, 'useInlineHelp', true); |
|
|
|
|
517
|
|
|
if ($useInlineHelp) { |
518
|
|
|
$field->hintOptions = [ |
519
|
|
|
'tag' => 'span', |
520
|
|
|
'class' => 'help-inline', |
521
|
|
|
]; |
522
|
|
|
$field->template = str_replace("\n{error}", '', $field->template); |
523
|
|
|
} |
524
|
|
|
|
525
|
|
|
if ($readOnly) { |
526
|
|
|
$options['disabled'] = 'disabled'; |
527
|
|
|
} |
528
|
|
|
|
529
|
|
|
if (strpos(ArrayHelper::getValue($options, 'class', ''), 'make-switch') !== false) { |
530
|
|
|
//$options['data-on-text'] = ArrayHelper::getValue($options, 'data-on-text', 'ON'); // value can be an icon e.g. <i class='fa fa-check'></i> |
531
|
|
|
//$options['data-off-text'] = ArrayHelper::getValue($options, 'data-off-text', 'OFF'); // value can be an icon e.g. <i class='fa fa-times'></i> |
532
|
|
|
//$options['data-on-color'] = ArrayHelper::getValue($options, 'data-on-color', 'primary'); |
533
|
|
|
//$options['data-off-color'] = ArrayHelper::getValue($options, 'data-off-color', 'default'); |
534
|
|
|
$options['data-size'] = ArrayHelper::getValue($options, 'data-size', 'small'); |
535
|
|
|
BootstrapSwitchAsset::register($this->getView()); |
536
|
|
|
} elseif (strpos(ArrayHelper::getValue($options, 'class', ''), 'icheck') !== false) { |
537
|
|
|
//Html::addCssClass($options, 'icheck'); |
538
|
|
|
$options['data-checkbox'] = ArrayHelper::getValue($options, 'data-checkbox', 'icheckbox_square-blue'); |
539
|
|
|
ICheckAsset::register($this->getView()); |
540
|
|
|
} |
541
|
|
|
|
542
|
|
|
return $this->getInput($field->$type($options, $enclosedByLabel), $type, null, ($useLabelColumn ? $label : null), $hint); |
543
|
|
|
break; |
|
|
|
|
544
|
|
|
|
545
|
|
|
case InputField::INPUT_RAW: |
546
|
|
|
$value = ArrayHelper::getValue($settings, 'value', ''); |
|
|
|
|
547
|
|
|
if ($value instanceof \Closure) { |
548
|
|
|
$value = $value(); |
549
|
|
|
} |
550
|
|
|
return $value; |
551
|
|
|
break; |
|
|
|
|
552
|
|
|
|
553
|
|
|
case InputField::INPUT_SELECT_PICKER_MULTI: |
554
|
|
|
case InputField::INPUT_SELECT2_MULTI: |
555
|
|
|
case InputField::INPUT_MULTISELECT: |
556
|
|
|
$isMultiple = true; |
557
|
|
|
// no break |
558
|
|
|
case InputField::INPUT_DROPDOWN_LIST: |
559
|
|
|
case InputField::INPUT_LIST_BOX: |
560
|
|
|
case InputField::INPUT_SELECT2: |
561
|
|
|
case InputField::INPUT_SELECT_PICKER: |
562
|
|
|
case InputField::INPUT_SELECT_SPLITTER: |
563
|
|
|
|
564
|
|
|
$isMultiple = ((isset($isMultiple) && $isMultiple) || isset($options['multiple']) ? true : false); |
|
|
|
|
565
|
|
|
if ($isMultiple) { |
566
|
|
|
$options['multiple'] = 'multiple'; |
567
|
|
|
$this->model->setAttribute($attribute, explode('|',$this->model->getAttribute($attribute))); |
|
|
|
|
568
|
|
|
} |
569
|
|
|
|
570
|
|
|
if (($isMultiple && !InputField::getIsWidgetFromFieldType($type)) || $type == InputField::INPUT_LIST_BOX) { |
571
|
|
|
$options['size'] = ArrayHelper::getValue($options, 'size', 4); |
572
|
|
|
} |
573
|
|
|
|
574
|
|
|
Html::addCssClass($options, 'form-control'); |
575
|
|
|
if (ArrayHelper::getValue($settings, 'placeholder', null) !== null) { |
|
|
|
|
576
|
|
|
$options['prompt'] = ArrayHelper::getValue($settings, 'placeholder', null); |
|
|
|
|
577
|
|
|
} |
578
|
|
|
if ($readOnly) { |
579
|
|
|
$options['disabled'] = 'disabled'; |
580
|
|
|
$clear = false; |
581
|
|
|
} else { |
582
|
|
|
$options = $this->setFocus($options, $field, $attribute, $focus); |
583
|
|
|
} |
584
|
|
|
|
585
|
|
|
$clear = ($clear === true ? true : false); // null defaults to false if still null at this stage |
586
|
|
|
if ($clear === false) { |
587
|
|
|
$allowClear = false; |
588
|
|
|
} |
589
|
|
|
|
590
|
|
|
if ($typeAutomatic && !isset($options['prompt'])) { |
591
|
|
|
if ($model->hasAttribute($attribute) && $model->getAttribute($attribute) != '' && $model->getAttribute($attribute) !== null) { |
|
|
|
|
592
|
|
|
// no prompt required by default |
593
|
|
|
} else { |
594
|
|
|
$options['prompt'] = 'Select...'; |
595
|
|
|
$options['promptValue'] = ''; |
596
|
|
|
} |
597
|
|
|
} |
598
|
|
|
|
599
|
|
|
switch ($type) { |
600
|
|
|
case InputField::INPUT_SELECT2: |
601
|
|
|
case InputField::INPUT_SELECT2_MULTI: |
602
|
|
|
case InputField::INPUT_SELECT_PICKER: |
603
|
|
|
case InputField::INPUT_SELECT_PICKER_MULTI: |
604
|
|
|
case InputField::INPUT_SELECT_SPLITTER: |
605
|
|
|
|
606
|
|
|
if (isset($options['prompt']) && $options['prompt'] != '') { |
607
|
|
|
// default value will be blank and convert to null by default |
608
|
|
|
if (($type == InputField::INPUT_SELECT2 || $type == InputField::INPUT_SELECT2_MULTI)) { |
609
|
|
|
$promptValue = (isset($options['promptValue']) ? $options['promptValue'] : '0'); |
610
|
|
|
if (!isset($options['groups'])) { |
611
|
|
|
$options['widgetOptions']['pluginOptions']['placeholder'] = $options['prompt']; |
612
|
|
|
$options['widgetOptions']['pluginOptions']['id'] = $promptValue; |
613
|
|
|
} else { |
614
|
|
|
$promptValue = $options['promptValue']; |
615
|
|
|
$items = array_merge([$promptValue => $options['prompt']], $items); |
616
|
|
|
} |
617
|
|
|
} elseif ($type == InputField::INPUT_SELECT_PICKER || $type == InputField::INPUT_SELECT_PICKER_MULTI) { |
618
|
|
|
$promptValue = (isset($options['promptValue']) ? $options['promptValue'] : ''); |
619
|
|
|
if ($promptValue != '') { |
620
|
|
|
$items = array_merge([$promptValue => $options['prompt']], $items); |
621
|
|
|
} else { |
622
|
|
|
$options['title'] = $options['prompt']; |
623
|
|
|
if (!$isMultiple) { |
624
|
|
|
//wlchere - makes it work well front end but breaks back end when an array is submitted |
625
|
|
|
//$isMultiple = true; |
626
|
|
|
//$options['multiple'] = 'multiple'; |
627
|
|
|
//$options['widgetOptions']['pluginOptions']['maxOptions'] = 1; |
628
|
|
|
} |
629
|
|
|
} |
630
|
|
|
} elseif ($type == InputField::INPUT_SELECT_SPLITTER) { |
631
|
|
|
if (!$isMultiple) { |
632
|
|
|
$promptValue = (isset($options['promptValue']) ? $options['promptValue'] : ''); |
633
|
|
|
$items = array_merge(['' => [$promptValue => $options['prompt']]], $items); |
634
|
|
|
$options['groups'] = (isset($options['groups']) ? $options['groups'] : []); |
635
|
|
|
$options['groups'] = array_merge(['' => ['label' => $options['prompt']]], $options['groups']); |
636
|
|
|
} |
637
|
|
|
} |
638
|
|
|
} |
639
|
|
|
break; |
640
|
|
|
default: |
641
|
|
|
if (!$isMultiple && isset($options['prompt']) && $options['prompt'] != '') { |
642
|
|
|
// default value will be blank and convert to null by default |
643
|
|
|
$promptValue = (isset($options['promptValue']) ? $options['promptValue'] : '0'); |
644
|
|
|
$items = array_merge([$promptValue => $options['prompt']], $items); |
645
|
|
|
} |
646
|
|
|
} |
647
|
|
|
unset($options['prompt']); |
648
|
|
|
unset($options['promptValue']); |
649
|
|
|
|
650
|
|
|
$inputSize = ArrayHelper::getValue($settings, 'size', InputField::INPUT_SIZE_AUTO); |
|
|
|
|
651
|
|
|
$inputSize = $this->getDefaultInputSize($inputSize, 0, $icon, $tooltip); |
652
|
|
|
$options = $this->applyInputSize($inputSize, $options); |
653
|
|
|
|
654
|
|
|
$options = $this->convertOptionsForWidgets($type, $options); |
655
|
|
|
|
656
|
|
|
if ($allowClear) { |
657
|
|
|
$allowClear['size'] = $inputSize; |
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
return $this->getInput($field, $type, [$items, $options], $label, $hint, $icon, $tooltip, $addon, $allowClear); |
661
|
|
|
|
662
|
|
|
break; |
|
|
|
|
663
|
|
|
|
664
|
|
|
case InputField::INPUT_CHECKBOX_LIST: |
665
|
|
|
case InputField::INPUT_CHECKBOX_LIST_ICHECK: |
666
|
|
|
|
667
|
|
|
$this->model->setAttribute($attribute, explode('|',$this->model->getAttribute($attribute))); |
668
|
|
|
|
669
|
|
|
$allowClear['input'] = 'checkbox'; |
670
|
|
|
|
671
|
|
|
if (!isset($options['itemOptions'])) { |
672
|
|
|
$options['itemOptions'] = []; |
673
|
|
|
} |
674
|
|
|
|
675
|
|
|
if (!isset($options['itemOptions']['labelOptions'])) { |
676
|
|
|
$options['itemOptions']['labelOptions'] = []; |
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
$inline = ArrayHelper::getValue($settings, 'inline', false); |
|
|
|
|
680
|
|
|
if ($inline) { |
681
|
|
|
Html::addCssClass($options['itemOptions']['labelOptions'], 'checkbox-inline'); |
682
|
|
|
} else { |
683
|
|
|
// vertically listed so disable form control as well |
684
|
|
|
$settings['noFormControl'] = true; |
685
|
|
|
} |
686
|
|
|
|
687
|
|
|
if (ArrayHelper::getValue($settings, 'noFormControl', false)) { |
|
|
|
|
688
|
|
|
// icon and tooltip will not be supported |
689
|
|
|
$icon = false; |
690
|
|
|
$tooltip = false; |
691
|
|
|
Html::addCssClass($options, 'checkbox-list'); |
692
|
|
|
$allowClear = false; |
693
|
|
|
} else { |
694
|
|
|
// wrap the whole checkbox list in a form-control box |
695
|
|
|
Html::addCssClass($options, 'form-control fc-checkbox-list checkbox-list'); |
696
|
|
|
} |
697
|
|
|
|
698
|
|
|
if ($type == InputField::INPUT_CHECKBOX_LIST_ICHECK) { |
699
|
|
|
$allowClear['input'] = 'icheckbox'; |
700
|
|
|
Html::addCssClass($options['itemOptions'], 'icheck'); |
701
|
|
|
$options['itemOptions']['data-checkbox'] = ArrayHelper::getValue($options['itemOptions'], 'data-checkbox', 'icheckbox_square-blue'); |
702
|
|
|
ICheckAsset::register($this->getView()); |
703
|
|
|
} |
704
|
|
|
|
705
|
|
|
if ($readOnly) { |
706
|
|
|
$options['disabled'] = 'disabled'; |
707
|
|
|
$options['itemOptions']['disabled'] = 'disabled'; |
708
|
|
|
$clear = false; |
709
|
|
|
} |
710
|
|
|
|
711
|
|
|
if ($allowClear) { |
712
|
|
|
$clear = ($clear === true ? true : false); // null defaults to false if still null at this stage |
713
|
|
|
if ($clear === false) { |
714
|
|
|
$allowClear = false; |
715
|
|
|
} |
716
|
|
|
} |
717
|
|
|
|
718
|
|
|
$options = $this->applyInputSize(ArrayHelper::getValue($settings, 'size', InputField::INPUT_SIZE_NONE), $options); |
|
|
|
|
719
|
|
|
|
720
|
|
|
return $this->getInput($field, 'checkboxList' ,[$items, $options], $label, $hint, $icon, $tooltip, $addon, $allowClear); |
721
|
|
|
break; |
|
|
|
|
722
|
|
|
|
723
|
|
|
case InputField::INPUT_RADIO_LIST: |
724
|
|
|
case InputField::INPUT_RADIO_LIST_ICHECK: |
725
|
|
|
|
726
|
|
|
$allowClear['input'] = 'radio'; |
727
|
|
|
|
728
|
|
|
if (!isset($options['itemOptions'])) { |
729
|
|
|
$options['itemOptions'] = []; |
730
|
|
|
} |
731
|
|
|
|
732
|
|
|
if (!isset($options['itemOptions']['labelOptions'])) { |
733
|
|
|
$options['itemOptions']['labelOptions'] = []; |
734
|
|
|
} |
735
|
|
|
|
736
|
|
|
$inline = ArrayHelper::getValue($settings, 'inline', false); |
|
|
|
|
737
|
|
|
if ($inline) { |
738
|
|
|
Html::addCssClass($options['itemOptions']['labelOptions'], 'radio-inline'); |
739
|
|
|
} else { |
740
|
|
|
// vertically listed so disable form control as well |
741
|
|
|
$settings['noFormControl'] = true; |
742
|
|
|
} |
743
|
|
|
|
744
|
|
|
if (ArrayHelper::getValue($settings, 'noFormControl', false)) { |
|
|
|
|
745
|
|
|
// icon and tooltip will not be supported |
746
|
|
|
$icon = false; |
747
|
|
|
$tooltip = false; |
748
|
|
|
Html::addCssClass($options, 'radio-list'); |
749
|
|
|
$allowClear = false; |
750
|
|
|
} else { |
751
|
|
|
// wrap the whole checkbox list in a form-control box |
752
|
|
|
Html::addCssClass($options, 'form-control fc-radio-list radio-list'); |
753
|
|
|
} |
754
|
|
|
|
755
|
|
|
if ($type == InputField::INPUT_RADIO_LIST_ICHECK) { |
756
|
|
|
$allowClear['input'] = 'iradio'; |
757
|
|
|
if (!$inline) { |
758
|
|
|
Html::addCssClass($options['itemOptions']['labelOptions'], 'radio-vertical'); |
759
|
|
|
} |
760
|
|
|
Html::addCssClass($options['itemOptions'], 'icheck'); |
761
|
|
|
$options['itemOptions']['data-radio'] = ArrayHelper::getValue($options['itemOptions'], 'data-radio', 'iradio_square-blue'); |
762
|
|
|
ICheckAsset::register($this->getView()); |
763
|
|
|
} |
764
|
|
|
|
765
|
|
|
if ($readOnly) { |
766
|
|
|
$options['disabled'] = 'disabled'; |
767
|
|
|
$options['itemOptions']['disabled'] = 'disabled'; |
768
|
|
|
$clear = false; |
769
|
|
|
} |
770
|
|
|
|
771
|
|
|
if ($allowClear) { |
772
|
|
|
$clear = ($clear === true ? true : false); // null defaults to false if still null at this stage |
773
|
|
|
if ($clear === false) { |
774
|
|
|
$allowClear = false; |
775
|
|
|
} |
776
|
|
|
} |
777
|
|
|
|
778
|
|
|
$options = $this->applyInputSize(ArrayHelper::getValue($settings, 'size', InputField::INPUT_SIZE_NONE), $options); |
|
|
|
|
779
|
|
|
|
780
|
|
|
return $this->getInput($field, 'radioList', [$items, $options], $label, $hint, $icon, $tooltip, $addon, $allowClear); |
781
|
|
|
break; |
|
|
|
|
782
|
|
|
|
783
|
|
|
case InputField::INPUT_HTML5: |
784
|
|
|
return 'WORK IN PROGRESS: ' . $attribute . ' : ' . $type . '<br/>'; |
785
|
|
|
break; |
|
|
|
|
786
|
|
|
|
787
|
|
|
case InputField::INPUT_EDITOR_CK: |
788
|
|
|
case InputField::INPUT_EDITOR_BS_WYSIHTML5: |
789
|
|
|
case InputField::INPUT_EDITOR_BS_SUMMERNOTE: |
790
|
|
|
|
791
|
|
|
//wlchere move to normal place above plus possibly switch this whole section into textarea above |
792
|
|
|
// and make use of InputField::getIsEditorFromFieldType($type) |
793
|
|
|
$allowClear['input'] = 'val'; |
794
|
|
|
|
795
|
|
|
Html::addCssClass($options, 'form-control'); |
796
|
|
|
if (ArrayHelper::getValue($settings, 'placeholder', null) !== null) { |
|
|
|
|
797
|
|
|
$options['placeholder'] = ArrayHelper::getValue($settings, 'placeholder', null); |
|
|
|
|
798
|
|
|
} |
799
|
|
|
if ($readOnly) { |
800
|
|
|
$options['disabled'] = 'disabled'; |
801
|
|
|
$clear = false; |
802
|
|
|
} |
803
|
|
|
|
804
|
|
|
$clear = ($clear === true ? true : false); // null defaults to false if still null at this stage |
805
|
|
|
if ($clear === false) { |
806
|
|
|
$allowClear = false; |
807
|
|
|
} |
808
|
|
|
|
809
|
|
|
$inputSize = ArrayHelper::getValue($settings, 'size', InputField::INPUT_SIZE_AUTO); |
|
|
|
|
810
|
|
|
$options = $this->applyInputSize($inputSize, $options); |
811
|
|
|
$options = $this->convertOptionsForWidgets($type, $options); |
812
|
|
|
|
813
|
|
|
if ($allowClear) { |
814
|
|
|
$allowClear['size'] = $inputSize; |
815
|
|
|
} |
816
|
|
|
|
817
|
|
|
return static::getInput($field, $type, [$options], $label, $hint, $icon, $tooltip, $addon, $allowClear); |
|
|
|
|
818
|
|
|
break; |
|
|
|
|
819
|
|
|
|
820
|
|
|
case InputField::INPUT_SELECT2_TAGS: |
821
|
|
|
case InputField::INPUT_WIDGET: |
822
|
|
|
return 'WORK IN PROGRESS (other): ' . $attribute . ' : ' . $type . '<br/>'; |
823
|
|
|
break; |
|
|
|
|
824
|
|
|
case InputField::INPUT_RADIO: |
825
|
|
|
return 'Not currently supported: ' . $attribute . ' : ' . $type . '<br/>'; |
826
|
|
|
break; |
|
|
|
|
827
|
|
|
default: |
828
|
|
|
return 'WORK IN PROGRESS (other): ' . $attribute . ' : ' . $type . '<br/>'; |
829
|
|
|
} |
830
|
|
|
|
831
|
|
|
return null; |
832
|
|
|
} |
833
|
|
|
|
834
|
|
|
/** |
835
|
|
|
* Extend ActiveField with any other generic settings ahead of rendering it |
836
|
|
|
* |
837
|
|
|
* @param ActiveField $field |
838
|
|
|
* @param string $type |
839
|
|
|
* @param array $params array of params for the field type call |
840
|
|
|
* @param string $label |
841
|
|
|
* @param string $hint |
842
|
|
|
* @param array $icon |
843
|
|
|
* @param array $tooltip |
844
|
|
|
* @param array $addon |
845
|
|
|
* @param false|array $allowClear |
846
|
|
|
* @return ActiveField |
847
|
|
|
*/ |
848
|
|
|
private function getInput($field, $type, $params = null, $label = null, $hint = null, $icon = null, $tooltip = null, $addon = null, $allowClear = null) |
849
|
|
|
{ |
850
|
|
|
|
851
|
|
|
$field->setType($type); |
852
|
|
|
|
853
|
|
|
if ($label !== null && $label !== false) { |
854
|
|
|
$field = $field->label($label); |
855
|
|
|
} |
856
|
|
|
|
857
|
|
|
if ($hint !== null && $hint !== false) { |
858
|
|
|
$field = $field->hint($hint); |
859
|
|
|
} |
860
|
|
|
|
861
|
|
|
if (($icon !== null && $icon !== false) || ($tooltip !== null && $tooltip !== false)) { |
862
|
|
|
$field->icon($icon, $tooltip); |
|
|
|
|
863
|
|
|
} |
864
|
|
|
|
865
|
|
|
if ($addon !== null && is_array($addon)) { |
866
|
|
|
$field->mergeAddon($addon); |
867
|
|
|
} |
868
|
|
|
|
869
|
|
|
if ($allowClear !== null && is_array($allowClear) && $allowClear) { |
|
|
|
|
870
|
|
|
$inputClearType = ArrayHelper::remove($allowClear, 'input', 'input'); |
871
|
|
|
$inputClearValue = ArrayHelper::remove($allowClear, 'value', ''); |
872
|
|
|
$inputClearGroupSize = ArrayHelper::remove($allowClear, 'size', ''); |
873
|
|
|
$field->addClearAddOn($inputClearType, $inputClearValue, $inputClearGroupSize); |
874
|
|
|
} |
875
|
|
|
|
876
|
|
|
if ($params !== null) { |
877
|
|
|
$field = call_user_func_array([$field, $type], $params); |
878
|
|
|
} |
879
|
|
|
|
880
|
|
|
return $field; |
881
|
|
|
} |
882
|
|
|
|
883
|
|
|
/** |
884
|
|
|
* Check to see if the provided attribute should have the default focus and apply it |
885
|
|
|
* |
886
|
|
|
* @param array $options field input options |
887
|
|
|
* @param ActiveField $field |
888
|
|
|
* @param string $attribute |
889
|
|
|
* @param string $defaultFocusSetting |
890
|
|
|
* @return array updated $options |
891
|
|
|
*/ |
892
|
|
|
public function setFocus($options, $field, $attribute, $defaultFocusSetting = null) |
|
|
|
|
893
|
|
|
{ |
894
|
|
|
if ($this->defaultFocus === null && $this->defaultFocusSelect === null) { |
895
|
|
|
if ($defaultFocusSetting !== null) { |
896
|
|
|
if ($defaultFocusSetting == 'focus') { |
897
|
|
|
Html::addCssClass($options, 'default-field'); |
898
|
|
|
} elseif ($defaultFocusSetting == 'select') { |
899
|
|
|
Html::addCssClass($options, 'default-field-select'); |
900
|
|
|
} |
901
|
|
|
} |
902
|
|
|
} else { |
903
|
|
|
if ($attribute == $this->defaultFocus) { |
904
|
|
|
Html::addCssClass($options, 'default-field'); |
905
|
|
|
} elseif ($attribute == $this->defaultFocusSelect) { |
906
|
|
|
Html::addCssClass($options, 'default-field-select'); |
907
|
|
|
} |
908
|
|
|
} |
909
|
|
|
return $options; |
910
|
|
|
} |
911
|
|
|
|
912
|
|
|
/** |
913
|
|
|
* Automate default input field size based on maxlength setting |
914
|
|
|
* |
915
|
|
|
* @param string $inputSize |
916
|
|
|
* @param integer $maxlength |
917
|
|
|
* @param array|string|null $icon |
918
|
|
|
* @param array|string|null $tooltip |
919
|
|
|
* @return string |
920
|
|
|
*/ |
921
|
|
|
public function getDefaultInputSize($inputSize, $maxlength, $icon = null, $tooltip = null) |
922
|
|
|
{ |
923
|
|
|
if ($inputSize == InputField::INPUT_SIZE_AUTO) { |
924
|
|
|
if ($maxlength == 0) { |
925
|
|
|
$inputSize = InputField::INPUT_SIZE_NONE; |
926
|
|
|
} else { |
927
|
|
|
if ($icon !== null || $tooltip !== null) { |
928
|
|
|
if ($maxlength < 5) { |
929
|
|
|
$inputSize = InputField::INPUT_SIZE_XSMALL; |
930
|
|
|
} elseif ($maxlength < 11) { |
931
|
|
|
$inputSize = InputField::INPUT_SIZE_SMALL; |
932
|
|
|
} elseif ($maxlength < 24) { |
933
|
|
|
$inputSize = InputField::INPUT_SIZE_MEDIUM; |
934
|
|
|
} elseif ($maxlength < 34) { |
935
|
|
|
$inputSize = InputField::INPUT_SIZE_LARGE; |
936
|
|
|
} elseif ($maxlength < 47) { |
937
|
|
|
$inputSize = InputField::INPUT_SIZE_XLARGE; |
938
|
|
|
} |
939
|
|
|
} else { |
940
|
|
|
if ($maxlength < 7) { |
941
|
|
|
$inputSize = InputField::INPUT_SIZE_XSMALL; |
942
|
|
|
} elseif ($maxlength < 15) { |
943
|
|
|
$inputSize = InputField::INPUT_SIZE_SMALL; |
944
|
|
|
} elseif ($maxlength < 27) { |
945
|
|
|
$inputSize = InputField::INPUT_SIZE_MEDIUM; |
946
|
|
|
} elseif ($maxlength < 37) { |
947
|
|
|
$inputSize = InputField::INPUT_SIZE_LARGE; |
948
|
|
|
} elseif ($maxlength < 49) { |
949
|
|
|
$inputSize = InputField::INPUT_SIZE_XLARGE; |
950
|
|
|
} |
951
|
|
|
} |
952
|
|
|
} |
953
|
|
|
} |
954
|
|
|
return $inputSize; |
955
|
|
|
} |
956
|
|
|
|
957
|
|
|
/** |
958
|
|
|
* Apply input size to input field |
959
|
|
|
* |
960
|
|
|
* @param string $inputSize |
961
|
|
|
* @param array $options |
962
|
|
|
* @return array |
963
|
|
|
*/ |
964
|
|
|
public function applyInputSize($inputSize, $options) |
965
|
|
|
{ |
966
|
|
|
if ($inputSize != InputField::INPUT_SIZE_NONE && $inputSize != InputField::INPUT_SIZE_AUTO) { |
967
|
|
|
Html::addCssClass($options, 'input-' . $inputSize); |
968
|
|
|
} |
969
|
|
|
return $options; |
970
|
|
|
} |
971
|
|
|
|
972
|
|
|
/** |
973
|
|
|
* Amend options array suitable for passing to widgets |
974
|
|
|
* |
975
|
|
|
* @param string $type |
976
|
|
|
* @param array $options |
977
|
|
|
* @return array |
978
|
|
|
*/ |
979
|
|
|
public function convertOptionsForWidgets($type, $options) |
980
|
|
|
{ |
981
|
|
|
if (InputField::getIsWidgetFromFieldType($type)) { |
982
|
|
|
// we need to present the options differently |
983
|
|
|
$newOptions = $options; |
984
|
|
|
$widgetOptions = ArrayHelper::getValue($options, 'widgetOptions', []); |
985
|
|
|
unset($newOptions['widgetOptions']); |
986
|
|
|
$options = $widgetOptions; |
987
|
|
|
$options['options'] = $newOptions; |
988
|
|
|
} |
989
|
|
|
return $options; |
990
|
|
|
} |
991
|
|
|
|
992
|
|
|
} |
993
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.