Field.php 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261
  1. <?php
  2. namespace Dcat\Admin\Form;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Form;
  5. use Dcat\Admin\Support\Helper;
  6. use Dcat\Admin\Traits\HasBuilderEvents;
  7. use Dcat\Admin\Traits\HasVariables;
  8. use Dcat\Admin\Widgets\Form as WidgetForm;
  9. use Illuminate\Contracts\Support\Arrayable;
  10. use Illuminate\Contracts\Support\Renderable;
  11. use Illuminate\Support\Arr;
  12. use Illuminate\Support\Fluent;
  13. use Illuminate\Support\Traits\Macroable;
  14. /**
  15. * Class Field.
  16. */
  17. class Field implements Renderable
  18. {
  19. use Macroable;
  20. use Form\Concerns\HasFieldValidator;
  21. use HasBuilderEvents;
  22. use HasVariables;
  23. const FILE_DELETE_FLAG = '_file_del_';
  24. const FIELD_CLASS_PREFIX = 'field_';
  25. /**
  26. * Element value.
  27. *
  28. * @var mixed
  29. */
  30. protected $value;
  31. /**
  32. * Data of all original columns of value.
  33. *
  34. * @var mixed
  35. */
  36. protected $data;
  37. /**
  38. * Field original value.
  39. *
  40. * @var mixed
  41. */
  42. protected $original;
  43. /**
  44. * Field default value.
  45. *
  46. * @var mixed
  47. */
  48. protected $default;
  49. /**
  50. * @var bool
  51. */
  52. protected $allowDefaultValueInEditPage = false;
  53. /**
  54. * Element label.
  55. *
  56. * @var string
  57. */
  58. protected $label = '';
  59. /**
  60. * Column name.
  61. *
  62. * @var string|array
  63. */
  64. protected $column = '';
  65. /**
  66. * Form element name.
  67. *
  68. * @var string|array
  69. */
  70. protected $elementName = [];
  71. /**
  72. * Form element classes.
  73. *
  74. * @var array
  75. */
  76. protected $elementClass = [];
  77. /**
  78. * Options for specify elements.
  79. *
  80. * @var array
  81. */
  82. protected $options = [];
  83. /**
  84. * Checked for specify elements.
  85. *
  86. * @var array
  87. */
  88. protected $checked = [];
  89. /**
  90. * Css required by this field.
  91. *
  92. * @var array
  93. */
  94. protected static $css = [];
  95. /**
  96. * Js required by this field.
  97. *
  98. * @var array
  99. */
  100. protected static $js = [];
  101. /**
  102. * Script for field.
  103. *
  104. * @var string
  105. */
  106. protected $script = '';
  107. /**
  108. * Element attributes.
  109. *
  110. * @var array
  111. */
  112. protected $attributes = [];
  113. /**
  114. * Parent form.
  115. *
  116. * @var Form|WidgetForm
  117. */
  118. protected $form = null;
  119. /**
  120. * View for field to render.
  121. *
  122. * @var string
  123. */
  124. protected $view = '';
  125. /**
  126. * Help block.
  127. *
  128. * @var array
  129. */
  130. protected $help = [];
  131. /**
  132. * Key for errors.
  133. *
  134. * @var string|array
  135. */
  136. protected $errorKey;
  137. /**
  138. * Placeholder for this field.
  139. *
  140. * @var string|array
  141. */
  142. protected $placeholder;
  143. /**
  144. * Width for label and field.
  145. *
  146. * @var array
  147. */
  148. protected $width = [
  149. 'label' => 2,
  150. 'field' => 8,
  151. ];
  152. /**
  153. * If the form horizontal layout.
  154. *
  155. * @var bool
  156. */
  157. protected $horizontal = true;
  158. /**
  159. * column data format.
  160. *
  161. * @var \Closure
  162. */
  163. protected $customFormat = null;
  164. /**
  165. * @var bool
  166. */
  167. protected $display = true;
  168. /**
  169. * @var array
  170. */
  171. protected $labelClass = ['text-capitalize'];
  172. /**
  173. * @var array
  174. */
  175. protected $fieldClass = [];
  176. /**
  177. * @var array
  178. */
  179. protected $formGroupClass = ['form-field'];
  180. /**
  181. * @var \Closure[]
  182. */
  183. protected $savingCallbacks = [];
  184. /**
  185. * Field constructor.
  186. *
  187. * @param string|array $column
  188. * @param array $arguments
  189. */
  190. public function __construct($column, $arguments = [])
  191. {
  192. $this->column = $column;
  193. $this->label = $this->formatLabel($arguments);
  194. $this->callResolving();
  195. }
  196. /**
  197. * @param array $options
  198. *
  199. * @return $this
  200. */
  201. public function setNestedFormRelation(array $options = [])
  202. {
  203. return $this;
  204. }
  205. /**
  206. * Format the label value.
  207. *
  208. * @param array $arguments
  209. *
  210. * @return string
  211. */
  212. protected function formatLabel($arguments = [])
  213. {
  214. if (isset($arguments[0])) {
  215. return $arguments[0];
  216. }
  217. $column = is_array($this->column) ? current($this->column) : $this->column;
  218. return str_replace('_', ' ', admin_trans_field($column));
  219. }
  220. /**
  221. * Format the name of the field.
  222. *
  223. * @param string $column
  224. *
  225. * @return array|mixed|string
  226. */
  227. protected function formatName($column)
  228. {
  229. return Helper::formatElementName($column);
  230. }
  231. /**
  232. * Set form element name.
  233. *
  234. * @param string|array $name
  235. *
  236. * @return $this
  237. *
  238. * @author Edwin Hui
  239. */
  240. public function setElementName($name)
  241. {
  242. $this->elementName = $name;
  243. return $this;
  244. }
  245. /**
  246. * Get form element name.
  247. *
  248. * @return array|mixed|string
  249. */
  250. public function getElementName()
  251. {
  252. return $this->elementName ?: $this->formatName($this->column);
  253. }
  254. /**
  255. * Fill data to the field.
  256. *
  257. * @param array $data
  258. *
  259. * @return void
  260. */
  261. final public function fill($data)
  262. {
  263. $data = Helper::array($data);
  264. $this->data($data);
  265. $this->value = $this->formatFieldData($data);
  266. $this->callCustomFormatter();
  267. }
  268. /**
  269. * Format field data.
  270. *
  271. * @param array $data
  272. *
  273. * @return mixed
  274. */
  275. protected function formatFieldData($data)
  276. {
  277. if (is_array($this->column)) {
  278. $value = [];
  279. foreach ($this->column as $key => $column) {
  280. $value[$key] = Arr::get($data, $this->normalizeColumn($column));
  281. }
  282. return $value;
  283. }
  284. return Arr::get($data, $this->normalizeColumn(), $this->value);
  285. }
  286. protected function normalizeColumn(?string $column = null)
  287. {
  288. return str_replace('->', '.', $column ?: $this->column);
  289. }
  290. /**
  291. * custom format form column data when edit.
  292. *
  293. * @param \Closure $call
  294. *
  295. * @return $this
  296. */
  297. public function customFormat(\Closure $call)
  298. {
  299. $this->customFormat = $call;
  300. return $this;
  301. }
  302. /**
  303. * Set original value to the field.
  304. *
  305. * @param array $data
  306. *
  307. * @return void
  308. */
  309. final public function setOriginal($data)
  310. {
  311. $data = Helper::array($data);
  312. $this->original = $this->formatFieldData($data);
  313. $this->callCustomFormatter('original', new Fluent($data));
  314. }
  315. /**
  316. * @param string $key
  317. * @param Fluent|null $dataremoveField
  318. */
  319. protected function callCustomFormatter($key = 'value', Fluent $data = null)
  320. {
  321. if ($this->customFormat) {
  322. $this->{$key} = $this->customFormat
  323. ->call(
  324. $data ?: $this->data(),
  325. $this->{$key},
  326. $this->column,
  327. $this
  328. );
  329. }
  330. }
  331. /**
  332. * @param Form|WidgetForm $form
  333. *
  334. * @return $this
  335. */
  336. public function setForm($form = null)
  337. {
  338. $this->form = $form;
  339. return $this;
  340. }
  341. /**
  342. * @return Fluent
  343. */
  344. public function values()
  345. {
  346. return $this->form ? $this->form->model() : new Fluent();
  347. }
  348. /**
  349. * Set width for field and label.
  350. *
  351. * @param int $field
  352. * @param int $label
  353. *
  354. * @return $this
  355. */
  356. public function width($field = 8, $label = 2)
  357. {
  358. $this->width = [
  359. 'label' => $label,
  360. 'field' => $field,
  361. ];
  362. return $this;
  363. }
  364. /**
  365. * Set the field options.
  366. *
  367. * @param array $options
  368. *
  369. * @return $this
  370. */
  371. public function options($options = [])
  372. {
  373. if ($options instanceof \Closure) {
  374. $options = $options->call($this->data(), $this->value());
  375. }
  376. $this->options = array_merge($this->options, Helper::array($options));
  377. return $this;
  378. }
  379. /**
  380. * @param array $options
  381. *
  382. * @return $this
  383. */
  384. public function replaceOptions($options)
  385. {
  386. if ($options instanceof \Closure) {
  387. $options = $options->call($this->data(), $this->value());
  388. }
  389. $this->options = $options;
  390. return $this;
  391. }
  392. /**
  393. * @param array|Arrayable $options
  394. *
  395. * @return $this
  396. */
  397. public function mergeOptions($options)
  398. {
  399. return $this->options($options);
  400. }
  401. /**
  402. * Set the field option checked.
  403. *
  404. * @param array $checked
  405. *
  406. * @return $this
  407. */
  408. public function checked($checked = [])
  409. {
  410. if ($checked instanceof Arrayable) {
  411. $checked = $checked->toArray();
  412. }
  413. $this->checked = array_merge($this->checked, (array) $checked);
  414. return $this;
  415. }
  416. /**
  417. * Set key for error message.
  418. *
  419. * @param string|array $key
  420. *
  421. * @return $this
  422. */
  423. public function setErrorKey($key)
  424. {
  425. $this->errorKey = $key;
  426. return $this;
  427. }
  428. /**
  429. * Get key for error message.
  430. *
  431. * @return string
  432. */
  433. public function getErrorKey()
  434. {
  435. return $this->errorKey ?: $this->column;
  436. }
  437. /**
  438. * Set or get value of the field.
  439. *
  440. * @param null $value
  441. *
  442. * @return mixed
  443. */
  444. public function value($value = null)
  445. {
  446. if (is_null($value)) {
  447. if (
  448. $this->value === null
  449. || (is_array($this->value) && empty($this->value))
  450. ) {
  451. return $this->default();
  452. }
  453. return $this->value;
  454. }
  455. $this->value = value($value);
  456. return $this;
  457. }
  458. /**
  459. * Set or get data.
  460. *
  461. * @param array $data
  462. *
  463. * @return $this|Fluent
  464. */
  465. public function data(array $data = null)
  466. {
  467. if (is_null($data)) {
  468. if (! $this->data || is_array($this->data)) {
  469. $this->data = new Fluent((array) $this->data);
  470. }
  471. return $this->data;
  472. }
  473. $this->data = new Fluent($data);
  474. return $this;
  475. }
  476. /**
  477. * Get or set default value for field.
  478. *
  479. * @param mixed $default
  480. * @param bool $edit
  481. *
  482. * @return $this|mixed
  483. */
  484. public function default($default = null, bool $edit = false)
  485. {
  486. if ($default === null) {
  487. if (
  488. $this->form
  489. && method_exists($this->form, 'isCreating')
  490. && ! $this->form->isCreating()
  491. && ! $this->allowDefaultValueInEditPage
  492. ) {
  493. return;
  494. }
  495. if ($this->default instanceof \Closure) {
  496. $this->default->bindTo($this->data());
  497. return call_user_func($this->default, $this->form);
  498. }
  499. return $this->default;
  500. }
  501. $this->default = value($default);
  502. $this->allowDefaultValueInEditPage = $edit;
  503. return $this;
  504. }
  505. /**
  506. * Set help block for current field.
  507. *
  508. * @param string $text
  509. * @param string $icon
  510. *
  511. * @return $this
  512. */
  513. public function help($text = '', $icon = 'feather icon-help-circle')
  514. {
  515. $this->help = compact('text', 'icon');
  516. return $this;
  517. }
  518. /**
  519. * Get column of the field.
  520. *
  521. * @return string|array
  522. */
  523. public function column()
  524. {
  525. return $this->column;
  526. }
  527. /**
  528. * Get or set label of the field.
  529. *
  530. * @param null $label
  531. *
  532. * @return $this|string
  533. */
  534. public function label($label = null)
  535. {
  536. if ($label == null) {
  537. return $this->label;
  538. }
  539. if ($label instanceof \Closure) {
  540. $label = $label($this->label);
  541. }
  542. $this->label = $label;
  543. return $this;
  544. }
  545. /**
  546. * Get original value of the field.
  547. *
  548. * @return mixed
  549. */
  550. public function original()
  551. {
  552. return $this->original;
  553. }
  554. /**
  555. * Sanitize input data.
  556. *
  557. * @param array $input
  558. * @param string $column
  559. *
  560. * @return array
  561. */
  562. protected function sanitizeInput($input, $column)
  563. {
  564. if ($this instanceof Field\MultipleSelect) {
  565. $value = Arr::get($input, $column);
  566. Arr::set($input, $column, array_filter($value));
  567. }
  568. return $input;
  569. }
  570. /**
  571. * Add html attributes to elements.
  572. *
  573. * @param array|string $attribute
  574. * @param mixed $value
  575. *
  576. * @return $this
  577. */
  578. public function attribute($attribute, $value = null)
  579. {
  580. if (is_array($attribute)) {
  581. $this->attributes = array_merge($this->attributes, $attribute);
  582. } else {
  583. $this->attributes[$attribute] = (string) $value;
  584. }
  585. return $this;
  586. }
  587. /**
  588. * @param string $key
  589. *
  590. * @return bool
  591. */
  592. public function hasAttribute(string $key)
  593. {
  594. return array_key_exists($key, $this->attributes);
  595. }
  596. /**
  597. * @param string $key
  598. *
  599. * @return mixed|null
  600. */
  601. public function getAttribute(string $key)
  602. {
  603. return $this->attributes[$key] ?? null;
  604. }
  605. /**
  606. * Specifies a regular expression against which to validate the value of the input.
  607. *
  608. * @param string $error
  609. * @param string $regexp
  610. *
  611. * @return $this
  612. */
  613. public function pattern($regexp, $error = null)
  614. {
  615. if ($error) {
  616. $this->attribute('data-pattern-error', $error);
  617. }
  618. return $this->attribute('pattern', $regexp);
  619. }
  620. /**
  621. * set the input filed required.
  622. *
  623. * @param bool $isLabelAsterisked
  624. *
  625. * @return $this
  626. */
  627. public function required($isLabelAsterisked = true)
  628. {
  629. if ($isLabelAsterisked) {
  630. $this->setLabelClass(['asterisk']);
  631. }
  632. $this->rules('required');
  633. return $this->attribute('required', true);
  634. }
  635. /**
  636. * Set the field automatically get focus.
  637. *
  638. * @return $this
  639. */
  640. public function autofocus()
  641. {
  642. return $this->attribute('autofocus', true);
  643. }
  644. /**
  645. * Set the field as readonly mode.
  646. *
  647. * @return $this
  648. */
  649. public function readOnly()
  650. {
  651. return $this->attribute('readonly', true);
  652. }
  653. /**
  654. * Set field as disabled.
  655. *
  656. * @return $this
  657. */
  658. public function disable()
  659. {
  660. return $this->attribute('disabled', true);
  661. }
  662. /**
  663. * Get or set field placeholder.
  664. *
  665. * @param string $placeholder
  666. *
  667. * @return $this|string
  668. */
  669. public function placeholder($placeholder = null)
  670. {
  671. if ($placeholder === null) {
  672. return $this->placeholder ?: trans('admin.input').' '.$this->label;
  673. }
  674. $this->placeholder = $placeholder;
  675. return $this;
  676. }
  677. /**
  678. * @param mixed $value
  679. *
  680. * @return mixed
  681. */
  682. protected function prepareInputValue($value)
  683. {
  684. return $value;
  685. }
  686. /**
  687. * @param \Closure $closure
  688. *
  689. * @return $this
  690. */
  691. public function saving(\Closure $closure)
  692. {
  693. $this->savingCallbacks[] = $closure;
  694. return $this;
  695. }
  696. /**
  697. * Prepare for a field value before update or insert.
  698. *
  699. * @param mixed $value
  700. *
  701. * @return mixed
  702. */
  703. final public function prepare($value)
  704. {
  705. $value = $this->prepareInputValue($value);
  706. if ($this->savingCallbacks) {
  707. foreach ($this->savingCallbacks as $callback) {
  708. $value = $callback->call($this->data(), $value);
  709. }
  710. }
  711. return $value;
  712. }
  713. /**
  714. * Format the field attributes.
  715. *
  716. * @return string
  717. */
  718. protected function formatAttributes()
  719. {
  720. $html = [];
  721. foreach ($this->attributes as $name => $value) {
  722. $html[] = $name.'="'.e($value).'"';
  723. }
  724. return implode(' ', $html);
  725. }
  726. /**
  727. * @return $this
  728. */
  729. public function disableHorizontal()
  730. {
  731. $this->horizontal = false;
  732. return $this;
  733. }
  734. /**
  735. * @return array
  736. */
  737. public function getViewElementClasses()
  738. {
  739. if ($this->horizontal) {
  740. return [
  741. 'label' => "col-md-{$this->width['label']} {$this->getLabelClass()}",
  742. 'field' => "col-md-{$this->width['field']} {$this->getFieldClass()}",
  743. 'form-group' => "form-group row {$this->getFormGroupClass()}",
  744. ];
  745. }
  746. return [
  747. 'label' => $this->getLabelClass(),
  748. 'field' => $this->getFieldClass(),
  749. 'form-group' => $this->getFormGroupClass(),
  750. ];
  751. }
  752. /**
  753. * Set element class.
  754. *
  755. * @param string|array $class
  756. *
  757. * @return $this
  758. */
  759. public function setElementClass($class)
  760. {
  761. $this->elementClass = array_merge($this->elementClass, (array) $this->normalizeElementClass($class));
  762. return $this;
  763. }
  764. /**
  765. * Get element class.
  766. *
  767. * @return array
  768. */
  769. public function getElementClass()
  770. {
  771. if (! $this->elementClass) {
  772. $this->elementClass = $this->normalizeElementClass((array) $this->getElementName());
  773. }
  774. return $this->elementClass;
  775. }
  776. /**
  777. * @param string|array $class
  778. *
  779. * @return array|string
  780. */
  781. public function normalizeElementClass($class)
  782. {
  783. if (is_array($class)) {
  784. return array_map([$this, 'normalizeElementClass'], $class);
  785. }
  786. return static::FIELD_CLASS_PREFIX.str_replace(['[', ']', '->', '.'], '_', $class);
  787. }
  788. /**
  789. * Get element class selector.
  790. *
  791. * @return string|array
  792. */
  793. public function getElementClassSelector()
  794. {
  795. $elementClass = $this->getElementClass();
  796. $formId = $this->getFormElementId();
  797. $formId = $formId ? '#'.$formId : '';
  798. if (Arr::isAssoc($elementClass)) {
  799. $classes = [];
  800. foreach ($elementClass as $index => $class) {
  801. $classes[$index] = $formId.' .'.(is_array($class) ? implode('.', $class) : $class);
  802. }
  803. return $classes;
  804. }
  805. return $formId.' .'.implode('.', $elementClass);
  806. }
  807. /**
  808. * Get element class string.
  809. *
  810. * @return mixed
  811. */
  812. public function getElementClassString()
  813. {
  814. $elementClass = $this->getElementClass();
  815. if (Arr::isAssoc($elementClass)) {
  816. $classes = [];
  817. foreach ($elementClass as $index => $class) {
  818. $classes[$index] = is_array($class) ? implode(' ', $class) : $class;
  819. }
  820. return $classes;
  821. }
  822. return implode(' ', $elementClass);
  823. }
  824. /**
  825. * @return $this
  826. */
  827. public function hideInDialog()
  828. {
  829. if (
  830. $this->form instanceof Form
  831. && $this->form->inDialog()
  832. ) {
  833. $this->display(false);
  834. }
  835. return $this;
  836. }
  837. /**
  838. * @return string|null
  839. */
  840. protected function getFormElementId()
  841. {
  842. return $this->form ? $this->form->getElementId() : null;
  843. }
  844. /**
  845. * Add the element class.
  846. *
  847. * @param $class
  848. *
  849. * @return $this
  850. */
  851. public function addElementClass($class)
  852. {
  853. $this->elementClass = array_unique(
  854. array_merge($this->elementClass, (array) $class)
  855. );
  856. return $this;
  857. }
  858. /**
  859. * Remove element class.
  860. *
  861. * @param $class
  862. *
  863. * @return $this
  864. */
  865. public function removeElementClass($class)
  866. {
  867. $delClass = [];
  868. if (is_string($class) || is_array($class)) {
  869. $delClass = (array) $class;
  870. }
  871. foreach ($delClass as $del) {
  872. if (($key = array_search($del, $this->elementClass))) {
  873. unset($this->elementClass[$key]);
  874. }
  875. }
  876. return $this;
  877. }
  878. /**
  879. * @param array|string $labelClass
  880. * @param bool $append
  881. *
  882. * @return $this|string
  883. */
  884. public function setLabelClass($labelClass, bool $append = true)
  885. {
  886. $this->labelClass = $append
  887. ? array_unique(array_merge($this->labelClass, (array) $labelClass))
  888. : (array) $labelClass;
  889. return $this;
  890. }
  891. /**
  892. * @return string
  893. */
  894. public function getLabelClass()
  895. {
  896. return implode(' ', $this->labelClass);
  897. }
  898. /**
  899. * @param mixed $value
  900. * @param callable $callback
  901. *
  902. * @return $this|mixed
  903. */
  904. public function when($value, $callback)
  905. {
  906. if ($value) {
  907. return $callback($this, $value) ?: $this;
  908. }
  909. return $this;
  910. }
  911. public function setFormGroupClass($labelClass, bool $append = true)
  912. {
  913. $this->formGroupClass = $append
  914. ? array_unique(array_merge($this->formGroupClass, (array) $labelClass))
  915. : (array) $labelClass;
  916. return $this;
  917. }
  918. public function getFormGroupClass()
  919. {
  920. return implode(' ', $this->formGroupClass);
  921. }
  922. public function setFieldClass($labelClass, bool $append = true)
  923. {
  924. $this->fieldClass = $append
  925. ? array_unique(array_merge($this->fieldClass, (array) $labelClass))
  926. : (array) $labelClass;
  927. return $this;
  928. }
  929. public function getFieldClass()
  930. {
  931. return implode(' ', $this->fieldClass);
  932. }
  933. /**
  934. * Get the view variables of this field.
  935. *
  936. * @return array
  937. */
  938. public function defaultVariables()
  939. {
  940. return [
  941. 'name' => $this->getElementName(),
  942. 'help' => $this->help,
  943. 'class' => $this->getElementClassString(),
  944. 'value' => $this->value(),
  945. 'label' => $this->label,
  946. 'viewClass' => $this->getViewElementClasses(),
  947. 'column' => $this->column,
  948. 'errorKey' => $this->getErrorKey(),
  949. 'attributes' => $this->formatAttributes(),
  950. 'placeholder' => $this->placeholder(),
  951. 'disabled' => $this->attributes['disabled'] ?? false,
  952. 'formId' => $this->getFormElementId(),
  953. 'selector' => $this->getElementClassSelector(),
  954. 'options' => $this->options,
  955. ];
  956. }
  957. protected function isCreating()
  958. {
  959. return request()->isMethod('POST');
  960. }
  961. protected function isEditing()
  962. {
  963. return request()->isMethod('PUT');
  964. }
  965. /**
  966. * Get view of this field.
  967. *
  968. * @return string
  969. */
  970. public function view()
  971. {
  972. return $this->view ?: 'admin::form.'.strtolower(class_basename(static::class));
  973. }
  974. /**
  975. * Set view of current field.
  976. *
  977. * @return string
  978. */
  979. public function setView($view)
  980. {
  981. $this->view = $view;
  982. return $this;
  983. }
  984. /**
  985. * Get script of current field.
  986. *
  987. * @return string
  988. */
  989. public function getScript()
  990. {
  991. return $this->script;
  992. }
  993. /**
  994. * Set script of current field.
  995. *
  996. * @return self
  997. */
  998. public function script($script)
  999. {
  1000. $this->script = $script;
  1001. return $this;
  1002. }
  1003. /**
  1004. * To set this field should render or not.
  1005. *
  1006. * @return self
  1007. */
  1008. public function display(bool $display)
  1009. {
  1010. $this->display = $display;
  1011. return $this;
  1012. }
  1013. /**
  1014. * If this field should render.
  1015. *
  1016. * @return bool
  1017. */
  1018. protected function shouldRender()
  1019. {
  1020. return $this->display;
  1021. }
  1022. public function saveAsJson($option = 0)
  1023. {
  1024. return $this->saving(function ($value) use ($option) {
  1025. if (! $value || is_scalar($value)) {
  1026. return $value;
  1027. }
  1028. return json_encode($value, $option);
  1029. });
  1030. }
  1031. public function saveAsString()
  1032. {
  1033. return $this->saving(function ($value) {
  1034. return (string) $value;
  1035. });
  1036. }
  1037. /**
  1038. * Collect assets required by this field.
  1039. */
  1040. public static function requireAssets()
  1041. {
  1042. static::$js && Admin::js(static::$js);
  1043. static::$css && Admin::css(static::$css);
  1044. }
  1045. /**
  1046. * Render this filed.
  1047. *
  1048. * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View|string
  1049. */
  1050. public function render()
  1051. {
  1052. if (! $this->shouldRender()) {
  1053. return '';
  1054. }
  1055. $this->callComposing();
  1056. $this->withScript();
  1057. return Admin::view($this->view(), $this->variables());
  1058. }
  1059. protected function withScript()
  1060. {
  1061. if ($this->script) {
  1062. Admin::script($this->script);
  1063. }
  1064. }
  1065. /**
  1066. * @return string
  1067. */
  1068. public function __toString()
  1069. {
  1070. $view = $this->render();
  1071. return $view instanceof Renderable ? $view->render() : (string) $view;
  1072. }
  1073. }