DynamicInputWidget.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: NODELOG
  5. * Date: 16/7/15
  6. * Time: 上午11:34
  7. */
  8. namespace common\widgets\dynamicInput;
  9. use common\modules\attachment\widgets\MultipleWidget;
  10. use common\modules\city\widgets\CityWidget;
  11. use common\widgets\EditorWidget;
  12. use common\modules\attachment\widgets\SingleWidget;
  13. use kartik\date\DatePicker;
  14. use kartik\datetime\DateTimePicker;
  15. use yii\base\InvalidParamException;
  16. use yii\helpers\ArrayHelper;
  17. use yii\helpers\Html;
  18. use yii\widgets\InputWidget;
  19. class DynamicInputWidget extends InputWidget
  20. {
  21. /**
  22. * @var array 支持的类型集合
  23. */
  24. public $types = [
  25. 'text',
  26. 'prefixText',
  27. 'suffixText',
  28. 'array',
  29. 'boolean',
  30. 'password',
  31. 'textarea',
  32. 'select',
  33. 'checkbox',
  34. 'radio',
  35. 'image',
  36. 'images',
  37. 'editor',
  38. 'date',
  39. 'datetime',
  40. 'file',
  41. 'files',
  42. 'city',
  43. ];
  44. public $type;
  45. public $data;
  46. public $inputOptions = ['class' => 'form-control'];
  47. public $widgetOptions = [];
  48. public function init()
  49. {
  50. parent::init();
  51. if (!in_array($this->type, $this->types)) {
  52. throw new InvalidParamException('不支持的类型');
  53. }
  54. $this->data = $this->parseExtra($this->data);
  55. if (is_string($this->data)) {
  56. $this->data = config($this->data);
  57. }
  58. if (empty($this->widgetOptions)) {
  59. $this->widgetOptions = ArrayHelper::remove($this->options, 'widgetOptions', []);
  60. }
  61. }
  62. public function run()
  63. {
  64. if ($this->hasModel()) {
  65. return $this->parseActive();
  66. } else {
  67. return $this->parse();
  68. }
  69. }
  70. private function parse()
  71. {
  72. switch ($this->type) {
  73. case 'text': // 文本框
  74. $options = array_merge($this->inputOptions, $this->options);
  75. return Html::textInput($this->name, $this->value, $options);
  76. break;
  77. case 'prefixText': // 前缀文本框
  78. $options = array_merge($this->inputOptions, $this->options);
  79. $prefix = ArrayHelper::remove($options, 'prefix');
  80. $prefixType = ArrayHelper::remove($options, 'prefixType', 'addon');
  81. return '<div class="input-group">' . Html::tag('div', $prefix, ['class' => 'input-group-' . $prefixType]) . Html::textInput($this->name, $this->value, $options) . '</div>';
  82. break;
  83. case 'suffixText': // 后缀文本框
  84. $options = array_merge($this->inputOptions, $this->options);
  85. $suffix = ArrayHelper::remove($options, 'suffix');
  86. $suffixType = ArrayHelper::remove($options, 'suffixType', 'addon');
  87. return '<div class="input-group">' . Html::textInput($this->name, $this->value, $options) . Html::tag('div', $suffix, ['class' => 'input-group-' . $suffixType]) . '</div>';
  88. break;
  89. case 'password': // 密码框
  90. $options = array_merge($this->inputOptions, $this->options);
  91. return Html::passwordInput($this->name, $this->value, $options);
  92. break;
  93. case 'boolean': // 布尔
  94. return Html::boolean($this->name, $this->value, $this->options);
  95. break;
  96. case 'array': // 数组
  97. $options = array_merge($this->inputOptions, ['rows' => 5], $this->options);
  98. return Html::textarea($this->name, $this->value, $options);
  99. break;
  100. case 'textarea': // 多行文本框
  101. $options = array_merge($this->inputOptions, ['rows' => 5], $this->options);
  102. return Html::textarea($this->name, $this->value, $options);
  103. break;
  104. case 'select': // 下拉
  105. $options = array_merge($this->inputOptions, $this->options);
  106. return Html::dropDownList($this->name, $this->value, $this->data, $options);
  107. break;
  108. case 'checkbox': // 多选
  109. return Html::checkboxList($this->name, $this->value, $this->data, $this->options);
  110. break;
  111. case 'radio': // 单选
  112. return Html::radioList($this->name, $this->value, $this->data, $this->options);
  113. break;
  114. case 'image': // 图片
  115. return SingleWidget::widget(ArrayHelper::merge(['name' => $this->name, 'value' => $this->value, 'onlyUrl' => true], $this->widgetOptions));
  116. break;
  117. case 'images': // 图片
  118. return MultipleWidget::widget(ArrayHelper::merge(['name' => $this->name, 'value' => $this->value, 'onlyUrl' => true], $this->widgetOptions));
  119. break;
  120. case 'file': // 文件
  121. return SingleWidget::widget(ArrayHelper::merge(['name' => $this->name, 'value' => $this->value, 'onlyImage' => false, 'onlyUrl' => true], $this->widgetOptions));
  122. break;
  123. case 'files': // 文件
  124. return MultipleWidget::widget(ArrayHelper::merge(['name' => $this->name, 'value' => $this->value, 'onlyImage' => false, 'onlyUrl' => true], $this->widgetOptions));
  125. break;
  126. case 'editor': // 编辑器
  127. return EditorWidget::widget(ArrayHelper::merge([
  128. 'name' => $this->name,
  129. 'value' => $this->value
  130. ], $this->widgetOptions));
  131. break;
  132. case 'date': // 日期
  133. return DatePicker::widget(ArrayHelper::merge([
  134. 'name' => $this->name,
  135. 'value' => $this->value,
  136. 'type' => 3,
  137. 'convertFormat' => true,
  138. 'pluginOptions' => ['format' => 'php:Y-m-d', 'autoclose' => true],
  139. ], $this->widgetOptions));
  140. break;
  141. case 'datetime': // 时间
  142. return DateTimePicker::widget(ArrayHelper::merge([
  143. 'name' => $this->name,
  144. 'value' => $this->value,
  145. 'type' => 3,
  146. 'convertFormat' => true,
  147. 'pluginOptions' => ['format' => 'php:Y-m-d H:i:s', 'autoclose' => true]
  148. ], $this->widgetOptions));
  149. break;
  150. case 'city': //城市联动
  151. return CityWidget::widget(ArrayHelper::merge([
  152. 'name' => $this->name,
  153. 'value' => $this->value,
  154. ], $this->widgetOptions));
  155. break;
  156. }
  157. }
  158. private function parseActive()
  159. {
  160. switch ($this->type) {
  161. case 'text': // 文本框
  162. $options = array_merge($this->inputOptions, $this->options);
  163. return Html::activeTextInput($this->model, $this->attribute, $options);
  164. break;
  165. case 'prefixText': // 前缀文本框
  166. $options = array_merge($this->inputOptions, $this->options);
  167. $prefix = ArrayHelper::remove($options, 'prefix');
  168. $prefixType = ArrayHelper::remove($options, 'prefixType', 'addon');
  169. return '<div class="input-group">' . Html::tag('div', $prefix, ['class' => 'input-group-' . $prefixType]) . Html::activeTextInput($this->model, $this->attribute, $options) . '</div>';
  170. break;
  171. case 'suffixText': // 后缀文本框
  172. $options = array_merge($this->inputOptions, $this->options);
  173. $suffix = ArrayHelper::remove($options, 'suffix');
  174. $suffixType = ArrayHelper::remove($options, 'suffixType', 'addon');
  175. return '<div class="input-group">' . Html::activeTextInput($this->model, $this->attribute, $options) . Html::tag('div', $suffix, ['class' => 'input-group-' . $suffixType]) . '</div>';
  176. break;
  177. case 'password': // 密码框
  178. $options = array_merge($this->inputOptions, $this->options);
  179. return Html::activePasswordInput($this->model, $this->attribute, $options);
  180. break;
  181. case 'boolean': // 布尔
  182. return Html::activeBoolean($this->model, $this->attribute, ArrayHelper::merge($this->options, ['label' => false]));
  183. break;
  184. case 'array': // 数组
  185. $options = array_merge($this->inputOptions, ['rows' => 5], $this->options);
  186. return Html::activeTextarea($this->model, $this->attribute, $options);
  187. break;
  188. case 'textarea': // 多行文本框
  189. $options = array_merge($this->inputOptions, ['rows' => 5], $this->options);
  190. return Html::activeTextarea($this->model, $this->attribute, $options);
  191. break;
  192. case 'select': // 下拉
  193. $options = array_merge($this->inputOptions, $this->options);
  194. return Html::activeDropDownList($this->model, $this->attribute, $this->data, $options);
  195. break;
  196. case 'checkbox': // 多选
  197. return Html::activeCheckboxList($this->model, $this->attribute, $this->data, $this->options);
  198. break;
  199. case 'radio': // 单选
  200. return Html::activeRadioList($this->model, $this->attribute, $this->data, $this->options);
  201. break;
  202. case 'image': // 图片
  203. return SingleWidget::widget(ArrayHelper::merge(['model' => $this->model, 'attribute' => $this->attribute, 'onlyUrl' => true], $this->widgetOptions));
  204. break;
  205. case 'images': // 图片
  206. return MultipleWidget::widget(ArrayHelper::merge(['model' => $this->model, 'attribute' => $this->attribute, 'onlyUrl' => true], $this->widgetOptions));
  207. break;
  208. case 'file': // 文件
  209. return SingleWidget::widget(ArrayHelper::merge(['model' => $this->model, 'attribute' => $this->attribute, 'onlyImage' => false, 'onlyUrl' => true], $this->widgetOptions));
  210. break;
  211. case 'files': // 文件
  212. return MultipleWidget::widget(ArrayHelper::merge(['model' => $this->model, 'attribute' => $this->attribute, 'onlyImage' => false, 'onlyUrl' => true], $this->widgetOptions));
  213. break;
  214. case 'editor': // 编辑器
  215. return EditorWidget::widget(ArrayHelper::merge([
  216. 'model' => $this->model,
  217. 'attribute' => $this->attribute
  218. ], $this->widgetOptions));
  219. break;
  220. case 'date': // 日期
  221. return DatePicker::widget(ArrayHelper::merge([
  222. 'model' => $this->model,
  223. 'attribute' => $this->attribute,
  224. 'type' => 3,
  225. 'convertFormat' => true,
  226. 'pluginOptions' => ['format' => 'php:Y-m-d', 'autoclose' => true],
  227. ], $this->widgetOptions));
  228. break;
  229. case 'datetime': // 时间
  230. return DateTimePicker::widget(ArrayHelper::merge([
  231. 'model' => $this->model,
  232. 'attribute' => $this->attribute,
  233. 'type' => 3,
  234. 'convertFormat' => true,
  235. 'pluginOptions' => ['format' => 'php:Y-m-d H:i:s', 'autoclose' => true],
  236. ], $this->widgetOptions));
  237. break;
  238. case 'city': //城市联动
  239. return CityWidget::widget(ArrayHelper::merge([
  240. 'model' => $this->model,
  241. 'attribute' => $this->attribute,
  242. ], $this->widgetOptions));
  243. break;
  244. }
  245. }
  246. /**
  247. * 分析枚举类型.
  248. * @param $value string
  249. * @return array
  250. */
  251. public function parseExtra($value)
  252. {
  253. $return = [];
  254. if (is_array($value)) {
  255. return $value;
  256. }
  257. if (config()->has($value)) {
  258. return config($value);
  259. }
  260. // foreach (explode("\r\n", $value) as $val) {
  261. foreach (preg_split("/[\r\n]+/s", $value) as $val) {
  262. if (strpos($val, '=>') !== false) {
  263. list($k, $v) = explode('=>', $val);
  264. $return[$k] = $v;
  265. } else {
  266. $return[] = $val;
  267. }
  268. }
  269. return $return;
  270. }
  271. }