Tab.php 3.5 KB

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