SelectResource.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  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\Contracts\Support\Arrayable;
  7. class SelectResource extends Field
  8. {
  9. use PlainInput;
  10. protected static $js = [
  11. '@resource-selector',
  12. ];
  13. protected $area = ['51%', '65%'];
  14. protected $source;
  15. protected $maxItem = 1;
  16. protected $style = 'primary';
  17. protected $btnId;
  18. /**
  19. * Set window's area.
  20. *
  21. * @param string $width
  22. * @param string $height
  23. *
  24. * @return $this
  25. */
  26. public function area(string $width, string $height)
  27. {
  28. $this->area = [$width, $height];
  29. return $this;
  30. }
  31. /**
  32. * Set button style.
  33. *
  34. * @param string $style
  35. *
  36. * @return $this
  37. */
  38. public function style(string $style = 'primary')
  39. {
  40. $this->style = $style;
  41. return $this;
  42. }
  43. /**
  44. * Set the field options.
  45. *
  46. * @param array|\Closure $options
  47. *
  48. * @return $this
  49. */
  50. public function options($options = [])
  51. {
  52. if ($options instanceof Arrayable) {
  53. $options = $options->toArray();
  54. }
  55. $this->options = $options;
  56. return $this;
  57. }
  58. protected function formatOptions()
  59. {
  60. if ($this->options instanceof \Closure) {
  61. $value = Helper::array(old($this->column, $this->value()));
  62. $this->options = $this->options->call($this->values(), $value, $this);
  63. }
  64. $this->options = Helper::array($this->options);
  65. }
  66. /**
  67. * Multiple select.
  68. *
  69. * @param int|null|null $max
  70. *
  71. * @return SelectResource
  72. */
  73. public function multiple(?int $max = null)
  74. {
  75. return $this->max($max);
  76. }
  77. /**
  78. * @param ?int $max
  79. *
  80. * @return $this
  81. */
  82. public function max(?int $max)
  83. {
  84. $this->maxItem = $max;
  85. return $this;
  86. }
  87. /**
  88. * Set source path.
  89. *
  90. * @param string $source
  91. *
  92. * @return $this
  93. */
  94. public function path($source)
  95. {
  96. $this->source = admin_url($source);
  97. return $this;
  98. }
  99. protected function formatValue()
  100. {
  101. $value = Helper::array(old($this->column, $this->value));
  102. $this->value = [];
  103. foreach ($this->options as $id => $label) {
  104. foreach ($value as $v) {
  105. if ($v == $id && $v !== null) {
  106. $this->value[$v] = $label;
  107. }
  108. }
  109. }
  110. $this->value = json_encode((object) $this->value);
  111. }
  112. protected function setDefaultSource()
  113. {
  114. if (! $this->source) {
  115. if (strpos($this->column, '.')) {
  116. $this->path(str_replace('_id', '', last(explode('.', $this->column))));
  117. } else {
  118. $this->path(str_replace('_id', '', $this->column));
  119. }
  120. }
  121. }
  122. protected function prepareToSave($value)
  123. {
  124. if ($this->maxItem == 1) {
  125. if ($value === null || $value === '') {
  126. return 0;
  127. }
  128. return $value;
  129. }
  130. return Helper::array($value, true);
  131. }
  132. protected function setupScript()
  133. {
  134. $label = ucfirst(trans('admin.choose')).' '.$this->label;
  135. $area = json_encode($this->area);
  136. $disabled = empty($this->attributes['disabled']) ? '' : 'disabled';
  137. $containerId = $this->id.$this->getFormElementId();
  138. $maxItem = (int) $this->maxItem;
  139. Admin::script(
  140. <<<JS
  141. Dcat.ResourceSelector({
  142. title: '{$label}',
  143. column: "{$this->getElementName()}",
  144. source: '{$this->source}',
  145. selector: '#{$this->btnId}',
  146. maxItem: {$maxItem},
  147. area: {$area},
  148. items: {$this->value()},
  149. placeholder: '{$this->placeholder()}',
  150. showCloseButton: false,
  151. disabled: '{$disabled}',
  152. displayer: 'navList',
  153. displayerContainer: $('#{$containerId}'),
  154. });
  155. JS
  156. );
  157. }
  158. protected function setupStyle()
  159. {
  160. if (! $this->maxItem || $this->maxItem > 1) {
  161. $primayDarker = Admin::color()->primaryDarker();
  162. Admin::style(
  163. ".select-resource .nav li a{padding:8px 10px;font-size:13px;font-weight:bold;color:{$primayDarker}}.select-resource .nav li a.red{cursor:pointer}.select-resource .nav-stacked>li{border-bottom:1px solid #eee;background: #fff;}.select-resource .nav {border: 1px solid #eee;margin-bottom:5px;}"
  164. );
  165. }
  166. }
  167. /**
  168. * {@inheritdoc}
  169. */
  170. public function render()
  171. {
  172. $this->btnId = $this->id.'-select-resource';
  173. $this->formatOptions();
  174. $this->formatValue();
  175. $this->setDefaultSource();
  176. $this->setupStyle();
  177. $this->setupScript();
  178. $name = $this->elementName ?: $this->formatName($this->column);
  179. $this->prepend('<i class="feather icon-arrow-up"></i>')
  180. ->defaultAttribute('class', 'form-control '.$this->getElementClassString())
  181. ->defaultAttribute('type', 'text')
  182. ->defaultAttribute('id', $this->id.$this->getFormElementId())
  183. ->defaultAttribute('name', $name);
  184. $this->addVariables([
  185. 'className' => str_replace(['[', ']'], '_', $name),
  186. 'prepend' => $this->prepend,
  187. 'append' => $this->append,
  188. 'placeholder' => $this->placeholder(),
  189. 'style' => $this->style,
  190. 'btnId' => $this->btnId,
  191. ]);
  192. return parent::render();
  193. }
  194. }