Autocomplete.php 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. <?php
  2. namespace Dcat\Admin\Form\Field;
  3. use Dcat\Admin\Support\Helper;
  4. use Dcat\Admin\Support\JavaScript;
  5. class Autocomplete extends Text
  6. {
  7. use HasDepends;
  8. protected $view = 'admin::form.autocomplete';
  9. protected $groups = [];
  10. protected $groupBy = '__group__';
  11. protected $configs = [
  12. 'autoSelectFirst' => true,
  13. ];
  14. public function __construct($column, $arguments = [])
  15. {
  16. $this->prepend('<i class="feather icon-edit-2"></i>');
  17. parent::__construct($column, $arguments);
  18. }
  19. public function datalist($entries = [])
  20. {
  21. return $this->options($entries);
  22. }
  23. /**
  24. * Set option groups.
  25. *
  26. * eg: $group = [
  27. * [
  28. * 'label' => 'xxxx',
  29. * 'options' => [
  30. * 'foo',
  31. * 'bar',
  32. * ...
  33. * ],
  34. * ...
  35. * ]
  36. *
  37. * @param array|\Closure $groups
  38. * @return $this
  39. */
  40. public function groups($groups = [])
  41. {
  42. if ($groups instanceof \Closure) {
  43. $groups = $groups->call($this->data(), $this->value());
  44. }
  45. $this->groups = array_merge($this->groups, $groups);
  46. return $this;
  47. }
  48. /**
  49. * @param array|\Closure $options
  50. * @return $this|Autocomplete
  51. */
  52. public function options($options = [])
  53. {
  54. if ($options instanceof \Closure) {
  55. $options = $options->call($this->data(), $this->value());
  56. }
  57. $this->options = array_merge($this->options, $this->formatOptions($options));
  58. return $this;
  59. }
  60. /**
  61. * Set config for autocomplete.
  62. *
  63. * all configurations see https://github.com/devbridge/jQuery-Autocomplete
  64. *
  65. * @param array|\Closure $configs
  66. * @return $this
  67. */
  68. public function configs($configs = [])
  69. {
  70. if ($configs instanceof \Closure) {
  71. $configs = $configs->call($this->data(), $this->value());
  72. }
  73. $this->configs = array_merge($this->configs, Helper::array($configs));
  74. return $this;
  75. }
  76. public function groupBy(string $groupBy)
  77. {
  78. $this->groupBy = $groupBy;
  79. return $this;
  80. }
  81. /**
  82. * Load options from ajax results.
  83. *
  84. * @param string $url
  85. * @param string|null $valueField
  86. * @param string|null $groupField
  87. * @return $this
  88. */
  89. public function ajax(string $url, string $valueField = '', string $groupField = '')
  90. {
  91. $url = admin_url($url);
  92. return $this->addVariables(['ajax' => compact('url', 'valueField', 'groupField')]);
  93. }
  94. public function render()
  95. {
  96. $this->formatGroupOptions();
  97. $this->configs([
  98. 'groupBy' => $this->groupBy,
  99. ]);
  100. $this->addVariables([
  101. 'options' => json_encode($this->options, \JSON_UNESCAPED_UNICODE),
  102. 'configs' => JavaScript::format($this->configs),
  103. ]);
  104. return parent::render();
  105. }
  106. protected function formatGroupOptions()
  107. {
  108. foreach ($this->groups as $group) {
  109. if (! array_key_exists('options', $group) || ! array_key_exists('label', $group)) {
  110. continue;
  111. }
  112. $this->options = array_merge($this->options, $this->formatOptions($group['options'], $group['label']));
  113. }
  114. $this->groups = [];
  115. return $this;
  116. }
  117. protected function formatOptions($options, string $group = ''): array
  118. {
  119. return array_filter(array_map(function ($opt) use ($group) {
  120. if (! is_array($opt)) {
  121. $opt = ['value' => $opt, 'data' => []];
  122. }
  123. if (! array_key_exists('value', $opt)) {
  124. return null;
  125. }
  126. if ($group) {
  127. $opt['data'][$this->groupBy] = $group;
  128. }
  129. return $opt;
  130. }, Helper::array($options)));
  131. }
  132. }