Tab.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. <?php
  2. namespace Dcat\Admin\Form;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Form;
  5. use Dcat\Admin\Widgets\Form as WidgetForm;
  6. use Illuminate\Support\Collection;
  7. class Tab
  8. {
  9. /**
  10. * @var Form|WidgetForm
  11. */
  12. protected $form;
  13. /**
  14. * @var Collection
  15. */
  16. protected $tabs;
  17. /**
  18. * @var int
  19. */
  20. protected $offset = 0;
  21. /**
  22. * @var int
  23. */
  24. protected $columnOffset = 0;
  25. /**
  26. * @var bool
  27. */
  28. public $hasRows = false;
  29. /**
  30. * Tab constructor.
  31. *
  32. * @param Form|WidgetForm $form
  33. */
  34. public function __construct($form)
  35. {
  36. $this->form = $form;
  37. $this->tabs = new Collection();
  38. }
  39. /**
  40. * Append a tab section.
  41. *
  42. * @param string $title
  43. * @param \Closure $content
  44. * @param bool $active
  45. *
  46. * @return $this
  47. */
  48. public function append($title, \Closure $content, $active = false)
  49. {
  50. call_user_func($content, $this->form);
  51. $fields = $this->collectFields();
  52. $layout = $this->collectColumnLayout();
  53. $id = 'tab-form-'.($this->tabs->count() + 1).'-'.mt_rand(0, 9999);
  54. $this->tabs->push(compact('id', 'title', 'fields', 'active', 'layout'));
  55. return $this;
  56. }
  57. /**
  58. * Collect fields under current tab.
  59. *
  60. * @return Collection
  61. */
  62. protected function collectFields()
  63. {
  64. $fields = clone $this->form->fields();
  65. $all = $fields->toArray();
  66. foreach ($this->form->rows() as $row) {
  67. $rowFields = $row->fields()->map(function ($field) {
  68. return $field['element'];
  69. });
  70. $match = false;
  71. foreach ($rowFields as $field) {
  72. if (($index = array_search($field, $all)) !== false) {
  73. if (! $match) {
  74. $fields->put($index, $row);
  75. } else {
  76. $fields->pull($index);
  77. }
  78. $match = true;
  79. }
  80. }
  81. $this->hasRows = true;
  82. }
  83. $fields = $fields->slice($this->offset);
  84. $this->offset += $fields->count();
  85. return $fields;
  86. }
  87. protected function collectColumnLayout()
  88. {
  89. $layout = clone $this->form->layout();
  90. $this->form->layout()->reset();
  91. return $layout;
  92. }
  93. /**
  94. * Get all tabs.
  95. *
  96. * @return Collection
  97. */
  98. public function getTabs()
  99. {
  100. // If there is no active tab, then active the first.
  101. if ($this->tabs->filter(function ($tab) {
  102. return $tab['active'];
  103. })->isEmpty()) {
  104. $first = $this->tabs->first();
  105. $first['active'] = true;
  106. $this->tabs->offsetSet(0, $first);
  107. }
  108. return $this->tabs;
  109. }
  110. /**
  111. * @return bool
  112. */
  113. public function isEmpty()
  114. {
  115. return $this->tabs->isEmpty();
  116. }
  117. /**
  118. * @return void
  119. */
  120. public function addScript()
  121. {
  122. $elementId = $this->form->getElementId();
  123. $script = <<<JS
  124. (function () {
  125. var hash = document.location.hash;
  126. if (hash) {
  127. $('#$elementId .nav-tabs a[href="' + hash + '"]').tab('show');
  128. }
  129. // Change hash for page-reload
  130. $('#$elementId .nav-tabs a').on('shown.bs.tab', function (e) {
  131. history.pushState(null,null, e.target.hash);
  132. });
  133. if ($('#$elementId .has-error').length) {
  134. $('#$elementId .has-error').each(function () {
  135. var tabId = '#'+$(this).closest('.tab-pane').attr('id');
  136. $('li a[href="'+tabId+'"] i').removeClass('hide');
  137. });
  138. var first = $('#$elementId .has-error:first').closest('.tab-pane').attr('id');
  139. $('li a[href="#'+first+'"]').tab('show');
  140. }
  141. })();
  142. JS;
  143. Admin::script($script);
  144. }
  145. }