ListField.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. <?php
  2. namespace Dcat\Admin\Form\Field;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Form\Field;
  5. use Dcat\Admin\Support\Helper;
  6. use Illuminate\Support\Arr;
  7. use Illuminate\Support\MessageBag;
  8. class ListField extends Field
  9. {
  10. const DEFAULT_FLAG_NAME = '_def_';
  11. /**
  12. * Max list size.
  13. *
  14. * @var int
  15. */
  16. protected $max;
  17. /**
  18. * Minimum list size.
  19. *
  20. * @var int
  21. */
  22. protected $min = 0;
  23. /**
  24. * Set Max list size.
  25. *
  26. * @param int $size
  27. *
  28. * @return $this
  29. */
  30. public function max(int $size)
  31. {
  32. $this->max = $size;
  33. return $this;
  34. }
  35. /**
  36. * Set Minimum list size.
  37. *
  38. * @param int $size
  39. *
  40. * @return $this
  41. */
  42. public function min(int $size)
  43. {
  44. $this->min = $size;
  45. return $this;
  46. }
  47. /**
  48. * Fill data to the field.
  49. *
  50. * @param array $data
  51. *
  52. * @return array
  53. */
  54. public function formatFieldData($data)
  55. {
  56. $this->data = $data;
  57. return Helper::array(Arr::get($data, $this->column, $this->value));
  58. }
  59. /**
  60. * {@inheritdoc}
  61. */
  62. public function getValidator(array $input)
  63. {
  64. if ($this->validator) {
  65. return $this->validator->call($this, $input);
  66. }
  67. if (! is_string($this->column)) {
  68. return false;
  69. }
  70. $rules = $attributes = [];
  71. if (
  72. (! $fieldRules = $this->getRules())
  73. && ! $this->max
  74. && ! $this->min
  75. ) {
  76. return false;
  77. }
  78. if (! Arr::has($input, $this->column)) {
  79. return false;
  80. }
  81. if ($fieldRules) {
  82. $rules["{$this->column}.values.*"] = $fieldRules;
  83. }
  84. $attributes["{$this->column}.values.*"] = __('Value');
  85. $rules["{$this->column}.values"][] = 'array';
  86. if (! is_null($this->max)) {
  87. $rules["{$this->column}.values"][] = "max:$this->max";
  88. }
  89. if (! is_null($this->min)) {
  90. $rules["{$this->column}.values"][] = "min:$this->min";
  91. }
  92. $attributes["{$this->column}.values"] = $this->label;
  93. $input = $this->prepareValidatorInput($input);
  94. return validator($input, $rules, $this->getValidationMessages(), $attributes);
  95. }
  96. public function formatValidatorMessages($messageBag)
  97. {
  98. $messages = new MessageBag();
  99. foreach ($messageBag->toArray() as $column => $message) {
  100. $messages->add($this->column, $message);
  101. }
  102. return $messages;
  103. }
  104. protected function prepareValidatorInput(array $input)
  105. {
  106. Arr::forget($input, "{$this->column}.values.".static::DEFAULT_FLAG_NAME);
  107. return $input;
  108. }
  109. /**
  110. * {@inheritdoc}
  111. */
  112. protected function addScript()
  113. {
  114. $value = old($this->column, $this->value());
  115. $number = $value ? count($value) : 0;
  116. $this->script = <<<JS
  117. (function () {
  118. var index = {$number};
  119. $('.{$this->column}-add').on('click', function () {
  120. var tpl = $('template.{$this->column}-tpl').html().replace('{key}', index);
  121. $('tbody.list-{$this->column}-table').append(tpl);
  122. index++;
  123. });
  124. $('tbody').on('click', '.{$this->column}-remove', function () {
  125. $(this).closest('tr').remove();
  126. });
  127. })();
  128. JS;
  129. }
  130. /**
  131. * {@inheritdoc}
  132. */
  133. protected function prepareInputValue($value)
  134. {
  135. unset($value['values'][static::DEFAULT_FLAG_NAME]);
  136. if (empty($value['values'])) {
  137. return '[]';
  138. }
  139. return json_encode(array_values($value['values']));
  140. }
  141. /**
  142. * {@inheritdoc}
  143. */
  144. public function render()
  145. {
  146. $this->addScript();
  147. Admin::style('td .form-group {margin-bottom: 0 !important;}');
  148. return parent::render();
  149. }
  150. }