DialogForm.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. <?php
  2. namespace Dcat\Admin\Widgets;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Form;
  5. use Dcat\Admin\Layout\Content;
  6. use Dcat\Admin\Support\Helper;
  7. use Illuminate\Contracts\Support\Arrayable;
  8. class DialogForm
  9. {
  10. const QUERY_NAME = '_dialog_form_';
  11. /**
  12. * @var string
  13. */
  14. public static $contentView = 'admin::layouts.form-content';
  15. /**
  16. * @var array
  17. */
  18. protected $options = [
  19. 'title' => 'Form',
  20. 'area' => ['700px', '670px'],
  21. 'defaultUrl' => null,
  22. 'buttonSelector' => null,
  23. 'query' => null,
  24. 'lang' => null,
  25. 'forceRefresh' => false,
  26. 'reset' => true,
  27. ];
  28. /**
  29. * @var array
  30. */
  31. protected $handlers = [
  32. 'saved' => null,
  33. 'success' => null,
  34. 'error' => null,
  35. ];
  36. public function __construct(?string $title = null, $url = null)
  37. {
  38. $this->title($title);
  39. $this->url($url);
  40. }
  41. /**
  42. * @param array $options
  43. *
  44. * @return $this
  45. */
  46. public function options($options = [])
  47. {
  48. if ($options instanceof Arrayable) {
  49. $options = $options->toArray();
  50. }
  51. $this->options = array_merge($this->options, $options);
  52. return $this;
  53. }
  54. /**
  55. * 设置弹窗标题.
  56. *
  57. * @param string $title
  58. *
  59. * @return $this
  60. */
  61. public function title(?string $title)
  62. {
  63. $this->options['title'] = $title;
  64. return $this;
  65. }
  66. /**
  67. * 绑定点击按钮.
  68. *
  69. * @param string $buttonSelector
  70. *
  71. * @return $this
  72. */
  73. public function click(string $buttonSelector)
  74. {
  75. $this->options['buttonSelector'] = $buttonSelector;
  76. return $this;
  77. }
  78. /**
  79. * 强制每次点击按钮都重新渲染表单弹窗.
  80. *
  81. * @return $this
  82. */
  83. public function forceRefresh()
  84. {
  85. $this->options['forceRefresh'] = true;
  86. return $this;
  87. }
  88. /**
  89. * 重置按钮.
  90. *
  91. * @param bool $value
  92. *
  93. * @return $this
  94. */
  95. public function resetButton(bool $value = true)
  96. {
  97. $this->options['reset'] = $value;
  98. return $this;
  99. }
  100. /**
  101. * 保存后触发的js的代码(不论成功还是失败).
  102. *
  103. * @param string $script
  104. *
  105. * @return $this
  106. */
  107. public function saved(string $script)
  108. {
  109. $this->handlers['saved'] = $script;
  110. return $this;
  111. }
  112. /**
  113. * 保存失败时触发的js代码
  114. *
  115. * @param string $script
  116. *
  117. * @return $this
  118. */
  119. public function error(string $script)
  120. {
  121. $this->handlers['error'] = $script;
  122. return $this;
  123. }
  124. /**
  125. * 保存成功后触发的js代码
  126. *
  127. * @param string $script
  128. *
  129. * @return $this
  130. */
  131. public function success(string $script)
  132. {
  133. $this->handlers['success'] = $script;
  134. return $this;
  135. }
  136. /**
  137. * 设置弹窗宽高
  138. * 支持百分比和"px".
  139. *
  140. * @param string $width
  141. * @param string $height
  142. *
  143. * @return $this
  144. */
  145. public function dimensions(string $width, string $height)
  146. {
  147. $this->options['area'] = [$width, $height];
  148. return $this;
  149. }
  150. /**
  151. * 设置弹窗宽度
  152. * 支持百分比和"px".
  153. *
  154. * @param string|null $width
  155. *
  156. * @return $this
  157. */
  158. public function width(?string $width)
  159. {
  160. $this->options['area'][0] = $width;
  161. return $this;
  162. }
  163. /**
  164. * 设置弹窗高度
  165. * 支持百分比和"px".
  166. *
  167. * @param string|null $height
  168. *
  169. * @return $this
  170. */
  171. public function height(?string $height)
  172. {
  173. $this->options['area'][1] = $height;
  174. return $this;
  175. }
  176. /**
  177. * 设置默认的表单页面url.
  178. *
  179. * @param null|string $url
  180. *
  181. * @return $this
  182. */
  183. public function url(?string $url)
  184. {
  185. if ($url) {
  186. $this->options['defaultUrl'] = Helper::urlWithQuery(
  187. admin_url($url),
  188. [static::QUERY_NAME => 1]
  189. );
  190. }
  191. return $this;
  192. }
  193. /**
  194. * @return string
  195. */
  196. protected function render()
  197. {
  198. $this->setUpOptions();
  199. $opts = json_encode($this->options);
  200. Admin::script(
  201. <<<JS
  202. (function () {
  203. var opts = {$opts};
  204. opts.success = function (success, response) {
  205. {$this->handlers['success']}
  206. };
  207. opts.error = function (success, response) {
  208. {$this->handlers['error']}
  209. };
  210. opts.saved = function (success, response) {
  211. {$this->handlers['saved']}
  212. };
  213. Dcat.DialogForm(opts);
  214. })();
  215. JS
  216. );
  217. }
  218. /**
  219. * 配置选项初始化.
  220. *
  221. * @return void
  222. */
  223. protected function setUpOptions()
  224. {
  225. $this->options['lang'] = [
  226. 'submit' => trans('admin.submit'),
  227. 'reset' => trans('admin.reset'),
  228. ];
  229. $this->options['query'] = static::QUERY_NAME;
  230. }
  231. /**
  232. * 判断是否是获取弹窗表单内容的请求
  233. *
  234. * @return bool
  235. */
  236. public static function is()
  237. {
  238. return request(static::QUERY_NAME) ? true : false;
  239. }
  240. /**
  241. * @param Form $form
  242. */
  243. public static function prepare(Form $form)
  244. {
  245. if (! static::is()) {
  246. return;
  247. }
  248. Admin::baseCss([], false);
  249. Admin::baseJs([], false);
  250. Admin::fonts(false);
  251. Admin::style('.form-content{ padding-top: 7px }');
  252. $form->wrap(function ($v) {
  253. return $v;
  254. });
  255. $form->disableHeader();
  256. $form->disableFooter();
  257. $form->width(9, 2);
  258. $form->composing(function ($form) {
  259. static::addScript($form);
  260. });
  261. Content::composing(function (Content $content) {
  262. $content->view(static::$contentView);
  263. });
  264. }
  265. protected static function addScript(Form $form)
  266. {
  267. $confirm = json_encode($form->builder()->confirm);
  268. Admin::script(
  269. <<<JS
  270. Dcat.FormConfirm = {$confirm};
  271. JS
  272. );
  273. }
  274. public function __destruct()
  275. {
  276. if ($results = Helper::render($this->render())) {
  277. Admin::html($results);
  278. }
  279. }
  280. }