JsTreeCheckBox.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. <?php
  2. namespace common\widgets\jstree;
  3. use yii\helpers\Json;
  4. use yii\widgets\InputWidget;
  5. use common\widgets\jstree\assets\AppAsset;
  6. /**
  7. * Class JsTree
  8. *
  9. * ```php
  10. *
  11. * $defaultData = [
  12. * [
  13. * 'id' => 1,
  14. * 'pid' => 0,
  15. * 'title' => '测试1',
  16. * ],
  17. * [
  18. * 'id' => 2,
  19. * 'pid' => 0,
  20. * 'title' => '测试2',
  21. * ],
  22. * [
  23. * 'id' => 3,
  24. * 'pid' => 0,
  25. * 'title' => '测试3',
  26. * ],
  27. * [
  28. * 'id' => 4,
  29. * 'pid' => 1,
  30. * 'title' => '测试4',
  31. * ],
  32. * ];
  33. *
  34. * $selectIds = [1, 2];
  35. *
  36. * ```
  37. *
  38. * @package common\widgets\jstree
  39. * @author jianyan74 <751393839@qq.com>
  40. */
  41. class JsTreeCheckBox extends InputWidget
  42. {
  43. /**
  44. * ID
  45. *
  46. * @var
  47. */
  48. public $name;
  49. /**
  50. * @var string
  51. */
  52. public $theme = 'check-box';
  53. /**
  54. * 默认数据
  55. *
  56. * @var array
  57. */
  58. public $defaultData = [];
  59. /**
  60. * 选择的ID
  61. *
  62. * @var array
  63. */
  64. public $selectIds = [];
  65. /**
  66. * 过滤掉的ID
  67. *
  68. * @var array
  69. */
  70. protected $filtrationId = [];
  71. /**
  72. * @return string
  73. */
  74. public function run()
  75. {
  76. $this->registerClientScript();
  77. $defaultData = $this->defaultData;
  78. $selectIds = $this->selectIds;
  79. // 获取下级没有全部选择的ID
  80. $this->filtration(self::itemsMerge($defaultData));
  81. $filtrationIds = [];
  82. foreach ($this->filtrationId as $filtrationId) {
  83. $filtrationIds = array_merge($filtrationIds, array_column(self::getParents($defaultData, $filtrationId), 'id'));
  84. }
  85. $jsTreeData = [];
  86. foreach ($defaultData as $datum) {
  87. $jsTreeData[] = [
  88. 'id' => $datum['id'],
  89. 'parent' => !empty($datum['pid']) ? $datum['pid'] : '#',
  90. 'text' => trim($datum['title']),
  91. // 'icon' => 'none'
  92. ];
  93. }
  94. // 过滤选择的ID
  95. foreach ($selectIds as $key => $selectId) {
  96. if (in_array($selectId, $filtrationIds)) {
  97. unset($selectIds[$key]);
  98. }
  99. }
  100. return $this->render($this->theme, [
  101. 'name' => $this->name,
  102. 'selectIds' => Json::encode(array_values($selectIds)),
  103. 'defaultData' => Json::encode($jsTreeData),
  104. ]);
  105. }
  106. /**
  107. * 过滤
  108. *
  109. * @param $data
  110. */
  111. public function filtration($data)
  112. {
  113. foreach ($data as $datum) {
  114. if (!empty($datum['-'])) {
  115. $this->filtration($datum['-']);
  116. if (in_array($datum['id'], $this->selectIds)) {
  117. $ids = array_column($datum['-'], 'id');
  118. $selectChildIds = array_intersect($this->selectIds, $ids);
  119. if (count($selectChildIds) != count($ids)) {
  120. $this->filtrationId[] = $datum['id'];
  121. }
  122. }
  123. }
  124. }
  125. }
  126. /**
  127. * 传递一个子分类ID返回所有的父级分类
  128. *
  129. * @param array $items
  130. * @param $id
  131. * @return array
  132. */
  133. public static function getParents(array $items, $id)
  134. {
  135. $arr = [];
  136. foreach ($items as $v) {
  137. if (is_numeric($id)) {
  138. if ($v['id'] == $id) {
  139. $arr[] = $v;
  140. $arr = array_merge(self::getParents($items, $v['pid']), $arr);
  141. }
  142. }
  143. }
  144. return $arr;
  145. }
  146. /**
  147. * 递归
  148. *
  149. * @param array $items
  150. * @param int $pid
  151. * @param string $idField
  152. * @param string $pidField
  153. * @param string $child
  154. * @return array
  155. */
  156. protected static function itemsMerge(array $items, $pid = 0)
  157. {
  158. $arr = [];
  159. foreach ($items as $v) {
  160. if (is_numeric($pid)) {
  161. if ($v['pid'] == $pid) {
  162. $v['-'] = self::itemsMerge($items, $v['id']);
  163. $arr[] = $v;
  164. }
  165. }
  166. }
  167. return $arr;
  168. }
  169. /**
  170. * 注册资源
  171. */
  172. protected function registerClientScript()
  173. {
  174. AppAsset::register($this->getView());
  175. }
  176. }
粤ICP备19079148号