ActiveField.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. <?php
  2. /**
  3. * Author: lf
  4. * Blog: https://blog.feehi.com
  5. * Email: job@feehi.com
  6. * Created at: 2016-03-21 14:40
  7. */
  8. namespace backend\widgets;
  9. use Yii;
  10. use yii\helpers\Html;
  11. class ActiveField extends \yii\widgets\ActiveField
  12. {
  13. public $options = [
  14. 'class' => 'form-group'
  15. ];
  16. public $labelOptions = [
  17. 'class' => 'col-sm-2 control-label',
  18. ];
  19. public $size = '10';
  20. public $template = "{label}\n<div class=\"col-sm-{size}\">{input}\n{error}</div>\n{hint}";
  21. public $errorOptions = [
  22. 'class' => 'help-block m-b-none'
  23. ];
  24. public function init()
  25. {
  26. parent::init();
  27. if( !isset($this->options['class']) ){
  28. $this->options['class'] = 'form-group';
  29. }
  30. if(!isset($this->labelOptions['class'])){
  31. $this->labelOptions['class'] = 'col-sm-2 control-label';
  32. }
  33. if(!isset($this->errorOptions['class'])){
  34. $this->errorOptions['class'] = 'help-block m-b-none';
  35. }
  36. }
  37. /**
  38. * @inheritdoc
  39. */
  40. public function render($content = null)
  41. {
  42. if ($content === null) {
  43. if (! isset($this->parts['{input}'])) {
  44. $this->parts['{input}'] = Html::activeTextInput($this->model, $this->attribute, $this->inputOptions);
  45. }
  46. if (! isset($this->parts['{label}'])) {
  47. if( $this->model->isAttributeRequired($this->attribute) && ( !isset( $this->labelOptions['requiredSign'] ) || $this->labelOptions['requiredSign'] ) ){
  48. $requiredSign = !isset( $this->labelOptions['requiredSign'] ) ? "<span style='color:red'>*</span> " : $this->labelOptions['requiredSign'];
  49. $this->labelOptions['label'] = $requiredSign . ( isset( $this->labelOptions['label'] ) ? $this->labelOptions['label'] : $this->model->getAttributeLabel($this->attribute) );
  50. }
  51. $this->parts['{label}'] = Html::activeLabel($this->model, $this->attribute, $this->labelOptions);
  52. }
  53. if (! isset($this->parts['{error}'])) {
  54. $this->parts['{error}'] = Html::error($this->model, $this->attribute, $this->errorOptions);
  55. }
  56. if (! isset($this->parts['{hint}'])) {
  57. $this->parts['{hint}'] = '';
  58. }
  59. $this->parts['{size}'] = $this->size;
  60. $content = strtr($this->template, $this->parts);
  61. } elseif (! is_string($content)) {
  62. $content = call_user_func($content, $this);
  63. }
  64. return $this->begin() . "\n" . $content . "\n" . $this->end();
  65. }
  66. /**
  67. * @inheritdoc
  68. */
  69. public function checkbox($options = [], $enclosedByLabel = false)
  70. {
  71. static $i = 1;
  72. $unique = uniqid() . $i;
  73. $i++;
  74. if($i >= 10000) $i = 1;
  75. $for = 'inlineCheckbox' . $unique;
  76. $options['id'] = $for;
  77. $options['tag'] = 'a';
  78. $this->labelOptions = [];
  79. $this->options['class'] = '';
  80. $this->template = "<span class=\"checkbox checkbox-success checkbox-inline\">{input}
  81. {label}
  82. </span>";
  83. return parent::checkbox($options, $enclosedByLabel);
  84. }
  85. /**
  86. * @inheritdoc
  87. */
  88. public function dropDownList($items, $options = [], $generateDefault = true)
  89. {
  90. if ($generateDefault === true && ! isset($options['prompt'])) {
  91. $options['prompt'] = Yii::t('app', 'Please chose');
  92. }
  93. return parent::dropDownList($items, $options);
  94. }
  95. /**
  96. * 美化过的select选框
  97. *
  98. * @param array $items 需要设置的option元素,数组key作为值,数组value显示为option选项内容
  99. * @param bool $multiple 是否多选,默认单选
  100. * @param array $options htmp属性设置
  101. * - 具体的参数配置请参考jquery chosen官方文档: https://harvesthq.github.io/chosen/options.html
  102. * @param bool $generateDefault 是否生成请选择选项,默认是
  103. * @return \yii\widgets\ActiveField
  104. */
  105. public function chosenSelect($items, $multiple = false, $options = [], $generateDefault = true)
  106. {
  107. if( isset( $options['class'] ) ){
  108. $options['class'] .= " chosen-select";
  109. }else{
  110. $options['class'] = "chosen-select";
  111. }
  112. $multiple && $options['multiple'] = "1";
  113. !isset($options['allow_single_deselect']) && $options['allow_single_deselect'] = true;
  114. $options['allow_single_deselect'] === true && $options['allow_single_deselect'] = 'true';
  115. $options['allow_single_deselect'] === false && $options['allow_single_deselect'] = 'false';
  116. !isset($options['disable_search']) && $options['disable_search'] = false;
  117. $options['disable_search'] === true && $options['disable_search'] = 'true';
  118. $options['disable_search'] === false && $options['disable_search'] = 'false';
  119. !isset($options['disable_search_threshold']) && $options['disable_search_threshold'] = 0;
  120. !isset($options['enable_split_word_search']) && $options['enable_split_word_search'] = true;
  121. $options['enable_split_word_search'] === true && $options['enable_split_word_search'] = 'true';
  122. $options['enable_split_word_search'] === false && $options['enable_split_word_search'] = 'false';
  123. !isset($options['inherit_select_classes']) && $options['inherit_select_classes'] = false;
  124. $options['inherit_select_classes'] === true && $options['inherit_select_classes'] = 'true';
  125. $options['inherit_select_classes'] === false && $options['inherit_select_classes'] = 'false';
  126. !isset($options['max_selected_options']) && $options['max_selected_options'] = 'Infinity';
  127. !isset($options['no_results_text']) && $options['no_results_text'] = Yii::t('app', 'None');
  128. !isset($options['placeholder_text_multiple']) && $options['placeholder_text_multiple'] = Yii::t('app', 'Please chose some');;
  129. !isset($options['placeholder_text_single']) && $options['placeholder_text_single'] = Yii::t('app', 'Please chose');
  130. !isset($options['search_contains']) && $options['search_contains'] = true;
  131. $options['search_contains'] === true && $options['search_contains'] = 'true';
  132. $options['search_contains'] === false && $options['search_contains'] = 'false';
  133. !isset($options['group_search']) && $options['group_search'] = true;
  134. $options['group_search'] === true && $options['group_search'] = 'true';
  135. $options['group_search'] === false && $options['group_search'] = 'false';
  136. !isset($options['single_backstroke_delete']) && $options['single_backstroke_delete'] = true;
  137. $options['single_backstroke_delete'] === true && $options['single_backstroke_delete'] = 'true';
  138. $options['single_backstroke_delete'] === false && $options['single_backstroke_delete'] = 'false';
  139. !isset($options['width']) && $options['width'] = '100%';
  140. !isset($options['display_disabled_options']) && $options['display_disabled_options'] = true;
  141. $options['display_disabled_options'] === true && $options['display_disabled_options'] = 'true';
  142. $options['display_disabled_options'] === false && $options['display_disabled_options'] = 'false';
  143. !isset($options['display_selected_options']) && $options['display_selected_options'] = true;
  144. $options['display_selected_options'] === true && $options['display_selected_options'] = 'true';
  145. $options['display_selected_options'] === false && $options['display_selected_options'] = 'false';
  146. !isset($options['include_group_label_in_selected']) && $options['include_group_label_in_selected'] = false;
  147. $options['include_group_label_in_selected'] === true && $options['include_group_label_in_selected'] = 'true';
  148. $options['include_group_label_in_selected'] === false && $options['include_group_label_in_selected'] = 'false';
  149. !isset($options['max_shown_results']) && $options['max_shown_results'] = 'Infinity';
  150. !isset($options['case_sensitive_search']) && $options['case_sensitive_search'] = false;
  151. $options['case_sensitive_search'] === true && $options['case_sensitive_search'] = 'true';
  152. $options['case_sensitive_search'] === false && $options['case_sensitive_search'] = 'false';
  153. !isset($options['hide_results_on_select']) && $options['hide_results_on_select'] = true;
  154. $options['hide_results_on_select'] === true && $options['hide_results_on_select'] = 'true';
  155. $options['hide_results_on_select'] === false && $options['hide_results_on_select'] = 'false';
  156. !isset($options['rtl']) && $options['trl'] = false;
  157. $options['trl'] === true && $options['trl'] = 'true';
  158. $options['trl'] === false && $options['trl'] = 'false';
  159. return $this->dropDownList($items, $options, $generateDefault);
  160. }
  161. /**
  162. * @inheritdoc
  163. */
  164. public function readOnly($value = null, $options = [])
  165. {
  166. $options = array_merge($this->inputOptions, $options);
  167. $this->adjustLabelFor($options);
  168. $value = $value === null ? Html::getAttributeValue($this->model, $this->attribute) : $value;
  169. $options['class'] = 'da-style';
  170. $options['style'] = 'display: inline-block;';
  171. $this->parts['{input}'] = Html::activeHiddenInput($this->model, $this->attribute) . Html::tag('span', $value, $options);
  172. return $this;
  173. }
  174. /**
  175. * @inheritdoc
  176. */
  177. public function radioList($items, $options = [])
  178. {
  179. $options['tag'] = 'div';
  180. $inputId = Html::getInputId($this->model, $this->attribute);
  181. $this->selectors = ['input' => "#$inputId input"];
  182. $options['class'] = 'radio';
  183. $encode = ! isset($options['encode']) || $options['encode'];
  184. $itemOptions = isset($options['itemOptions']) ? $options['itemOptions'] : [];
  185. $options['item'] = function ($index, $label, $name, $checked, $value) use ($encode, $itemOptions) {
  186. static $i = 1;
  187. $radio = Html::radio($name, $checked, array_merge($itemOptions, [
  188. 'value' => $value,
  189. 'id' => $name . $i,
  190. //'label' => $encode ? Html::encode($label) : $label,
  191. ]));
  192. $radio .= "<label for=\"$name$i\"> $label </label>";
  193. $radio = "<div class='radio radio-success radio-inline'>{$radio}</div>";
  194. //var_dump($radio);die;
  195. $i++;
  196. return $radio;
  197. };
  198. return parent::radioList($items, $options);
  199. }
  200. /**
  201. * @inheritdoc
  202. */
  203. public function checkboxList($items, $options = [])
  204. {
  205. $options['tag'] = 'ul';
  206. $inputId = Html::getInputId($this->model, $this->attribute);
  207. $this->selectors = ['input' => "#$inputId input"];
  208. $options['class'] = 'da-form-list inline';
  209. $encode = ! isset($options['encode']) || $options['encode'];
  210. $itemOptions = isset($options['itemOptions']) ? $options['itemOptions'] : [];
  211. $unique = uniqid();
  212. $options['item'] = function ($index, $label, $name, $checked, $value) use ($encode, $itemOptions, $unique){
  213. static $i = 1;
  214. $unique .= rand(1, 99999) . $i;
  215. $i++;
  216. if($i >= 10000) $i = 1;
  217. $checkbox = Html::checkbox($name, $checked, array_merge($itemOptions, [
  218. 'value' => $value,
  219. 'id' => 'inlineCheckbox' . $unique,
  220. ]));
  221. return "<li class='checkbox checkbox-success checkbox-inline'>
  222. $checkbox
  223. <label for='inlineCheckbox{$unique}'> {$label} </label>
  224. </li>";
  225. };
  226. return parent::checkboxList($items, $options);
  227. }
  228. /**
  229. * @inheritdoc
  230. */
  231. public function textarea($options = [])
  232. {
  233. if (! isset($options['rows'])) {
  234. $options['rows'] = 5;
  235. }
  236. return parent::textarea($options);
  237. }
  238. /**
  239. * @param array $options
  240. * @return \yii\widgets\ActiveField
  241. */
  242. public function fileInput($options = [])
  243. {
  244. if (!isset($options['class'])) {
  245. $options['class'] = 'pretty-file';
  246. }else{
  247. $options['class'] .= ' pretty-file';
  248. }
  249. !isset($options['text']) && $options['text'] = Yii::t("app", 'Choose File');
  250. return parent::fileInput($options); // TODO: Change the autogenerated stub
  251. }
  252. /**
  253. * @param array $options
  254. * @return $this
  255. */
  256. public function imgInput($options = [])
  257. {
  258. if( $this->template === "{label}\n<div class=\"col-sm-{size}\">{input}\n{error}</div>\n{hint}" ) {
  259. $this->template = "{label}\n<div class=\"col-sm-{size} image\">{input}<div style='position: relative'>{img}{actions}</div>\n{error}</div>\n{hint}";
  260. }
  261. $attribute = $this->attribute;
  262. $src = key_exists('value', $options) ? $options['value'] : $this->model->$attribute;
  263. /** @var $cdn \feehi\cdn\TargetAbstract */
  264. $cdn = Yii::$app->cdn;
  265. $baseUrl = $cdn->host;
  266. $nonePicUrl = isset($options['default']) ? $options['default'] : $baseUrl . 'static/images/none.jpg';
  267. if ($src != '') {
  268. if( strpos($src, $baseUrl) !== 0 ){
  269. $temp = parse_url($src);
  270. $src = (! isset($temp['host'])) ? $cdn->getCdnUrl($src) : $src;
  271. }
  272. $delete = Yii::t('app', 'Delete');
  273. $this->parts['{actions}'] = "<div onclick=\"$(this).parents('.image').find('input[type=hidden]').val(0);$(this).prev().attr('src', '$nonePicUrl');$(this).remove()\" style='position: absolute;width: 50px;padding: 5px 3px 3px 5px;top:5px;left:6px;background: black;opacity: 0.6;color: white;cursor: pointer'><i class='fa fa-trash' aria-hidden='true'> {$delete}</i></div>";
  274. }else{
  275. $src = $nonePicUrl;
  276. $this->parts['{actions}'] = '';
  277. }
  278. if (!isset($options['class'])) {
  279. $options['class'] = 'pretty-file img-responsive';
  280. }else{
  281. $options['class'] .= ' pretty-file img-responsive';
  282. }
  283. !isset($options['text']) && $options['text'] = Yii::t("app", 'Choose Image');
  284. $this->parts['{img}'] = Html::img($src, array_merge($options, ["nonePicUrl"=>$nonePicUrl]));
  285. return parent::fileInput($options); // TODO: Change the autogenerated stub
  286. }
  287. /**
  288. * ueditor编辑器
  289. *
  290. * @param array $options
  291. * @return $this
  292. * @throws \Exception
  293. */
  294. public function ueditor($options = [])
  295. {
  296. if (! isset($options['rows'])) {
  297. $options['rows'] = 5;
  298. }
  299. $options = array_merge($this->inputOptions, $options);
  300. $this->adjustLabelFor($options);
  301. $name = isset($options['name']) ? $options['name'] : Html::getInputName($this->model, $this->attribute);
  302. if (isset($options['value'])) {
  303. $value = $options['value'];
  304. unset($options['value']);
  305. } else {
  306. $value = Html::getAttributeValue($this->model, $this->attribute);
  307. }
  308. if (! array_key_exists('id', $options)) {
  309. $options['id'] = Html::getInputId($this->model, $this->attribute);
  310. }
  311. //self::normalizeMaxLength($model, $attribute, $options);
  312. $this->parts['{input}'] = Ueditor::widget(['content' => $value, 'name' => $name, 'id' => $this->attribute]);
  313. return $this;
  314. }
  315. /**
  316. * 时间/日期输入框
  317. *
  318. * @param array $options
  319. * - val: string 值,替代html的value属性,设置此val会在页面加载完成后由js把value改为val,此处与laydate不同之处,需要注意
  320. * - type: string,输入框类型,默认date。可选值:
  321. year 年选择器 只提供年列表选择
  322. month 年月选择器 只提供年、月选择
  323. date 日期选择器 可选择:年、月、日。type默认值,一般可不填
  324. time 时间选择器 只提供时、分、秒选择
  325. datetime 日期时间选择器 可选择:年、月、日、时、分、秒
  326. * - range: bool/string, 开启左右面板范围选择,默认false。如果设置 true,将默认采用 “ ~ ” 分割。 你也可以直接设置 分割字符。五种选择器类型均支持左右面板的范围选择。
  327. * - theme: string,主题,默认值:default。可选值有:default(默认简约)、molv(墨绿背景)、#颜色值(自定义颜色背景)、grid(格子主题)
  328. * ...更多的设置请直接参考laydate官方文档: https://www.layui.com/doc/modules/laydate.html
  329. * @return $this
  330. */
  331. public function date($options=[])
  332. {
  333. !isset($options['elem']) && $options['elem'] = 'this';
  334. !isset($options['type']) && $options['type'] = 'datetime';
  335. !isset($options['range']) && $options['range'] = false;
  336. $options['range'] === true && $options['range'] = '~';
  337. $options['range'] === false && $options['range'] = 'false';
  338. !isset($options['format']) && $options['format'] = 'yyyy-MM-dd HH:mm:ss';
  339. !isset($options['val']) && $options['val'] = $this->model->{$this->attribute} ? $this->model->{$this->attribute} : ( strpos(get_class($this->model), 'Search' ) !== false ? '' : 'new Date()' );
  340. !isset($options['isInitValue']) && $options['isInitValue'] = false;
  341. $options['isInitValue'] === true && $options['isInitValue'] = 'true';
  342. $options['isInitValue'] === false && $options['isInitValue'] = 'false';
  343. !isset($options['min']) && $options['min'] = '1900-1-1';
  344. !isset($options['max']) && $options['max'] = '2099-12-31';
  345. !isset($options['trigger']) && $options['trigger'] = 'focus';
  346. !isset($options['show']) && $options['show'] = false;
  347. $options['show'] === true && $options['show'] = 'true';
  348. $options['show'] === false && $options['show'] = 'false';
  349. !isset($options['position']) && $options['position'] = 'absolute';
  350. !isset($options['zIndex']) && $options['zIndex'] = '66666666';
  351. !isset($options['showBottom']) && $options['showBottom'] = true;
  352. $options['showBottom'] === true && $options['showBottom'] = 'true';
  353. $options['showBottom'] === false && $options['showBottom'] = 'false';
  354. !isset($options['btns']) && $options['btns'] = "['clear', 'now', 'confirm']";
  355. !isset($options['lang']) && $options['lang'] = ( strpos( Yii::$app->language, 'en' ) === 0 ? 'en' : 'cn' );
  356. !isset($options['theme']) && $options['theme'] = 'molv';
  357. !isset($options['calendar']) && $options['calendar'] = true;
  358. $options['calendar'] === true && $options['calendar'] = "true";
  359. $options['calendar'] === false && $options['calendar'] = "false";
  360. !isset($options['mark']) && $options['mark'] = '{}';//json对象
  361. !isset($options['ready']) && $options['ready'] = 'function(date){}';//匿名函数
  362. !isset($options['change']) && $options['change'] = 'function(value, date, endDate){}';//匿名函数
  363. !isset($options['done']) && $options['done'] = 'function(value, date, endDate){}';//匿名函数
  364. $options['dateType'] = $options['type'];
  365. $options['search'] = 'true';
  366. unset($options['type']);
  367. if (!isset($options['class'])) {
  368. $options['class'] = 'form-control date-time';
  369. }else{
  370. $options['class'] .= ' form-control date-time';
  371. }
  372. $this->parts['{input}'] = Html::activeTextInput($this->model, $this->attribute, $options);
  373. return $this;
  374. }
  375. }