Form.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. <?php
  2. /**
  3. * FormBuilder表单生成器
  4. * Author: xaboy
  5. * Github: https://github.com/xaboy/form-builder
  6. */
  7. namespace FormBuilder;
  8. use FormBuilder\components\Cascader;
  9. use FormBuilder\components\FormStyle;
  10. use FormBuilder\components\Hidden;
  11. use FormBuilder\components\Row;
  12. use FormBuilder\exception\FormBuilderException;
  13. use FormBuilder\traits\form\FormCascaderTrait;
  14. use FormBuilder\traits\form\FormCheckBoxTrait;
  15. use FormBuilder\traits\form\FormColorPickerTrait;
  16. use FormBuilder\traits\form\FormDatePickerTrait;
  17. use FormBuilder\traits\form\FormFrameTrait;
  18. use FormBuilder\traits\form\FormHiddenTrait;
  19. use FormBuilder\traits\form\FormInputNumberTrait;
  20. use FormBuilder\traits\form\FormInputTrait;
  21. use FormBuilder\traits\form\FormRadioTrait;
  22. use FormBuilder\traits\form\FormRateTrait;
  23. use FormBuilder\traits\form\FormSelectTrait;
  24. use FormBuilder\traits\form\FormSliderTrait;
  25. use FormBuilder\traits\form\FormStyleTrait;
  26. use FormBuilder\traits\form\FormSwitchesTrait;
  27. use FormBuilder\traits\form\FormTimePickerTrait;
  28. use FormBuilder\traits\form\FormTreeTrait;
  29. use FormBuilder\traits\form\FormUploadTrait;
  30. use FormBuilder\traits\form\FormOptionTrait;
  31. use FormBuilder\traits\form\FormValidateTrait;
  32. /**
  33. * Class Form
  34. *
  35. * @package FormBuilder
  36. */
  37. class Form
  38. {
  39. use FormColorPickerTrait,
  40. FormFrameTrait,
  41. FormInputNumberTrait,
  42. FormRadioTrait,
  43. FormRateTrait,
  44. FormSelectTrait,
  45. FormSwitchesTrait,
  46. FormUploadTrait,
  47. FormCheckBoxTrait,
  48. FormDatePickerTrait,
  49. FormInputTrait,
  50. FormSliderTrait,
  51. FormCascaderTrait,
  52. FormHiddenTrait,
  53. FormTimePickerTrait,
  54. FormTreeTrait,
  55. FormStyleTrait,
  56. FormOptionTrait,
  57. FormValidateTrait;
  58. /**
  59. * 三级联动 加载省市数据
  60. *
  61. * @var bool
  62. */
  63. protected $loadCityData = false;
  64. /**
  65. * 三级联动 加载省市区数据
  66. *
  67. * @var bool
  68. */
  69. protected $loadCityAreaData = false;
  70. /**
  71. * @var array
  72. */
  73. protected $components = [];
  74. /**
  75. * @var array
  76. */
  77. protected $fields = [];
  78. /**
  79. * @var array
  80. */
  81. protected $script = [
  82. 'jq' => '<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>',
  83. 'vue' => '<script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script>',
  84. //iview 版本 2.14.3
  85. 'iview-css' => '<link href="https://cdn.jsdelivr.net/npm/iview@2.14.3/dist/styles/iview.css" rel="stylesheet">',
  86. 'iview' => '<script src="https://cdn.jsdelivr.net/npm/iview@2.14.3/dist/iview.min.js"></script>',
  87. //form-create 版本 1.4.5
  88. 'form-create' => '<script src="https://cdn.jsdelivr.net/npm/form-create@1.4.5/dist/form-create.min.js"></script>',
  89. 'city-data' => '<script src="https://cdn.jsdelivr.net/npm/form-create/district/province_city.js"></script>',
  90. 'city-area-data' => '<script src="https://cdn.jsdelivr.net/npm/form-create/district/province_city_area.js"></script>'
  91. ];
  92. /**
  93. * 加载 jquery
  94. *
  95. * @var bool
  96. */
  97. protected $linkJq = true;
  98. /**
  99. * 加载 vue
  100. *
  101. * @var bool
  102. */
  103. protected $linkVue = true;
  104. /**
  105. * 加载 iview
  106. *
  107. * @var bool
  108. */
  109. protected $linkIview = true;
  110. /**
  111. * @var string
  112. */
  113. protected $successScript = '';
  114. /**
  115. * 网页标题
  116. *
  117. * @var string
  118. */
  119. protected $title = 'formBuilder';
  120. /**
  121. * 提交地址
  122. *
  123. * @var string
  124. */
  125. protected $action = '';
  126. /**
  127. * 表单id
  128. *
  129. * @var string
  130. */
  131. protected $id = '';
  132. /**
  133. * 提交方式
  134. *
  135. * @var string
  136. */
  137. protected $method = 'post';
  138. protected $resetBtn = false;
  139. protected $submitBtn = true;
  140. /**
  141. * 表单配置
  142. *
  143. * @var array|mixed
  144. */
  145. protected $config = [
  146. 'form' => [
  147. 'inline' => false,
  148. 'labelPosition' => 'right',
  149. 'labelWidth' => 125,
  150. 'showMessage' => true,
  151. 'autocomplete' => 'off'
  152. ],
  153. 'row' => []
  154. ];
  155. /**
  156. * Form constructor.
  157. *
  158. * @param string $action 提交地址
  159. * @param array $components 组件
  160. */
  161. public function __construct($action = '', array $components = [])
  162. {
  163. $this->components($components);
  164. $this->action = $action;
  165. }
  166. public static function json()
  167. {
  168. return new Json();
  169. }
  170. /**
  171. * @param bool $linkJq
  172. */
  173. public function setLinkJq($linkJq)
  174. {
  175. $this->linkJq = (bool)$linkJq;
  176. }
  177. /**
  178. * @param bool $linkVue
  179. */
  180. public function setLinkVue($linkVue)
  181. {
  182. $this->linkVue = (bool)$linkVue;
  183. }
  184. /**
  185. * @param bool $linkIview
  186. */
  187. public function setLinkIview($linkIview)
  188. {
  189. $this->linkIview = (bool)$linkIview;
  190. }
  191. /**
  192. * @return bool
  193. */
  194. public function isLoadCityData()
  195. {
  196. return $this->loadCityData;
  197. }
  198. /**
  199. * @return bool
  200. */
  201. public function isLoadCityAreaData()
  202. {
  203. return $this->loadCityAreaData;
  204. }
  205. /**
  206. * @param array $components
  207. * @return $this
  208. */
  209. public function components(array $components = [])
  210. {
  211. foreach ($components as $component) {
  212. $this->append($component);
  213. }
  214. return $this;
  215. }
  216. /**
  217. * @param Row $row
  218. * @return $this
  219. */
  220. public function formRow(Row $row)
  221. {
  222. $this->config['row'] = $row->build();
  223. return $this;
  224. }
  225. /**
  226. * @param FormStyle $formStyle
  227. * @return $this
  228. */
  229. public function formStyle(FormStyle $formStyle)
  230. {
  231. $this->config['form'] = $formStyle->build();
  232. return $this;
  233. }
  234. /**
  235. * @return string
  236. */
  237. public function getSuccessScript()
  238. {
  239. return $this->successScript;
  240. }
  241. /**
  242. * 表单提交后成功执行的js地址
  243. * formCreate.formSuccess(formData,$f)
  244. *
  245. * @param string $successScript
  246. * @return $this
  247. */
  248. public function setSuccessScript($successScript)
  249. {
  250. $this->successScript = $successScript;
  251. return $this;
  252. }
  253. /**
  254. * @return string
  255. */
  256. public function getId()
  257. {
  258. return $this->id;
  259. }
  260. /**
  261. * @param string $id
  262. * @return $this
  263. */
  264. public function setId($id)
  265. {
  266. $this->id = $id;
  267. return $this;
  268. }
  269. /**
  270. * @return string
  271. */
  272. public function getAction()
  273. {
  274. return $this->action;
  275. }
  276. /**
  277. * 提交地址
  278. *
  279. * @param string $action
  280. * @return $this
  281. */
  282. public function setAction($action)
  283. {
  284. $this->action = $action;
  285. return $this;
  286. }
  287. /**
  288. * @return string
  289. */
  290. public function getMethod()
  291. {
  292. return $this->method;
  293. }
  294. /**
  295. * @param string $key
  296. * @return array|mixed|null
  297. */
  298. public function getConfig($key = '')
  299. {
  300. if ($key == '')
  301. return $this->config;
  302. else
  303. return isset($this->config[$key]) ? $this->config[$key] : null;
  304. }
  305. /**
  306. * 提交方式
  307. *
  308. * @param string $method
  309. * @return $this
  310. */
  311. public function setMethod($method)
  312. {
  313. $this->method = $method;
  314. return $this;
  315. }
  316. /**
  317. * 标题
  318. *
  319. * @return string
  320. */
  321. public function getTitle()
  322. {
  323. return $this->title;
  324. }
  325. /**
  326. * @param string $title
  327. * @return $this
  328. */
  329. public function setTitle($title)
  330. {
  331. $this->title = $title;
  332. return $this;
  333. }
  334. /**
  335. * 追加组件
  336. *
  337. * @param FormComponentDriver $component
  338. * @return $this
  339. */
  340. public function append(FormComponentDriver $component)
  341. {
  342. $field = $component->getField();
  343. if (!isset($this->components[$field]))
  344. $this->fields[] = $field;
  345. $this->components[$field] = $component;
  346. $this->checkLoadData($component);
  347. return $this;
  348. }
  349. /**
  350. * 开头插入组件
  351. *
  352. * @param FormComponentDriver $component
  353. * @return $this
  354. */
  355. public function prepend(FormComponentDriver $component)
  356. {
  357. $field = $component->getField();
  358. if (!isset($this->components[$field]))
  359. array_unshift($this->fields, $field);
  360. $this->components[$field] = $component;
  361. $this->checkLoadData($component);
  362. return $this;
  363. }
  364. /**
  365. * 是否需要引入省市区数据
  366. *
  367. * @param FormComponentDriver $component
  368. */
  369. protected function checkLoadData(FormComponentDriver $component)
  370. {
  371. if (
  372. $component instanceof Cascader
  373. && ($this->loadCityData == false || $this->loadCityAreaData == false)
  374. ) {
  375. $type = $component->getType();
  376. if ($type == Cascader::TYPE_CITY)
  377. $this->loadCityData = true;
  378. else if ($type == Cascader::TYPE_CITY_AREA)
  379. $this->loadCityAreaData = true;
  380. }
  381. }
  382. /**
  383. * 获得表单规则
  384. *
  385. * @return array
  386. * @throws FormBuilderException
  387. */
  388. public function getRules()
  389. {
  390. $rules = [];
  391. $fields = [];
  392. foreach ($this->fields as $field) {
  393. $component = $this->components[$field];
  394. if (!($component instanceof FormComponentDriver))
  395. continue;
  396. $field = $component->getField();
  397. if (in_array($field, $fields))
  398. throw new FormBuilderException($field . '字段已重复,请保证组件 field 无重复');
  399. $fields[] = $field;
  400. $rule = $component->build();
  401. if (!$component instanceof Hidden)
  402. $rule['validate'] = array_merge(isset($rule['validate']) ? $rule['validate'] : [], $component->validate()->build());
  403. $rules[] = $rule;
  404. }
  405. return $rules;
  406. }
  407. /**
  408. * 获取表单视图
  409. *
  410. * @return string
  411. */
  412. public function view()
  413. {
  414. ob_start();
  415. $form = $this;
  416. require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'form.php';
  417. $html = ob_get_clean();
  418. return $html;
  419. }
  420. /**
  421. * 获取表单生成器所需全部js
  422. *
  423. * @return array
  424. */
  425. public function script()
  426. {
  427. return $this->script;
  428. }
  429. /**
  430. * 获取生成表单的js代码
  431. *
  432. * @return string
  433. */
  434. public function formScript()
  435. {
  436. ob_start();
  437. $form = $this;
  438. require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'view' . DIRECTORY_SEPARATOR . 'formScript.php';
  439. $script = ob_get_clean();
  440. return $script;
  441. }
  442. /**
  443. * 获取表单生成器所需js
  444. *
  445. * @return array
  446. */
  447. public function getScript()
  448. {
  449. $_script = $this->script;
  450. $script = [
  451. $_script['form-create']
  452. ];
  453. if ($this->loadCityAreaData == true)
  454. $script[] = $_script['city-area-data'];
  455. if ($this->loadCityData == true)
  456. $script[] = $_script['city-data'];
  457. if ($this->linkJq)
  458. $script[] = $_script['jq'];
  459. if ($this->linkIview) {
  460. $script[] = $_script['iview'];
  461. $script[] = $_script['iview-css'];
  462. }
  463. if ($this->linkVue)
  464. $script[] = $_script['vue'];
  465. return array_reverse($script);
  466. }
  467. /**
  468. * 是否隐藏提交按钮(默认显示)
  469. *
  470. * @param bool $isShow
  471. * @return Form
  472. */
  473. public function hiddenSubmitBtn($isShow = false)
  474. {
  475. $this->submitBtn = !(bool)$isShow;
  476. return $this;
  477. }
  478. /**
  479. * 是否隐藏重置按钮(默认隐藏)
  480. *
  481. * @param bool $isShow
  482. * @return Form
  483. */
  484. public function hiddenResetBtn($isShow = false)
  485. {
  486. $this->resetBtn = !(bool)$isShow;
  487. return $this;
  488. }
  489. /**
  490. * @return bool
  491. */
  492. public function isResetBtn()
  493. {
  494. return $this->resetBtn;
  495. }
  496. /**
  497. * @return bool
  498. */
  499. public function isSubmitBtn()
  500. {
  501. return $this->submitBtn;
  502. }
  503. /**
  504. * 生成表单快捷方法
  505. *
  506. * @param string $action
  507. * @param array $components
  508. * @return Form
  509. */
  510. public static function create($action, array $components = [])
  511. {
  512. return new self($action, $components);
  513. }
  514. }