dropdown-item.js 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import TComponent from '../common/component';
  2. import config from '../common/config';
  3. const { prefix } = config;
  4. const name = `${prefix}-dropdown-item`;
  5. TComponent({
  6. properties: {
  7. title: {
  8. type: String,
  9. value: '',
  10. },
  11. options: {
  12. type: Array,
  13. value: [],
  14. },
  15. selectMode: {
  16. type: String,
  17. value: 'single', // single | multi
  18. },
  19. optionsLayout: {
  20. type: String,
  21. value: 'columns', // columns | tree | slot
  22. },
  23. optionsColumns: {
  24. type: Number,
  25. optionalTypes: [String],
  26. value: 1,
  27. },
  28. value: {
  29. type: Array,
  30. optionalTypes: [String, Number],
  31. value: [],
  32. },
  33. disabled: {
  34. type: Boolean,
  35. value: false,
  36. },
  37. itemId: {
  38. type: String,
  39. value: '',
  40. },
  41. },
  42. data: {
  43. classBasePrefix: prefix,
  44. classPrefix: name,
  45. show: false,
  46. isBtnDisabled: true,
  47. bar: null,
  48. top: 0,
  49. contentClasses: '',
  50. treeColumns: 3,
  51. selected: [],
  52. treeState: {
  53. leafLevel: 0,
  54. selectList: [],
  55. select: [],
  56. },
  57. treeOptions: [],
  58. isTree: false,
  59. },
  60. relations: {
  61. './dropdown-menu': {
  62. type: 'parent',
  63. linked(target) {
  64. this._getParentBottom(target);
  65. this.setData({
  66. bar: target,
  67. });
  68. },
  69. },
  70. },
  71. attached() {
  72. const { selectMode } = this.data;
  73. const { optionsLayout } = this.data;
  74. const layoutCol = +this.data.optionsColumns;
  75. const isTree = optionsLayout === 'tree';
  76. const treeCol = isTree ? +this.data.treeColumns : 0;
  77. const contentClassesObj = {
  78. [`${prefix}-is-tree`]: isTree,
  79. [`${prefix}-is-single`]: !isTree && selectMode === 'single',
  80. [`${prefix}-is-multi`]: !isTree && selectMode === 'multi',
  81. [`${prefix}-is-col1`]: layoutCol === 1 || treeCol === 1,
  82. [`${prefix}-is-col2`]: layoutCol === 2 || treeCol === 2,
  83. [`${prefix}-is-col3`]: layoutCol === 3 || treeCol === 3,
  84. };
  85. const contentClasses = Object.keys(contentClassesObj)
  86. .filter((e) => contentClassesObj[e] === true)
  87. .join(' ');
  88. this.setData({
  89. contentClasses,
  90. isTree,
  91. selected: this.data.value,
  92. });
  93. if (isTree) {
  94. this.data.treeState.selectList = this.data.selected || [];
  95. this._buildTreeOptions();
  96. }
  97. this.updateButtonState();
  98. },
  99. methods: {
  100. _buildTreeOptions() {
  101. const { options, selectMode } = this.data;
  102. const { selectList } = this.data.treeState;
  103. const newTreeOptions = [];
  104. let level = -1;
  105. let node = { options };
  106. while (node.options) {
  107. // 当前层级节点的列表
  108. const list = node.options;
  109. newTreeOptions.push([...list]);
  110. level += 1;
  111. // 当前层级列表选中项
  112. const thisValue = selectList[level];
  113. if (thisValue === undefined) {
  114. const [firstChild] = list;
  115. if (firstChild.options) {
  116. // 还有子节点,当前层级作为单选处理
  117. this._selectTreeNode(level, firstChild.value);
  118. node = firstChild;
  119. }
  120. else {
  121. // 没有子节点,结束处理
  122. this._selectTreeNode(level, selectMode === 'multi' ? [] : undefined);
  123. break;
  124. }
  125. }
  126. else {
  127. const child = !Array.isArray(thisValue) && list.find((child) => child.value === thisValue);
  128. node = child;
  129. }
  130. }
  131. this.setData({
  132. 'treeState.leafLevel': Math.max(0, level),
  133. treeOptions: newTreeOptions,
  134. });
  135. },
  136. _closeDropdown() {
  137. this.data.bar.setData({
  138. activeIdx: -1,
  139. });
  140. this.setData({
  141. show: false,
  142. });
  143. },
  144. _getParentBottom(parent) {
  145. const query = wx.createSelectorQuery().in(parent);
  146. query
  147. .select(`#${prefix}-bar`)
  148. .boundingClientRect((res) => {
  149. this.setData({
  150. top: res.bottom,
  151. });
  152. })
  153. .exec();
  154. },
  155. _selectTreeNode(level, value) {
  156. // console.log('level:', level, 'value:', value);
  157. // 当前节点
  158. const tempValue = this.data.treeState.selectList.slice(0, level);
  159. tempValue[level] = value;
  160. this.setData({
  161. 'treeState.selectList': tempValue,
  162. });
  163. },
  164. clickOverlay() {
  165. this._closeDropdown();
  166. },
  167. updateSelected(e) {
  168. if (this.data.isTree) {
  169. this._selectTreeNode(e.target.dataset.level, this.data.selectMode === 'single' ? e.detail.name : e.detail.names);
  170. }
  171. else {
  172. const data = {
  173. selected: this.data.selectMode === 'single' ? e.detail.name : e.detail.names,
  174. };
  175. this.setData(data);
  176. if (this.data.bar && this.data.selectMode === 'single') {
  177. this.confirmSelect();
  178. }
  179. }
  180. this.updateButtonState();
  181. },
  182. updateButtonState() {
  183. var _a;
  184. if (this.data.isTree) {
  185. let isEmpty = false;
  186. if (this.data.selectMode === 'single') {
  187. isEmpty = this.data.treeState.selectList[this.data.treeState.leafLevel] === undefined;
  188. }
  189. if (this.data.selectMode === 'multi') {
  190. const selectList = this.data.treeState.selectList[this.data.treeState.leafLevel];
  191. isEmpty = selectList && selectList.length <= 0;
  192. }
  193. this.setData({
  194. isBtnDisabled: isEmpty,
  195. });
  196. }
  197. else {
  198. const isEmpty = ((_a = this.data.selected) === null || _a === void 0 ? void 0 : _a.length) === 0;
  199. this.setData({
  200. isBtnDisabled: isEmpty,
  201. });
  202. }
  203. },
  204. resetSelect() {
  205. if (this.data.isTree) {
  206. this.setData({
  207. treeState: {
  208. leafLevel: 0,
  209. selectList: [],
  210. select: [],
  211. },
  212. });
  213. this._buildTreeOptions();
  214. this.updateButtonState();
  215. }
  216. else {
  217. this.updateSelected({ detail: { names: [], name: null } });
  218. }
  219. },
  220. confirmSelect() {
  221. if (this.data.isTree) {
  222. this.triggerEvent('change', this.data.treeState.selectList);
  223. }
  224. else {
  225. this.triggerEvent('change', this.data.selected);
  226. }
  227. this._closeDropdown();
  228. },
  229. selectTreeNode(e) {
  230. this._selectTreeNode(e.target.dataset.level, e.detail.name);
  231. this._buildTreeOptions();
  232. },
  233. },
  234. });
  235. //# sourceMappingURL=dropdown-item.js.map