FixColumns.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. <?php
  2. namespace Dcat\Admin\Grid;
  3. use Dcat\Admin\Admin;
  4. use Dcat\Admin\Grid;
  5. use Illuminate\Support\Collection;
  6. class FixColumns
  7. {
  8. /**
  9. * @var Grid
  10. */
  11. protected $grid;
  12. /**
  13. * @var int
  14. */
  15. public $head;
  16. /**
  17. * @var int
  18. */
  19. public $tail;
  20. /**
  21. * @var Collection
  22. */
  23. protected $left;
  24. /**
  25. * @var Collection
  26. */
  27. protected $right;
  28. /**
  29. * @var Collection
  30. */
  31. protected $complexLeft;
  32. /**
  33. * @var Collection
  34. */
  35. protected $complexRight;
  36. /**
  37. * @var string
  38. */
  39. protected $view = 'admin::grid.fixed-table';
  40. /**
  41. * @var int
  42. */
  43. protected $height;
  44. /**
  45. * FixColumns constructor.
  46. *
  47. * @param Grid $grid
  48. * @param int $head
  49. * @param int $tail
  50. */
  51. public function __construct(Grid $grid, $head, $tail = -1)
  52. {
  53. $this->grid = $grid;
  54. $this->head = $head;
  55. $this->tail = $tail;
  56. $this->left = Collection::make();
  57. $this->right = Collection::make();
  58. $this->complexLeft = Collection::make();
  59. $this->complexRight = Collection::make();
  60. }
  61. /**
  62. * @return Collection
  63. */
  64. public function leftColumns()
  65. {
  66. return $this->left;
  67. }
  68. /**
  69. * @return Collection
  70. */
  71. public function rightColumns()
  72. {
  73. return $this->right;
  74. }
  75. /**
  76. * @return Collection
  77. */
  78. public function leftComplexColumns()
  79. {
  80. return $this->complexLeft;
  81. }
  82. /**
  83. * @return Collection
  84. */
  85. public function rightComplexColumns()
  86. {
  87. return $this->complexRight;
  88. }
  89. /**
  90. * @param int $height px
  91. *
  92. * @return $this
  93. */
  94. public function height(int $height)
  95. {
  96. $this->height = $height;
  97. return $this;
  98. }
  99. /**
  100. * @return \Closure
  101. */
  102. public function apply()
  103. {
  104. $this->grid->view($this->view);
  105. $this->grid->with(['tableHeight' => $this->height]);
  106. $complexHeaders = $this->grid->getComplexHeaders();
  107. if ($this->head > 0) {
  108. if ($complexHeaders) {
  109. $this->complexLeft = $complexHeaders->slice(0, $this->head);
  110. $this->left = $this->formatColumns($this->complexLeft);
  111. } else {
  112. $this->left = $this->grid->columns()->slice(0, $this->head);
  113. }
  114. }
  115. if ($this->tail < 0) {
  116. if ($complexHeaders) {
  117. $this->complexRight = $complexHeaders->slice($this->tail);
  118. $this->right = $this->formatColumns($this->complexRight);
  119. } else {
  120. $this->right = $this->grid->columns()->slice($this->tail);
  121. }
  122. }
  123. $this->addStyle();
  124. $this->addScript();
  125. }
  126. protected function formatColumns(Collection $complexHeaders)
  127. {
  128. return $complexHeaders
  129. ->map(function (ComplexHeader $header) {
  130. return $header->getColumnNames()->toArray();
  131. })
  132. ->flatten()
  133. ->filter()
  134. ->map(function ($name) {
  135. return $this->grid->allColumns()->get($name);
  136. });
  137. }
  138. /**
  139. * @return $this
  140. */
  141. protected function addScript()
  142. {
  143. $script = <<<'JS'
  144. (function () {
  145. var $tableMain = $('.table-main');
  146. var theadHeight = $('.table-main thead tr').outerHeight();
  147. $('.table-fixed thead tr').outerHeight(theadHeight);
  148. var tfootHeight = $('.table-main tfoot tr').outerHeight();
  149. $('.table-fixed tfoot tr').outerHeight(tfootHeight);
  150. $('.table-main tbody tr').each(function(i, obj) {
  151. var height = $(obj).outerHeight();
  152. $('.table-fixed-left tbody tr').eq(i).outerHeight(height);
  153. $('.table-fixed-right tbody tr').eq(i).outerHeight(height);
  154. });
  155. if ($tableMain.width() >= $tableMain.prop('scrollWidth') || $(window).width() < 600) {
  156. $('.table-fixed').hide();
  157. } else {
  158. var height = ($(window).height() - 215);
  159. $tableMain.each(function (k, v) {
  160. $(v).css({height: ($(v).data('height') || height) + 'px'});
  161. });
  162. $('.table-fixed-right,.table-fixed-left').each(function (k, v) {
  163. $(v).css({height: (($(v).data('height') || height) - 16) + 'px'});
  164. });
  165. $('.table-fixed-right').css({right: '12px'});
  166. $tableMain.scroll(function () {
  167. var self = $(this);
  168. self.parents('.tables-container').find('.table-fixed-right,.table-fixed-left').scrollTop(self.scrollTop());
  169. });
  170. }
  171. $('.table-wrap tbody tr').on('mouseover', function () {
  172. var index = $(this).index();
  173. $('.table-main tbody tr').eq(index).addClass('active');
  174. $('.table-fixed-left tbody tr').eq(index).addClass('active');
  175. $('.table-fixed-right tbody tr').eq(index).addClass('active');
  176. });
  177. $('.table-wrap tbody tr').on('mouseout', function () {
  178. var index = $(this).index();
  179. $('.table-main tbody tr').eq(index).removeClass('active');
  180. $('.table-fixed-left tbody tr').eq(index).removeClass('active');
  181. $('.table-fixed-right tbody tr').eq(index).removeClass('active');
  182. });
  183. })();
  184. JS;
  185. Admin::script($script, true);
  186. return $this;
  187. }
  188. /**
  189. * @return $this
  190. */
  191. protected function addStyle()
  192. {
  193. $style = <<<'CSS'
  194. .tables-container {
  195. position:relative;
  196. margin-top: 12px;
  197. }
  198. .tables-container table {
  199. margin-bottom: 0 !important;
  200. }
  201. .tables-container table th, .tables-container table td {
  202. white-space:nowrap;
  203. }
  204. .table-wrap table tr .active {
  205. background: #f5f5f5;
  206. }
  207. .table-main {
  208. overflow: auto;
  209. width: 100%;
  210. }
  211. .table-fixed {
  212. position:absolute;
  213. top: 0;
  214. z-index:10;
  215. overflow: hidden;
  216. }
  217. .table-fixed th {
  218. background: #eff3f8;
  219. }
  220. .table-fixed-left {
  221. left:0;
  222. }
  223. .table-fixed-right {
  224. right:0;
  225. }
  226. .table-fixed-left {
  227. box-shadow: 5px 0 5px -5px rgba(0,0,0,.1);
  228. }
  229. .table-fixed-right {
  230. box-shadow: -5px 0 5px -5px rgba(0,0,0,.1);
  231. }
  232. .tables-container .table.table-bordered.dataTable.complex-headers {
  233. margin-top: 0!important;
  234. }
  235. CSS;
  236. Admin::style($style);
  237. return $this;
  238. }
  239. }