Field.php 24 KB

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