@iamproperty/components 7.1.0--beta7 → 7.2.1--beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (382) hide show
  1. package/assets/css/components/actionbar.component.css +1 -0
  2. package/assets/css/components/actionbar.component.css.map +1 -0
  3. package/assets/css/components/actionbar.global.css +1 -1
  4. package/assets/css/components/actionbar.global.css.map +1 -1
  5. package/assets/css/components/address-lookup.css +1 -1
  6. package/assets/css/components/address-lookup.css.map +1 -1
  7. package/assets/css/components/barchart.component.css +1 -1
  8. package/assets/css/components/barchart.component.css.map +1 -1
  9. package/assets/css/components/bento-grid.component.css +1 -0
  10. package/assets/css/components/bento-grid.component.css.map +1 -0
  11. package/assets/css/components/card.component.css +1 -1
  12. package/assets/css/components/card.component.css.map +1 -1
  13. package/assets/css/components/carousel.component.css +1 -1
  14. package/assets/css/components/carousel.component.css.map +1 -1
  15. package/assets/css/components/carousel.config.css +1 -1
  16. package/assets/css/components/carousel.config.css.map +1 -1
  17. package/assets/css/components/charts.config.css +1 -1
  18. package/assets/css/components/charts.config.css.map +1 -1
  19. package/assets/css/components/charts.css +1 -1
  20. package/assets/css/components/charts.css.map +1 -1
  21. package/assets/css/components/charts.module.css +1 -1
  22. package/assets/css/components/charts.module.css.map +1 -1
  23. package/assets/css/components/collapsible-side.css +1 -1
  24. package/assets/css/components/collapsible-side.css.map +1 -1
  25. package/assets/css/components/doughnutchart.component.css +1 -0
  26. package/assets/css/components/doughnutchart.component.css.map +1 -0
  27. package/assets/css/components/fileupload.css.map +1 -1
  28. package/assets/css/components/header.css.map +1 -1
  29. package/assets/css/components/inline-edit.preload.css +1 -1
  30. package/assets/css/components/inline-edit.preload.css.map +1 -1
  31. package/assets/css/components/marketing.css.map +1 -1
  32. package/assets/css/components/menu.component.css +1 -0
  33. package/assets/css/components/menu.component.css.map +1 -0
  34. package/assets/css/components/menu.css +1 -0
  35. package/assets/css/components/menu.css.map +1 -0
  36. package/assets/css/components/multi-step.component.css.map +1 -1
  37. package/assets/css/components/multiselect.preload.css +1 -1
  38. package/assets/css/components/multiselect.preload.css.map +1 -1
  39. package/assets/css/components/nav.component.css +1 -0
  40. package/assets/css/components/nav.component.css.map +1 -0
  41. package/assets/css/components/nav.docs.css.map +1 -1
  42. package/assets/css/components/nav.global.css.map +1 -1
  43. package/assets/css/components/nav.old.css +1 -1
  44. package/assets/css/components/nav.old.css.map +1 -1
  45. package/assets/css/components/nav.preload.css +1 -1
  46. package/assets/css/components/nav.preload.css.map +1 -1
  47. package/assets/css/components/notification.css +1 -1
  48. package/assets/css/components/notification.css.map +1 -1
  49. package/assets/css/components/pagination.css +1 -1
  50. package/assets/css/components/pagination.css.map +1 -1
  51. package/assets/css/components/property-searchbar.css.map +1 -1
  52. package/assets/css/components/slider.css +1 -1
  53. package/assets/css/components/slider.css.map +1 -1
  54. package/assets/css/components/snapshot.css.map +1 -1
  55. package/assets/css/components/stepper.css.map +1 -1
  56. package/assets/css/components/table-basic.component.css +1 -0
  57. package/assets/css/components/table-basic.component.css.map +1 -0
  58. package/assets/css/components/table-basic.global.css +1 -0
  59. package/assets/css/components/table-basic.global.css.map +1 -0
  60. package/assets/css/components/table.component.css +1 -0
  61. package/assets/css/components/table.component.css.map +1 -0
  62. package/assets/css/components/table.global.css +1 -1
  63. package/assets/css/components/table.global.css.map +1 -1
  64. package/assets/css/components/tabs.component.css +1 -0
  65. package/assets/css/components/tabs.component.css.map +1 -0
  66. package/assets/css/components/tabs.config.css +1 -0
  67. package/assets/css/components/tabs.config.css.map +1 -0
  68. package/assets/css/components/tabs.css +1 -1
  69. package/assets/css/components/tabs.css.map +1 -1
  70. package/assets/css/components/testimonial.css.map +1 -1
  71. package/assets/css/components/timeline.css.map +1 -1
  72. package/assets/css/core.min.css +1 -1
  73. package/assets/css/core.min.css.map +1 -1
  74. package/assets/css/mobile-core.min.css +1 -0
  75. package/assets/css/mobile-core.min.css.map +1 -0
  76. package/assets/css/mobile.min.css +1 -0
  77. package/assets/css/mobile.min.css.map +1 -0
  78. package/assets/css/style.min.css +1 -1
  79. package/assets/css/style.min.css.map +1 -1
  80. package/assets/js/components/_global.js +0 -1
  81. package/assets/js/components/accordion/accordion.component.min.js +1 -1
  82. package/assets/js/components/accordion/accordion.component.min.js.map +1 -1
  83. package/assets/js/components/actionbar/actionbar.component.js +86 -8
  84. package/assets/js/components/actionbar/actionbar.component.min.js +19 -6
  85. package/assets/js/components/actionbar/actionbar.component.min.js.map +1 -1
  86. package/assets/js/components/address-lookup/address-lookup.component.js +17 -18
  87. package/assets/js/components/address-lookup/address-lookup.component.min.js +5 -5
  88. package/assets/js/components/address-lookup/address-lookup.component.min.js.map +1 -1
  89. package/assets/js/components/applied-filters/applied-filters.component.js +0 -1
  90. package/assets/js/components/applied-filters/applied-filters.component.min.js +4 -4
  91. package/assets/js/components/applied-filters/applied-filters.component.min.js.map +1 -1
  92. package/assets/js/components/barchart/barchart.component.js +2 -3
  93. package/assets/js/components/barchart/barchart.component.min.js +8 -4
  94. package/assets/js/components/barchart/barchart.component.min.js.map +1 -1
  95. package/assets/js/components/bento-grid/bento-grid.component.js +50 -0
  96. package/assets/js/components/bento-grid/bento-grid.component.min.js +15 -0
  97. package/assets/js/components/bento-grid/bento-grid.component.min.js.map +1 -0
  98. package/assets/js/components/card/card.component.js +10 -13
  99. package/assets/js/components/card/card.component.min.js +7 -7
  100. package/assets/js/components/card/card.component.min.js.map +1 -1
  101. package/assets/js/components/carousel/carousel.component.js +4 -5
  102. package/assets/js/components/carousel/carousel.component.min.js +4 -4
  103. package/assets/js/components/carousel/carousel.component.min.js.map +1 -1
  104. package/assets/js/components/chart/chart.component.js +1 -5
  105. package/assets/js/components/collapsible-side/collapsible-side.component.js +4 -5
  106. package/assets/js/components/collapsible-side/collapsible-side.component.min.js +4 -4
  107. package/assets/js/components/collapsible-side/collapsible-side.component.min.js.map +1 -1
  108. package/assets/js/components/doughnutchart/doughnutchart.component.js +70 -0
  109. package/assets/js/components/doughnutchart/doughnutchart.component.min.js +25 -0
  110. package/assets/js/components/doughnutchart/doughnutchart.component.min.js.map +1 -0
  111. package/assets/js/components/fileupload/fileupload.component.js +2 -3
  112. package/assets/js/components/fileupload/fileupload.component.min.js +6 -6
  113. package/assets/js/components/fileupload/fileupload.component.min.js.map +1 -1
  114. package/assets/js/components/filter-card/filter-card.component.js +3 -4
  115. package/assets/js/components/filter-card/filter-card.component.min.js +4 -4
  116. package/assets/js/components/filter-card/filter-card.component.min.js.map +1 -1
  117. package/assets/js/components/filterlist/filterlist.component.js +0 -1
  118. package/assets/js/components/filterlist/filterlist.component.min.js +3 -3
  119. package/assets/js/components/filterlist/filterlist.component.min.js.map +1 -1
  120. package/assets/js/components/header/header.component.js +0 -1
  121. package/assets/js/components/header/header.component.min.js +1 -1
  122. package/assets/js/components/header/header.component.min.js.map +1 -1
  123. package/assets/js/components/inline-edit/inline-edit.component.js +7 -8
  124. package/assets/js/components/inline-edit/inline-edit.component.min.js +4 -4
  125. package/assets/js/components/inline-edit/inline-edit.component.min.js.map +1 -1
  126. package/assets/js/components/marketing/marketing.component.js +0 -1
  127. package/assets/js/components/marketing/marketing.component.min.js +1 -1
  128. package/assets/js/components/marketing/marketing.component.min.js.map +1 -1
  129. package/assets/js/components/menu/menu.component.js +200 -0
  130. package/assets/js/components/menu/menu.component.min.js +77 -0
  131. package/assets/js/components/menu/menu.component.min.js.map +1 -0
  132. package/assets/js/components/multi-step/multi-step.component.js +10 -10
  133. package/assets/js/components/multi-step/multi-step.component.min.js +13 -0
  134. package/assets/js/components/multi-step/multi-step.component.min.js.map +1 -0
  135. package/assets/js/components/multiselect/multiselect.component.js +10 -10
  136. package/assets/js/components/multiselect/multiselect.component.min.js +3 -3
  137. package/assets/js/components/multiselect/multiselect.component.min.js.map +1 -1
  138. package/assets/js/components/nav/nav.component.js +7 -7
  139. package/assets/js/components/nav/nav.component.min.js +7 -7
  140. package/assets/js/components/nav/nav.component.min.js.map +1 -1
  141. package/assets/js/components/notification/notification.component.js +3 -3
  142. package/assets/js/components/notification/notification.component.min.js +4 -4
  143. package/assets/js/components/notification/notification.component.min.js.map +1 -1
  144. package/assets/js/components/pagination/pagination.component.js +14 -8
  145. package/assets/js/components/pagination/pagination.component.min.js +5 -5
  146. package/assets/js/components/pagination/pagination.component.min.js.map +1 -1
  147. package/assets/js/components/record-card/record-card.component.js +6 -8
  148. package/assets/js/components/record-card/record-card.component.min.js +4 -4
  149. package/assets/js/components/record-card/record-card.component.min.js.map +1 -1
  150. package/assets/js/components/search/search.component.js +9 -6
  151. package/assets/js/components/search/search.component.min.js +8 -5
  152. package/assets/js/components/search/search.component.min.js.map +1 -1
  153. package/assets/js/components/slider/slider.component.js +8 -8
  154. package/assets/js/components/slider/slider.component.min.js +5 -5
  155. package/assets/js/components/slider/slider.component.min.js.map +1 -1
  156. package/assets/js/components/table/table.component.js +36 -200
  157. package/assets/js/components/table/table.component.min.js +13 -23
  158. package/assets/js/components/table/table.component.min.js.map +1 -1
  159. package/assets/js/components/table-ajax/table-ajax.component.js +46 -0
  160. package/assets/js/components/table-ajax/table-ajax.component.min.js +22 -0
  161. package/assets/js/components/table-ajax/table-ajax.component.min.js.map +1 -0
  162. package/assets/js/components/table-basic/table-basic.component.js +46 -0
  163. package/assets/js/components/table-basic/table-basic.component.min.js +22 -0
  164. package/assets/js/components/table-basic/table-basic.component.min.js.map +1 -0
  165. package/assets/js/components/table-no-submit/table-no-submit.component.js +77 -0
  166. package/assets/js/components/table-no-submit/table-no-submit.component.min.js +22 -0
  167. package/assets/js/components/table-no-submit/table-no-submit.component.min.js.map +1 -0
  168. package/assets/js/components/table-submit/table-submit.component.js +55 -0
  169. package/assets/js/components/table-submit/table-submit.component.min.js +22 -0
  170. package/assets/js/components/table-submit/table-submit.component.min.js.map +1 -0
  171. package/assets/js/components/tabs/tabs.component.js +3 -2
  172. package/assets/js/components/tabs/tabs.component.min.js +6 -4
  173. package/assets/js/components/tabs/tabs.component.min.js.map +1 -1
  174. package/assets/js/components/video-card/video-card.component.js +4 -3
  175. package/assets/js/components/video-card/video-card.component.min.js +3 -3
  176. package/assets/js/components/video-card/video-card.component.min.js.map +1 -1
  177. package/assets/js/modules/applied-filters.js +8 -9
  178. package/assets/js/modules/carousel.js +9 -10
  179. package/assets/js/modules/chart.js +5 -3
  180. package/assets/js/modules/chart.module.js +108 -1
  181. package/assets/js/modules/dialogs.js +6 -7
  182. package/assets/js/modules/drawer.js +1 -2
  183. package/assets/js/modules/dynamicEvents.js +7 -8
  184. package/assets/js/modules/fileupload.js +7 -7
  185. package/assets/js/modules/filterlist.js +3 -4
  186. package/assets/js/modules/form.js +12 -13
  187. package/assets/js/modules/helpers.js +7 -5
  188. package/assets/js/modules/inputs.js +6 -9
  189. package/assets/js/modules/nav.js +3 -4
  190. package/assets/js/modules/notification.js +2 -3
  191. package/assets/js/modules/orderablelist.js +0 -1
  192. package/assets/js/modules/table.js +604 -317
  193. package/assets/js/modules/tabs.js +46 -19
  194. package/assets/js/scripts.bundle.js +3 -3
  195. package/assets/js/scripts.bundle.js.map +1 -1
  196. package/assets/js/scripts.bundle.min.js +2 -2
  197. package/assets/js/scripts.bundle.min.js.map +1 -1
  198. package/assets/js/scripts.js +71 -6
  199. package/assets/js/tests/card.spec.js +14 -0
  200. package/assets/js/tests/carousel.spec.js +60 -0
  201. package/assets/js/tests/chart.spec.js +7 -5
  202. package/assets/js/tests/fileupload.spec.js +22 -0
  203. package/assets/js/tests/multistep.spec.js +68 -0
  204. package/assets/js/tests/table.spec.js +0 -31
  205. package/assets/sass/_bs_grid.scss +4 -1
  206. package/assets/sass/_components.scss +326 -100
  207. package/assets/sass/_corefiles.scss +42 -18
  208. package/assets/sass/_elements.scss +98 -18
  209. package/assets/sass/_example.scss +61 -0
  210. package/assets/sass/_func.scss +5 -13
  211. package/assets/sass/_functions/bs_utilities.scss +43 -39
  212. package/assets/sass/_functions/functions.scss +66 -52
  213. package/assets/sass/_functions/mixins.scss +84 -100
  214. package/assets/sass/_functions/utility-mixins.scss +56 -44
  215. package/assets/sass/_functions/variables.scss +90 -1659
  216. package/assets/sass/_functions/variables_old.scss +1701 -0
  217. package/assets/sass/_grid.scss +19 -5
  218. package/assets/sass/_tests/func.spec.scss +1 -37
  219. package/assets/sass/_tests/mixins.spec.scss +1 -77
  220. package/assets/sass/_tests/typography.spec.scss +1 -1
  221. package/assets/sass/_utilities.scss +15 -5
  222. package/assets/sass/_utility-mixins.scss +6 -1
  223. package/assets/sass/components/{actionbar.scss → actionbar.component.scss} +83 -16
  224. package/assets/sass/components/actionbar.global.scss +12 -68
  225. package/assets/sass/components/address-lookup.scss +6 -0
  226. package/assets/sass/components/barchart.component.scss +7 -20
  227. package/assets/sass/components/bento-grid.component.scss +91 -0
  228. package/assets/sass/components/carousel.config.scss +64 -58
  229. package/assets/sass/components/charts.config.scss +73 -67
  230. package/assets/sass/components/charts.module.scss +128 -97
  231. package/assets/sass/components/charts.scss +43 -42
  232. package/assets/sass/components/collapsible-side.scss +29 -27
  233. package/assets/sass/components/doughnutchart.component.scss +205 -0
  234. package/assets/sass/components/fileupload.scss +4 -3
  235. package/assets/sass/components/header.scss +5 -5
  236. package/assets/sass/components/inline-edit.preload.scss +108 -102
  237. package/assets/sass/components/menu.component.scss +101 -0
  238. package/assets/sass/components/menu.scss +21 -0
  239. package/assets/sass/components/multi-step.component.scss +5 -3
  240. package/assets/sass/components/multiselect.preload.scss +36 -30
  241. package/assets/sass/components/{nav.scss → nav.component.scss} +41 -21
  242. package/assets/sass/components/nav.docs.scss +1 -1
  243. package/assets/sass/components/nav.global.scss +13 -11
  244. package/assets/sass/components/nav.old.scss +21 -24
  245. package/assets/sass/components/nav.preload.scss +40 -34
  246. package/assets/sass/components/notification.scss +9 -5
  247. package/assets/sass/components/pagination.scss +7 -0
  248. package/assets/sass/components/property-searchbar.scss +7 -7
  249. package/assets/sass/components/slider.scss +2 -0
  250. package/assets/sass/components/snapshot.scss +2 -2
  251. package/assets/sass/components/stepper.scss +7 -7
  252. package/assets/sass/components/{table.scss → table-basic.component.scss} +25 -68
  253. package/assets/sass/components/table-basic.global.scss +355 -0
  254. package/assets/sass/components/table.component.scss +40 -0
  255. package/assets/sass/components/table.global.scss +215 -418
  256. package/assets/sass/components/tabs.component.scss +5 -0
  257. package/assets/sass/components/tabs.config.scss +27 -0
  258. package/assets/sass/components/tabs.scss +40 -4
  259. package/assets/sass/components/testimonial.scss +7 -7
  260. package/assets/sass/components/timeline.scss +1 -1
  261. package/assets/sass/core.scss +13 -4
  262. package/assets/sass/elements/admin-panel.scss +199 -185
  263. package/assets/sass/elements/badge-tag.scss +87 -81
  264. package/assets/sass/elements/brand.scss +67 -61
  265. package/assets/sass/elements/buttons--action.scss +55 -0
  266. package/assets/sass/elements/buttons--compact.scss +135 -0
  267. package/assets/sass/elements/buttons--global.scss +323 -0
  268. package/assets/sass/elements/buttons--secondary.scss +24 -0
  269. package/assets/sass/elements/buttons--tertiary.scss +57 -0
  270. package/assets/sass/elements/buttons.scss +29 -503
  271. package/assets/sass/elements/container.scss +157 -151
  272. package/assets/sass/elements/details.scss +147 -138
  273. package/assets/sass/elements/dialog.scss +36 -30
  274. package/assets/sass/elements/forms.scss +1061 -1047
  275. package/assets/sass/elements/icons.scss +23 -17
  276. package/assets/sass/elements/links.scss +131 -116
  277. package/assets/sass/elements/lists.scss +270 -264
  278. package/assets/sass/elements/media.scss +19 -13
  279. package/assets/sass/elements/modal.scss +336 -330
  280. package/assets/sass/elements/popover.scss +163 -152
  281. package/assets/sass/elements/progress.scss +173 -162
  282. package/assets/sass/elements/table.element.scss +116 -108
  283. package/assets/sass/elements/tooltips.scss +87 -80
  284. package/assets/sass/elements/type.scss +172 -160
  285. package/assets/sass/email.scss +0 -1
  286. package/assets/sass/error.scss +15 -13
  287. package/assets/sass/foundations/reboot.scss +176 -170
  288. package/assets/sass/foundations/root.scss +136 -125
  289. package/assets/sass/helpers/max-height.scss +2 -2
  290. package/assets/sass/main.scss +14 -6
  291. package/assets/sass/mobile-core.scss +14 -0
  292. package/assets/sass/mobile.scss +16 -0
  293. package/assets/sass/templates/auth.scss +88 -83
  294. package/assets/sass/templates/form.scss +68 -59
  295. package/assets/ts/components/_global.ts +2 -3
  296. package/assets/ts/components/actionbar/actionbar.component.ts +94 -2
  297. package/assets/ts/components/address-lookup/address-lookup.component.ts +21 -22
  298. package/assets/ts/components/applied-filters/applied-filters.component.ts +1 -2
  299. package/assets/ts/components/barchart/barchart.component.ts +3 -5
  300. package/assets/ts/components/bento-grid/README.md +31 -0
  301. package/assets/ts/components/bento-grid/bento-grid.component.ts +67 -0
  302. package/assets/ts/components/card/card.component.ts +13 -16
  303. package/assets/ts/components/carousel/carousel.component.ts +5 -7
  304. package/assets/ts/components/chart/chart.component.ts +4 -9
  305. package/assets/ts/components/collapsible-side/collapsible-side.component.ts +5 -6
  306. package/assets/ts/components/doughnutchart/doughnutchart.component.ts +85 -0
  307. package/assets/ts/components/fileupload/fileupload.component.ts +5 -6
  308. package/assets/ts/components/filter-card/filter-card.component.ts +4 -5
  309. package/assets/ts/components/filterlist/filterlist.component.ts +1 -2
  310. package/assets/ts/components/header/header.component.ts +1 -3
  311. package/assets/ts/components/inline-edit/inline-edit.component.ts +8 -11
  312. package/assets/ts/components/marketing/marketing.component.ts +1 -3
  313. package/assets/ts/components/menu/menu.component.ts +222 -0
  314. package/assets/ts/components/multi-step/multi-step.component.ts +19 -23
  315. package/assets/ts/components/multiselect/multiselect.component.ts +13 -14
  316. package/assets/ts/components/nav/nav.component.ts +8 -9
  317. package/assets/ts/components/notification/notification.component.ts +3 -3
  318. package/assets/ts/components/pagination/pagination.component.ts +24 -12
  319. package/assets/ts/components/record-card/record-card.component.ts +9 -11
  320. package/assets/ts/components/search/search.component.ts +12 -9
  321. package/assets/ts/components/slider/slider.component.ts +9 -10
  322. package/assets/ts/components/table/table.component.ts +50 -247
  323. package/assets/ts/components/table-ajax/table-ajax.component.ts +64 -0
  324. package/assets/ts/components/table-basic/README.md +40 -0
  325. package/assets/ts/components/table-basic/table-basic.component.ts +56 -0
  326. package/assets/ts/components/table-no-submit/table-no-submit.component.ts +134 -0
  327. package/assets/ts/components/table-submit/table-submit.component.ts +64 -0
  328. package/assets/ts/components/tabs/tabs.component.ts +4 -3
  329. package/assets/ts/components/video-card/video-card.component.ts +13 -12
  330. package/assets/ts/modules/applied-filters.ts +10 -11
  331. package/assets/ts/modules/card.module.ts +1 -1
  332. package/assets/ts/modules/carousel.ts +13 -15
  333. package/assets/ts/modules/chart.module.ts +152 -19
  334. package/assets/ts/modules/chart.ts +26 -24
  335. package/assets/ts/modules/dialogs.ts +10 -13
  336. package/assets/ts/modules/drawer.ts +1 -2
  337. package/assets/ts/modules/dynamicEvents.ts +12 -14
  338. package/assets/ts/modules/fileupload.ts +10 -10
  339. package/assets/ts/modules/filterlist.ts +6 -7
  340. package/assets/ts/modules/form.ts +16 -17
  341. package/assets/ts/modules/helpers.ts +24 -21
  342. package/assets/ts/modules/inputs.ts +15 -18
  343. package/assets/ts/modules/nav.ts +4 -5
  344. package/assets/ts/modules/notification.ts +7 -8
  345. package/assets/ts/modules/orderablelist.ts +3 -4
  346. package/assets/ts/modules/pagination.ts +1 -1
  347. package/assets/ts/modules/table.ts +726 -356
  348. package/assets/ts/modules/tabs.ts +59 -20
  349. package/assets/ts/scripts.ts +72 -6
  350. package/assets/ts/tests/card.spec.ts +19 -0
  351. package/assets/ts/tests/carousel.spec.ts +66 -0
  352. package/assets/ts/tests/chart.spec.ts +9 -6
  353. package/assets/ts/tests/fileupload.spec.ts +30 -0
  354. package/assets/ts/tests/multistep.spec.ts +78 -0
  355. package/assets/ts/tests/table.spec.ts +0 -38
  356. package/dist/components.es.js +1260 -1063
  357. package/dist/components.umd.js +468 -198
  358. package/package.json +44 -49
  359. package/src/components/BentoGrid/BentoGrid.vue +20 -0
  360. package/src/components/DoughnutChart/DoughnutChart.vue +23 -0
  361. package/src/components/FileUpload/FileUpload.vue +4 -1
  362. package/src/components/Menu/Menu.vue +22 -0
  363. package/src/components/Table/TableAjax.vue +34 -0
  364. package/src/components/Table/TableBasic.vue +34 -0
  365. package/src/components/Table/TableNoSubmit.vue +34 -0
  366. package/src/components/Table/TableSubmit.vue +34 -0
  367. package/src/components/Tabs/Tabs.vue +0 -4
  368. package/src/index.js +25 -19
  369. package/assets/css/components/actionbar.css +0 -1
  370. package/assets/css/components/actionbar.css.map +0 -1
  371. package/assets/css/components/nav.css +0 -1
  372. package/assets/css/components/nav.css.map +0 -1
  373. package/assets/css/components/table.css +0 -1
  374. package/assets/css/components/table.css.map +0 -1
  375. package/assets/js/components.bundle.js +0 -5
  376. package/assets/js/components.bundle.js.map +0 -1
  377. package/assets/js/components.js +0 -57
  378. package/assets/js/modules/file-upload.js +0 -32
  379. package/assets/ts/components.ts +0 -62
  380. package/assets/ts/modules/file-upload.ts +0 -52
  381. package/dist/style.css +0 -1
  382. package/src/components/Table/Table.spec.js +0 -47
@@ -1,12 +1,215 @@
1
- // @ts-nocheck
2
- import { zeroPad, isNumeric, ucfirst, resolvePath } from './helpers';
1
+ import { zeroPad, isNumeric, ucfirst, resolvePath, uniqueID } from './helpers';
3
2
 
4
- // Basic functionality needed
5
- export const addDataAttributes = (table) => {
3
+ // #region Helpers
4
+ export const formatCell = (format, cellOutput): any => {
5
+ switch (format) {
6
+ case 'datetime':
7
+ return (
8
+ new Date(cellOutput).toLocaleDateString('en-gb', {
9
+ weekday: 'short',
10
+ year: '2-digit',
11
+ month: 'long',
12
+ day: 'numeric',
13
+ }) +
14
+ ' ' +
15
+ new Date(cellOutput).toLocaleTimeString('en-gb', { hour: '2-digit', minute: '2-digit' })
16
+ );
17
+ case 'date':
18
+ return new Date(cellOutput).toLocaleDateString('en-gb', {
19
+ day: 'numeric',
20
+ month: 'long',
21
+ year: '2-digit',
22
+ });
23
+ case 'capitalise':
24
+ return (cellOutput = ucfirst(cellOutput));
25
+ }
26
+ };
27
+
28
+ const filterFilters = function (form): object {
29
+ const filters = new Object();
30
+
31
+ // Filter
32
+ const filterInputs = Array.from(form.querySelectorAll('[data-filter]'));
33
+
34
+ filterInputs.forEach((filterInput) => {
35
+ // Ignore uncked radio inputs
36
+ if (filterInput.type == 'radio' && !filterInput.checked) {
37
+ return;
38
+ }
39
+
40
+ if (filterInput.type == 'checkbox' && !filterInput.checked) {
41
+ return;
42
+ }
43
+
44
+ if (filterInput && filterInput.value) {
45
+ const dataFilter = filterInput.getAttribute('data-filter');
46
+ let filterValue = filterInput.value;
47
+
48
+ if (filterInput.hasAttribute('data-date-from')) filterValue += '-date-from';
49
+
50
+ if (filterInput.hasAttribute('data-date-to')) filterValue += '-date-to';
51
+
52
+ if (!filters[dataFilter]) filters[dataFilter] = [];
53
+
54
+ filters[dataFilter].push(filterValue);
55
+ }
56
+ });
57
+
58
+ return filters;
59
+ };
60
+
61
+ export const moveAttributesToComponents = (component): void => {
62
+ let form = document.createElement('form');
63
+
64
+ if (component.hasAttribute('data-filterby')) {
65
+ form = document.querySelector(`#${component.getAttribute('data-filterby')}`);
66
+ } else if (component.closest('form')) {
67
+ form = component.closest('form');
68
+ } else {
69
+ table.parentNode.insertBefore(form, table.nextSibling);
70
+ }
71
+
72
+ if (form.hasAttribute('data-ajax')) component.setAttribute('data-ajax', form.getAttribute('data-ajax'));
73
+
74
+ if (form.hasAttribute('data-schema')) component.setAttribute('data-schema', form.getAttribute('data-schema'));
75
+ };
76
+
77
+ export const paginateTable = (component, table, form, pagination, callback): void => {
78
+ if (!form.querySelector('[name=show]'))
79
+ form.insertAdjacentHTML(
80
+ 'beforeend',
81
+ `<input name="show" type="hidden" value="${component.getAttribute('data-show')}" />`
82
+ );
83
+
84
+ if (!form.querySelector('[name=page]'))
85
+ form.insertAdjacentHTML(
86
+ 'beforeend',
87
+ `<input name="page" type="hidden" value="${component.getAttribute('data-page')}" />`
88
+ );
89
+
90
+ pagination.addEventListener('update-show', (event) => {
91
+ if (form.querySelector('[name=show]').value != event.detail.show) {
92
+ form.querySelector('[name=show]').value = event.detail.show;
93
+
94
+ const updateEvent = new CustomEvent('update-show', { detail: { show: event.detail.show } });
95
+ component.dispatchEvent(updateEvent);
96
+
97
+ updateAttributes(component, pagination);
98
+
99
+ callback();
100
+ }
101
+ });
102
+
103
+ pagination.addEventListener('update-page', (event) => {
104
+ if (form.querySelector('[name=page]').value != event.detail.page) {
105
+ form.querySelector('[name=page]').value = event.detail.page;
106
+
107
+ const updateEvent = new CustomEvent('update-page', { detail: { page: event.detail.page } });
108
+ component.dispatchEvent(updateEvent);
109
+
110
+ updateAttributes(component, pagination);
111
+
112
+ callback();
113
+
114
+ // scroll back to the top of the table
115
+ if (!component.hasAttribute('data-no-scroll')) {
116
+ const yOffset = -250;
117
+ const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
118
+ window.scrollTo({ top: y, behavior: 'smooth' });
119
+ }
120
+ }
121
+ });
122
+ };
123
+
124
+ export const findForm = (component, table): HTMLElement => {
125
+ let form = document.createElement('form');
126
+
127
+ if (component.hasAttribute('data-filterby')) {
128
+ form = document.querySelector(`#${component.getAttribute('data-filterby')}`);
129
+ } else if (component.closest('form')) {
130
+ form = component.closest('form');
131
+ } else {
132
+ table.parentNode.insertBefore(form, table.nextSibling);
133
+ }
134
+
135
+ return form;
136
+ };
137
+ // #endregion
138
+
139
+ export const setupBasicTable = (component, table, form, pagination): void => {
140
+ const tableWrapper = component.shadowRoot.querySelector('.table__wrapper');
141
+
142
+ if (!component.hasAttribute('data-total'))
143
+ component.setAttribute('data-total', component.querySelectorAll('tbody tr').length);
144
+ if (!component.hasAttribute('data-page')) component.setAttribute('data-page', 1);
145
+ if (!component.hasAttribute('data-show')) component.setAttribute('data-show', 5);
146
+ if (!component.hasAttribute('data-increment'))
147
+ component.setAttribute('data-increment', component.getAttribute('data-show'));
148
+
149
+ transferAttributes(component, pagination);
150
+
151
+ addDataAttributes(table);
152
+ createMobileButton(component, table);
153
+
154
+ // Max height
155
+ if (component.classList.contains('mh-sm')) tableWrapper.classList.add('mh-sm');
156
+ if (component.classList.contains('mh-md')) tableWrapper.classList.add('mh-md');
157
+ if (component.classList.contains('mh-lg')) tableWrapper.classList.add('mh-lg');
158
+
159
+ if (component.classList.contains('table--cta')) {
160
+ getLargestLastColWidth(component, table);
161
+ getRowHeight(component, table);
162
+ }
163
+ };
164
+
165
+ // #region Basic table fnctions
166
+ export const transferAttributes = (component, pagination): void => {
167
+ if (component.hasAttribute('data-total')) pagination.setAttribute('data-total', component.getAttribute('data-total'));
168
+ if (component.hasAttribute('data-page')) pagination.setAttribute('data-page', component.getAttribute('data-page'));
169
+ if (component.hasAttribute('data-show')) pagination.setAttribute('data-show', component.getAttribute('data-show'));
170
+ if (component.hasAttribute('data-increment'))
171
+ pagination.setAttribute('data-increment', component.getAttribute('data-show'));
172
+
173
+ if (component.hasAttribute('data-page-jump')) pagination.setAttribute('data-page-jump', 'true');
174
+ if (component.hasAttribute('data-per-page')) pagination.setAttribute('data-per-page', 'true');
175
+ if (component.hasAttribute('data-item-count')) pagination.setAttribute('data-item-count', 'true');
176
+ if (component.hasAttribute('data-loading')) pagination.setAttribute('data-loading', 'true');
177
+
178
+ if (component.classList.contains('table--fullwidth')) pagination.setAttribute('data-minimal', 'true');
179
+ };
180
+
181
+ export const updateAttributes = (component, pagination): void => {
182
+ component.setAttribute('data-total', pagination.getAttribute('data-total'));
183
+ component.setAttribute('data-page', pagination.getAttribute('data-page'));
184
+ component.setAttribute('data-show', pagination.getAttribute('data-show'));
185
+ component.setAttribute('data-increment', pagination.getAttribute('data-show'));
186
+ };
187
+
188
+ export const paginateRows = (component): void => {
189
+ const total = component.getAttribute('data-total');
190
+ const page = component.getAttribute('data-page');
191
+ const show = component.getAttribute('data-show');
192
+ const increment = component.getAttribute('data-increment');
193
+
194
+ const table = component.querySelector('table');
195
+
196
+ const end = page * show;
197
+ const start = end - show;
198
+
199
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
200
+ if (index >= start && index < end) {
201
+ row.classList.add('show');
202
+ } else {
203
+ row.classList.remove('show');
204
+ }
205
+ });
206
+ };
207
+
208
+ export const addDataAttributes = (table): void => {
6
209
  const colHeadings = Array.from(table.querySelectorAll('thead th'));
7
210
  const colRows = Array.from(table.querySelectorAll('tbody tr'));
8
211
 
9
- colRows.forEach((row, index) => {
212
+ colRows.forEach((row) => {
10
213
  const cells = Array.from(row.querySelectorAll('th, td'));
11
214
  const statuses = [
12
215
  '0',
@@ -29,7 +232,8 @@ export const addDataAttributes = (table) => {
29
232
  'on track',
30
233
  'not started',
31
234
  'warning',
32
- 'error',
235
+ 'successful',
236
+ 'failed',
33
237
  ];
34
238
 
35
239
  cells.forEach((cell, cellIndex) => {
@@ -55,33 +259,17 @@ export const addDataAttributes = (table) => {
55
259
  });
56
260
  };
57
261
 
58
- export const getLargestLastColWidth = (table) => {
59
- let largestWidth = 0;
262
+ export const createMobileButton = (component, table): void => {
263
+ if (component.classList.contains('table--fullwidth') && !component.hasAttribute('data-expandable')) return false;
60
264
 
61
- Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
62
- const htmlStyles = window.getComputedStyle(document.querySelector('html'));
63
- const lastColChild = row.querySelector(':scope > *:last-child > *:first-child');
64
-
65
- if (lastColChild) {
66
- lastColChild.classList.add('text-nowrap');
67
- let responsiveWidth = lastColChild.offsetWidth / parseFloat(htmlStyles.fontSize);
68
- responsiveWidth += 1.7;
69
- largestWidth = largestWidth > responsiveWidth ? largestWidth : responsiveWidth;
70
- }
71
- });
72
-
73
- return largestWidth;
74
- };
265
+ if (table.querySelectorAll('thead tr th').length < 4 && !component.hasAttribute('data-expandable')) return false;
75
266
 
76
- export const createMobileButton = (table, wrapper) => {
77
- if (wrapper.classList.contains('table--fullwidth') && !wrapper.hasAttribute('data-expandable')) return false;
78
267
 
79
- if (table.querySelectorAll('thead tr th').length < 4 && !wrapper.hasAttribute('data-expandable')) return false;
80
268
 
81
269
  //If the expand column already exists we don't need to add a new one.
82
- Array.from(table.querySelectorAll('thead tr')).forEach((row, index) => {
270
+ Array.from(table.querySelectorAll('thead tr')).forEach((row) => {
83
271
  if (!table.querySelectorAll('thead tr th.expand-button-heading').length) {
84
- row.insertAdjacentHTML('afterbegin', `<th class="th--fixed expand-button-heading"></th>`);
272
+ row.insertAdjacentHTML('afterbegin', `<th class="${component.hasAttribute('data-expandable') ? 'th--fixed ' : '' }expand-button-heading"></th>`);
85
273
  }
86
274
  });
87
275
 
@@ -89,12 +277,11 @@ export const createMobileButton = (table, wrapper) => {
89
277
  const preExpanded = row.getAttribute('data-view') === 'full' ? 'aria-expanded' : '';
90
278
  row.insertAdjacentHTML(
91
279
  'afterbegin',
92
- `<td class="td--fixed td--expand"><button class="btn btn-compact btn-secondary" data-expand-button ${preExpanded}>Expand</button></td>`
280
+ `<td class="${component.hasAttribute('data-expandable') ? 'td--fixed ' : '' }td--expand"><button class="btn btn-compact btn-secondary btn-sm" data-expand-button ${preExpanded} data-index="${index}">Expand</button></td>`
93
281
  );
94
282
  });
95
- };
96
283
 
97
- export const addTableEventListeners = (table) => {
284
+
98
285
  table.addEventListener('click', (event) => {
99
286
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-expand-button]')) {
100
287
  const button = event.target.closest('[data-expand-button]');
@@ -106,27 +293,272 @@ export const addTableEventListeners = (table) => {
106
293
  else tableRow.setAttribute('data-view', 'full');
107
294
 
108
295
  button.blur();
296
+
297
+ component.dispatchEvent(new CustomEvent('row-expanded', { detail: { row: button.getAttribute('data-index') } }));
298
+ }
299
+ });
300
+ };
301
+
302
+ export const getLargestLastColWidth = (component, table): void => {
303
+ let largestWidth = 0;
304
+
305
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row) => {
306
+ const htmlStyles = window.getComputedStyle(document.querySelector('html'));
307
+ const lastColChild = row.querySelector(':scope > *:last-child > *:first-child');
308
+
309
+ if (lastColChild) {
310
+ lastColChild.classList.add('text-nowrap');
311
+ let responsiveWidth = lastColChild.offsetWidth / parseFloat(htmlStyles.fontSize);
312
+ responsiveWidth += 1.8;
313
+ largestWidth = largestWidth > responsiveWidth ? largestWidth : responsiveWidth;
314
+ }
315
+ });
316
+
317
+ component.style.setProperty('--cta-width', `${largestWidth}rem`);
318
+ };
319
+
320
+ export const getRowHeight = (component, table): void => {
321
+ function outputsize(): void {
322
+ Array.from(table.querySelectorAll('tr')).forEach((row) => {
323
+ const rowHeight = row.offsetHeight;
324
+
325
+ row.style.setProperty('--row-height', `${rowHeight}px`);
326
+ });
327
+ }
328
+
329
+ new ResizeObserver(outputsize).observe(table);
330
+ };
331
+ // #endregion
332
+
333
+ export const setupAdvancedTable = (component, table): void => {
334
+ if (
335
+ component.querySelector('iam-actionbar[data-selectall]') ||
336
+ document.querySelector(`iam-actionbar[data-for='${component.getAttribute('id')}']`)
337
+ ) {
338
+ const actionbar = component.querySelector('iam-actionbar[data-selectall]')
339
+ ? component.querySelector('iam-actionbar[data-selectall]')
340
+ : document.querySelector(`iam-actionbar[data-for='${component.getAttribute('id')}']`);
341
+
342
+ addSelectboxes(component, table, actionbar);
343
+ }
344
+
345
+ component.querySelectorAll('.dialog__wrapper .btn-compact').forEach((btn) => {
346
+ btn.classList.add('btn-sm');
347
+ btn.classList.add('m-0');
348
+
349
+ const tr = btn.closest('tr');
350
+ const td = btn.closest('td');
351
+
352
+
353
+
354
+ const trChildren = Array.prototype.slice.call( tr.children );
355
+ const cellIndex = trChildren.indexOf( td );
356
+
357
+ td.classList.add('td--fixed');
358
+ table.querySelector(`thead tr th:nth-child(${cellIndex+1})`).classList.add('th--fixed');
359
+
360
+ });
361
+
362
+
363
+
364
+ };
365
+ // #region Advanced table functions
366
+ export const addSelectboxes = (component, table, actionbar): void => {
367
+ Array.from(table.querySelectorAll('thead tr')).forEach((row) => {
368
+ if (row.querySelector('.expand-button-heading'))
369
+ row.querySelector('.expand-button-heading').insertAdjacentHTML('afterend', `<th class="th--fixed"></th>`);
370
+ else row.insertAdjacentHTML('afterbegin', `<th class="th--fixed"></th>`);
371
+ });
372
+
373
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
374
+ row.setAttribute('data-index', index + 1);
375
+ if (!row.querySelector('.selectrow')) {
376
+ const rowID = `row${uniqueID(index)}`;
377
+
378
+ if (row.querySelector('.td--expand'))
379
+ row
380
+ .querySelector('.td--expand')
381
+ .insertAdjacentHTML(
382
+ 'afterend',
383
+ `<td class="td--fixed selectrow selected"><input type="checkbox" name="row" id="${rowID}" ${row.hasAttribute('data-selected') ? `checked="true"` : ''}/><label for="${rowID}"><span class="visually-hidden">Select row</span></label></td>`
384
+ );
385
+ else
386
+ row.insertAdjacentHTML(
387
+ 'afterbegin',
388
+ `<td class="td--fixed selectrow selected"><input type="checkbox" name="row" id="${rowID}" ${row.hasAttribute('data-selected') ? `checked="true"` : ''}/><label for="${rowID}"><span class="visually-hidden">Select row</span></label></td>`
389
+ );
390
+ }
391
+ });
392
+
393
+ table.addEventListener('change', (event) => {
394
+ if (event && event.target instanceof HTMLElement && event.target.closest('.selectrow input')) {
395
+ const input = event.target.closest('.selectrow input');
396
+ const row = event.target.closest('tr');
397
+
398
+ const count = table.querySelectorAll('.selectrow input[type="checkbox"]').length;
399
+ const countChecked = table.querySelectorAll('.selectrow input[type="checkbox"]:checked').length;
400
+
401
+ actionbar.setAttribute('data-selected', count == countChecked ? 'all' : countChecked);
402
+
403
+ const dispatchedEvent = new CustomEvent('row-selected', {
404
+ detail: {
405
+ rowIndex: row.getAttribute('data-index'),
406
+ checked: input.checked ? true : false,
407
+ },
408
+ });
409
+ component.dispatchEvent(dispatchedEvent);
410
+ }
411
+ });
412
+
413
+ actionbar.addEventListener('selected', (event) => {
414
+ if (event.detail.selected == '0') {
415
+ Array.from(table.querySelectorAll('.selectrow input[type="checkbox"]')).forEach((input) => {
416
+ input.checked = false;
417
+ });
418
+
419
+ const dispatchedEvent = new CustomEvent('all-rows-unselected');
420
+ component.dispatchEvent(dispatchedEvent);
421
+ } else if (event.detail.selected == 'all') {
422
+ Array.from(table.querySelectorAll('.selectrow input[type="checkbox"]')).forEach((input) => {
423
+ input.checked = true;
424
+ });
425
+
426
+ const dispatchedEvent = new CustomEvent('all-rows-selected');
427
+ component.dispatchEvent(dispatchedEvent);
109
428
  }
110
429
  });
111
430
  };
112
431
 
113
- // Filters
114
- export const createSearchDataList = (table, form) => {
115
- const searchInput = form.querySelector('input[data-search]');
432
+ // Export CSV Data
433
+ export const addExportEventListeners = (button, table): void | boolean => {
434
+ if (!button) {
435
+ return false;
436
+ }
437
+
438
+ button.addEventListener('click', () => {
439
+ exportAsCSV(table);
440
+ });
441
+ };
442
+
443
+ export const exportAsCSV = function (table): void {
444
+ let csvData = [];
445
+ // Get each row data
446
+ const rows = table.getElementsByTagName('tr');
447
+ for (let i = 0; i < rows.length; i++) {
448
+ // Get each column data
449
+ const cols = rows[i].querySelectorAll('td,th');
450
+
451
+ // Stores each csv row data
452
+ const csvRow = [];
453
+ for (let j = 0; j < cols.length; j++) {
454
+ // Get the text data of each cell of a row and push it to csvrow
455
+ csvRow.push(`"${cols[j].textContent}"`);
456
+ }
457
+
458
+ // Combine each column value with comma
459
+ csvData.push(csvRow.join(','));
460
+ }
461
+
462
+ // Combine each row data with new line character
463
+ csvData = csvData.join('\n');
464
+
465
+ // Create CSV file object and feed our csvData into it
466
+ const CSVFile = new Blob([csvData], {
467
+ type: 'text/csv',
468
+ });
469
+
470
+ // Create to temporary link to initiate download process
471
+ const tempLink = document.createElement('a');
472
+ tempLink.download = 'export.csv';
473
+ const url = window.URL.createObjectURL(CSVFile);
474
+ tempLink.href = url;
475
+
476
+ // This link should not be displayed
477
+ tempLink.style.display = 'none';
478
+ document.body.appendChild(tempLink);
116
479
 
480
+ // Automatically click the link to trigger download
481
+ tempLink.click();
482
+ document.body.removeChild(tempLink);
483
+ };
484
+
485
+ // #endregion
486
+
487
+ export const setupNoSubmitTable = (component, table, form, pagination, savedTableBody): void => {
488
+ sortViaHeaders(component, table);
489
+
490
+ createSearchDataList(component, table);
491
+
492
+ form.addEventListener('change', (event) => {
493
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
494
+ sortTable(table, form, savedTableBody);
495
+ }
496
+ });
497
+
498
+ addFilterEventListeners(component, table, form, pagination, savedTableBody);
499
+ };
500
+
501
+ // #region No submit table functions
502
+ export const sortViaHeaders = (component, table): void => {
503
+ table.addEventListener('click', (event) => {
504
+ if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
505
+ const heading = event.target.closest('[data-sort]');
506
+ heading.setAttribute('data-sort', 'true');
507
+
508
+ // Turn other headings off
509
+ Array.from(table.querySelectorAll('th[data-sort]')).forEach((element) => {
510
+ if (element != heading) {
511
+ element.setAttribute('data-sort', '');
512
+ element.removeAttribute('data-order-by');
513
+ heading.setAttribute('title', 'Click to sort ascending');
514
+ }
515
+ });
516
+
517
+ if (heading.hasAttribute('data-order-by') && heading.getAttribute('data-order-by') == 'asc') {
518
+ heading.setAttribute('data-order-by', 'desc');
519
+ heading.setAttribute('title', 'Click to sort ascending');
520
+ } else {
521
+ heading.setAttribute('data-order-by', 'asc');
522
+ heading.setAttribute('title', 'Click to sort descending');
523
+ }
524
+
525
+ // dispath event
526
+ const dispatchedEvent = new CustomEvent('sort-by-heading', {
527
+ detail: {
528
+ heading: heading.textContent,
529
+ sortBy: heading.getAttribute('data-order-by'),
530
+ ref: heading.getAttribute('data-ref'),
531
+ },
532
+ });
533
+
534
+ component.dispatchEvent(dispatchedEvent);
535
+
536
+ const sortBy = heading.textContent.trim();
537
+ const order = heading.getAttribute('data-order-by');
538
+
539
+ if (!component.hasAttribute('data-submit')) {
540
+ // TODO
541
+ sortTableByValues(table, sortBy, order);
542
+ }
543
+ }
544
+ });
545
+ };
546
+
547
+ export const createSearchDataList = (component, table): void => {
548
+ const actionbar = component.querySelector('iam-actionbar');
549
+ if (!actionbar) return false;
550
+
551
+ const searchInput = actionbar.shadowRoot?.querySelector('input#search');
117
552
  if (!searchInput) return false;
118
553
 
119
554
  const searchID = searchInput.getAttribute('id');
120
- const searchableColumns = searchInput.getAttribute('data-search').split(',');
121
555
  const inputWrapper = searchInput.parentNode;
122
556
 
123
557
  const searchableTerms = {};
124
- searchableColumns.forEach((columnHeading, index) => {
125
- Array.from(table.querySelectorAll('td[data-label="' + columnHeading.trim() + '"]')).forEach((td, index) => {
126
- if (td.querySelector('.td__content'))
127
- searchableTerms[td.querySelector('.td__content').textContent] = td.querySelector('.td__content').textContent;
128
- else searchableTerms[td.textContent] = td.textContent;
129
- });
558
+ table.querySelectorAll('tbody td:not(.td--fixed)').forEach((td) => {
559
+ if (td.querySelector('.td__content'))
560
+ searchableTerms[td.querySelector('.td__content').textContent] = td.querySelector('.td__content').textContent;
561
+ else searchableTerms[td.textContent] = td.textContent;
130
562
  });
131
563
 
132
564
  searchInput.setAttribute('list', `${searchID}_list`);
@@ -139,18 +571,97 @@ export const createSearchDataList = (table, form) => {
139
571
  .join('')}`;
140
572
  };
141
573
 
142
- export const addFilterEventListeners = (table, form, pagination, wrapper, savedTableBody) => {
143
- let timer;
574
+ export const sortTable = (table, form, savedTableBody): void | boolean => {
575
+ if (form.getAttribute('data-ajax')) {
576
+ return false;
577
+ }
144
578
 
145
- // Check what conditions are set on the table to see what the form actions are
146
- const formSubmit = function (event, paginate = false) {
147
- if (wrapper.hasAttribute('data-no-submit')) {
148
- return false;
579
+ const tbody = table.querySelector('tbody');
580
+
581
+ let selectedOption = form.querySelector(`input[type="radio"][data-sort]:checked`);
582
+
583
+ if (form.querySelector('select[data-sort]')) {
584
+ const select = form.querySelector('select[data-sort]');
585
+ selectedOption = form.querySelector(`select[data-sort] option:nth-child(${select.selectedIndex + 1})`);
586
+ }
587
+
588
+ const sortBy = selectedOption.getAttribute('data-sort');
589
+ const order = selectedOption.getAttribute('data-order');
590
+ const format = selectedOption.getAttribute('data-format');
591
+
592
+ if (!sortBy) {
593
+ tbody.innerHTML = savedTableBody.innerHTML;
594
+ addDataAttributes(table);
595
+ return false;
596
+ }
597
+
598
+ sortTableByValues(table, sortBy, order, format);
599
+ };
600
+
601
+ export const sortTableByValues = (table, sortBy, order, format = ''): void => {
602
+ const tbody = table.querySelector('tbody');
603
+
604
+ let orderArray = [];
605
+ if (!['asc', 'desc', 'descending'].includes(order)) {
606
+ orderArray = order.split(',');
607
+ }
608
+
609
+ // Create an array from the table rows, the index created is then used to sort the array
610
+ let tableArr = [];
611
+ Array.from(tbody.querySelectorAll('tr')).forEach((tableRow) => {
612
+ let rowIndex = tableRow
613
+ .querySelector('td[data-label="' + sortBy + '"], th[data-label="' + sortBy + '"]')
614
+ .textContent.trim();
615
+
616
+ if (tableRow.querySelector('[data-label="' + sortBy + '"] .td__content')) {
617
+ rowIndex = tableRow.querySelector('[data-label="' + sortBy + '"] .td__content').textContent.trim();
618
+ }
619
+
620
+ // If a predefined order set replace the search term with an ordered numeric value so it can be sorted
621
+ if (orderArray.length && orderArray.includes(rowIndex)) {
622
+ rowIndex = orderArray.indexOf(rowIndex);
623
+ }
624
+
625
+ if (isNumeric(rowIndex)) {
626
+ rowIndex = zeroPad(rowIndex, 10);
627
+ }
628
+
629
+ // If the sort format is date then lets transform the index to a sortable date (this is never displayed)
630
+ if (format && format == 'date') {
631
+ rowIndex = new Date(rowIndex);
149
632
  }
150
633
 
634
+ const dataRow = {
635
+ index: rowIndex,
636
+ row: tableRow,
637
+ };
638
+ tableArr.push(dataRow);
639
+ });
640
+
641
+ // Sort array alphabetically
642
+ tableArr.sort((a, b) => (a.index > b.index ? 1 : -1));
643
+
644
+ // Reverse if descending
645
+ if (order == 'descending' || order == 'desc') {
646
+ tableArr = tableArr.reverse();
647
+ }
648
+
649
+ // Create a string to return and populate the tbody
650
+ let strTbody = '';
651
+ tableArr.forEach((tableRow) => {
652
+ strTbody += tableRow.row.outerHTML;
653
+ });
654
+ tbody.innerHTML = strTbody;
655
+ };
656
+
657
+ export const addFilterEventListeners = (component, table, form, pagination, savedTableBody): void => {
658
+ let timer;
659
+
660
+ // Check what conditions are set on the table to see what the form actions are
661
+ const formSubmit = function (event, paginate = false): void | boolean {
151
662
  if (form.classList.contains('processing')) return false;
152
663
 
153
- Array.from(form.querySelectorAll('iam-applied-filters')).forEach((element, index) => {
664
+ Array.from(form.querySelectorAll('iam-applied-filters')).forEach((element) => {
154
665
  const event = new Event('tags-set');
155
666
  element.dispatchEvent(event);
156
667
  });
@@ -158,7 +669,7 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
158
669
  // Before submitting check if any duplicate checkboxes within the filters dialog needs to upset the original input
159
670
  if (event.type == 'submit') {
160
671
  form.classList.add('processing');
161
- Array.from(form.querySelectorAll('[data-duplicate]')).forEach((element, index) => {
672
+ Array.from(form.querySelectorAll('[data-duplicate]')).forEach((element) => {
162
673
  const id = element.getAttribute('data-duplicate');
163
674
  const input = document.getElementById(id);
164
675
  const card = document.querySelector(`[for="${id}"] iam-card`);
@@ -175,22 +686,10 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
175
686
  form.classList.remove('processing');
176
687
  }
177
688
 
178
- if (form.hasAttribute('data-ajax')) {
179
- // Default back to page 1
180
- if (!paginate) {
181
- const paginationInput = form.querySelector('[data-pagination]');
182
- paginationInput.value = 1;
183
- wrapper.setAttribute('data-page', 1);
184
- }
185
-
186
- loadAjaxTable(table, form, pagination, wrapper);
187
- } else if (form.hasAttribute('data-submit')) {
188
- form.submit();
189
- } else {
190
- filterTable(table, form, wrapper);
191
- populateDataQueries(table, form);
192
- }
689
+ filterTable(component, table, form, pagination);
690
+ populateDataQueries(component, table, form);
193
691
 
692
+ /*
194
693
  // Pass post data back to the page
195
694
  if (form.hasAttribute('data-ajax-post')) {
196
695
  const formData = new FormData(form);
@@ -199,21 +698,41 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
199
698
  http.open('GET', `${window.location.href}?ajax=true&${queryString}`);
200
699
  http.send();
201
700
  }
701
+ */
202
702
  };
203
703
 
204
- if (form.querySelector('iam-actionbar[data-search]')) {
205
- form.querySelector('iam-actionbar[data-search]').addEventListener('search-submit', (event) => {
206
- if (form.querySelector('input[data-search]')) {
207
- form.querySelector('input[data-search]').value = event.detail.search;
208
- } else {
704
+ if (component.querySelector('iam-actionbar[data-search]')) {
705
+ component.querySelector('iam-actionbar[data-search]').addEventListener('search-submit', (event) => {
706
+ if (form.querySelector('input[data-search]')) {
707
+ form.querySelector('input[data-search]').value = event.detail.search;
708
+ } else {
709
+ form.insertAdjacentHTML(
710
+ 'beforeend',
711
+ `<input type="hidden" name="search" data-search="${component.querySelector('iam-actionbar[data-search]').getAttribute('data-search')}" value="${event.detail.search}"/>`
712
+ );
713
+ }
714
+
715
+ const submitEvent = new CustomEvent('search-submit', {
716
+ detail: event.details,
717
+ });
718
+ component.dispatchEvent(submitEvent);
719
+
720
+ clearTimeout(timer);
721
+ formSubmit(event);
722
+ });
723
+ }
724
+
725
+ if (component.querySelector('iam-actionbar') && !component.querySelector('iam-actionbar').closest('form')) {
726
+ component.querySelector('iam-actionbar').addEventListener('change', (event) => {
727
+ if (!form.querySelector('.duplicate-actionbar')) {
209
728
  form.insertAdjacentHTML(
210
729
  'beforeend',
211
- `<input type="hidden" name="search" data-search="${form.querySelector('iam-actionbar[data-search]').getAttribute('data-search')}" value="${event.detail.search}"/>`
730
+ `<div class="duplicate-actionbar" style="visibility: hidden; pointer-events: none; position: absolute;"></div>`
212
731
  );
213
732
  }
214
733
 
215
- clearTimeout(timer);
216
- formSubmit(event);
734
+ form.querySelector('.duplicate-actionbar').innerHTML = component.querySelector('iam-actionbar').innerHTML;
735
+ filterTable(component, table, form, pagination);
217
736
  });
218
737
  }
219
738
 
@@ -230,14 +749,6 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
230
749
  form.addEventListener('change', (event) => {
231
750
  clearTimeout(timer);
232
751
 
233
- if (event && event.target instanceof HTMLElement && event.target.closest('[data-sort]')) {
234
- if (!form.hasAttribute('data-submit')) {
235
- sortTable(table, form, savedTableBody);
236
- }
237
-
238
- formSubmit(event);
239
- }
240
-
241
752
  if (event && event.target instanceof HTMLElement && event.target.closest('input[data-search]')) {
242
753
  formSubmit(event);
243
754
  }
@@ -245,7 +756,7 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
245
756
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-filter][data-no-ajax]')) {
246
757
  // Allow for input fields to filter the current results without a new ajax call
247
758
 
248
- filterTable(table, form, wrapper);
759
+ filterTable(component, table, form, pagination);
249
760
  populateDataQueries(table, form);
250
761
  } else if (
251
762
  event &&
@@ -299,7 +810,7 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
299
810
  if (event && event.target instanceof HTMLElement && event.target.closest('[data-clear]')) {
300
811
  form.classList.add('processing');
301
812
  // Make sure any applied filters have been removed
302
- Array.from(form.querySelectorAll('.applied-filters')).forEach((filters, index) => {
813
+ Array.from(form.querySelectorAll('.applied-filters')).forEach((filters) => {
303
814
  filters.innerHTML = '';
304
815
  });
305
816
 
@@ -373,10 +884,10 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
373
884
  const fields = [];
374
885
 
375
886
  // Collect the forms that we need to add an event listener for.
376
- Array.from(form.querySelectorAll('[data-mimic]')).forEach((input, index) => {
887
+ Array.from(form.querySelectorAll('[data-mimic]')).forEach((input) => {
377
888
  const mimicField = input.getAttribute('data-mimic');
378
889
 
379
- Array.from(document.querySelectorAll(`[name="${mimicField}"]`)).forEach((mimicInput, index) => {
890
+ Array.from(document.querySelectorAll(`[name="${mimicField}"]`)).forEach((mimicInput) => {
380
891
  const parentForm = mimicInput.closest('form');
381
892
 
382
893
  if (!forms.includes(parentForm)) {
@@ -390,8 +901,8 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
390
901
  });
391
902
 
392
903
  // For each form add change listener
393
- forms.forEach((parentForm, index) => {
394
- const updateMimicInput = function () {
904
+ forms.forEach((parentForm) => {
905
+ const updateMimicInput = function (): void {
395
906
  const mimickedAlready = [];
396
907
  const formData = new FormData(parentForm);
397
908
 
@@ -422,94 +933,17 @@ export const addFilterEventListeners = (table, form, pagination, wrapper, savedT
422
933
  }
423
934
  };
424
935
 
425
- parentForm.addEventListener('force', (event) => {
936
+ parentForm.addEventListener('force', () => {
426
937
  updateMimicInput();
427
938
  });
428
939
 
429
- parentForm.addEventListener('change', (event) => {
940
+ parentForm.addEventListener('change', () => {
430
941
  updateMimicInput();
431
942
  });
432
943
  });
433
944
  };
434
945
 
435
- export const sortTable = (table, form, savedTableBody) => {
436
- if (form.getAttribute('data-ajax')) {
437
- return false;
438
- }
439
-
440
- const tbody = table.querySelector('tbody');
441
-
442
- let selectedOption = form.querySelector(`input[type="radio"][data-sort]:checked`);
443
-
444
- if (form.querySelector('select[data-sort]')) {
445
- const select = form.querySelector('select[data-sort]');
446
- selectedOption = form.querySelector(`select[data-sort] option:nth-child(${select.selectedIndex + 1})`);
447
- }
448
-
449
- const sortBy = selectedOption.getAttribute('data-sort');
450
- const order = selectedOption.getAttribute('data-order');
451
- const format = selectedOption.getAttribute('data-format');
452
-
453
- if (!sortBy) {
454
- tbody.innerHTML = savedTableBody.innerHTML;
455
- addDataAttributes(table);
456
- return false;
457
- }
458
-
459
- let orderArray = [];
460
- if (!['asc', 'desc', 'descending'].includes(order)) {
461
- orderArray = order.split(',');
462
- }
463
-
464
- // Create an array from the table rows, the index created is then used to sort the array
465
- let tableArr = [];
466
- Array.from(tbody.querySelectorAll('tr')).forEach((tableRow, index) => {
467
- let rowIndex = tableRow
468
- .querySelector('td[data-label="' + sortBy + '"], th[data-label="' + sortBy + '"]')
469
- .textContent.trim();
470
-
471
- if (tableRow.querySelector('[data-label="' + sortBy + '"] .td__content')) {
472
- rowIndex = tableRow.querySelector('[data-label="' + sortBy + '"] .td__content').textContent.trim();
473
- }
474
-
475
- // If a predefined order set replace the search term with an ordered numeric value so it can be sorted
476
- if (orderArray.length && orderArray.includes(rowIndex)) {
477
- rowIndex = orderArray.indexOf(rowIndex);
478
- }
479
-
480
- if (isNumeric(rowIndex)) {
481
- rowIndex = zeroPad(rowIndex, 10);
482
- }
483
-
484
- // If the sort format is date then lets transform the index to a sortable date (this is never displayed)
485
- if (format && format == 'date') {
486
- rowIndex = new Date(rowIndex);
487
- }
488
-
489
- const dataRow = {
490
- index: rowIndex,
491
- row: tableRow,
492
- };
493
- tableArr.push(dataRow);
494
- });
495
-
496
- // Sort array alphabetically
497
- tableArr.sort((a, b) => (a.index > b.index ? 1 : -1));
498
-
499
- // Reverse if descending
500
- if (order == 'descending' || order == 'desc') {
501
- tableArr = tableArr.reverse();
502
- }
503
-
504
- // Create a string to return and populate the tbody
505
- let strTbody = '';
506
- tableArr.forEach((tableRow, index) => {
507
- strTbody += tableRow.row.outerHTML;
508
- });
509
- tbody.innerHTML = strTbody;
510
- };
511
-
512
- export const filterTable = (table, form, wrapper) => {
946
+ export const filterTable = (component, table, form, pagination): void => {
513
947
  table.classList.remove('table--filtered');
514
948
 
515
949
  const filters = filterFilters(form);
@@ -519,7 +953,7 @@ export const filterTable = (table, form, wrapper) => {
519
953
  const showRows = form.querySelector('[data-show]') ? parseInt(form.querySelector('[data-show]').value) : 15;
520
954
 
521
955
  // Reset
522
- Array.from(table.querySelectorAll('tbody tr')).forEach((row, index) => {
956
+ Array.from(table.querySelectorAll('tbody tr')).forEach((row) => {
523
957
  row.classList.remove('filtered');
524
958
  row.classList.remove('filtered--matched');
525
959
  row.classList.remove('filtered--show');
@@ -530,21 +964,21 @@ export const filterTable = (table, form, wrapper) => {
530
964
  // Add search columns too
531
965
  if (form.querySelector('input[data-search]')) {
532
966
  const searchInput = form.querySelector('input[data-search]');
533
- const searchColumns = form.querySelector('input[data-search]').getAttribute('data-search').split(',');
967
+ //const searchColumns = form.querySelector('input[data-search],[part="search-input"]').getAttribute('data-search').split(',');
534
968
 
535
- searchColumns.forEach((column, index) => {
536
- searches.push({ column: `${column.trim()}`, value: `${searchInput.value}` });
969
+ table.querySelectorAll('thead tr th').forEach((column) => {
970
+ searches.push({ column: `${column.textContent.trim()}`, value: `${searchInput.value}` });
537
971
  });
538
972
  }
539
973
 
540
974
  //Display the filter count
541
- Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element, index) => {
975
+ Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element) => {
542
976
  element.innerHTML = '';
543
977
  element.parentNode.classList.remove('hover');
544
978
  });
545
979
 
546
980
  let filterCount = 0;
547
- Object.values(filters).forEach((filter, index) => {
981
+ Object.values(filters).forEach((filter) => {
548
982
  if (typeof filter == 'object' && Object.values(filter).length) {
549
983
  filterCount += Object.values(filter).length;
550
984
  } else {
@@ -553,7 +987,7 @@ export const filterTable = (table, form, wrapper) => {
553
987
  });
554
988
 
555
989
  if (filterCount) {
556
- Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element, index) => {
990
+ Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element) => {
557
991
  element.innerHTML += `(${filterCount})`;
558
992
  element.parentNode.classList.add('hover');
559
993
  });
@@ -562,9 +996,9 @@ export const filterTable = (table, form, wrapper) => {
562
996
  // Filter the table
563
997
  table.classList.add('table--filtered');
564
998
  for (const [key, filterValue] of Object.entries(filters)) {
565
- Array.from(table.querySelectorAll('tbody tr:not(.filtered)')).forEach((row, index) => {
999
+ Array.from(table.querySelectorAll('tbody tr:not(.filtered)')).forEach((row) => {
566
1000
  let isMatched = false;
567
- filterValue.forEach((filter, index) => {
1001
+ filterValue.forEach((filter) => {
568
1002
  const filterTd = row.querySelector(`[data-label="${key}"]`);
569
1003
 
570
1004
  if (filter.includes('-date-from')) {
@@ -672,10 +1106,10 @@ export const filterTable = (table, form, wrapper) => {
672
1106
  });
673
1107
  }
674
1108
  // Search whats left of the table after filtering
675
- Array.from(table.querySelectorAll('tbody tr:not(.filtered)')).forEach((row, index) => {
1109
+ Array.from(table.querySelectorAll('tbody tr:not(.filtered)')).forEach((row) => {
676
1110
  let isSearched = searches.length > 0 && searches[0].value.length >= 3 ? false : true;
677
1111
 
678
- searches.forEach((search, index) => {
1112
+ searches.forEach((search) => {
679
1113
  const searchTd = row.querySelector(`[data-label="${search.column}"]`);
680
1114
 
681
1115
  if (
@@ -693,7 +1127,7 @@ export const filterTable = (table, form, wrapper) => {
693
1127
  });
694
1128
 
695
1129
  // Work out what to display after pagination
696
- Array.from(table.querySelectorAll('tbody tr:not(.filtered)')).forEach((row, index) => {
1130
+ Array.from(table.querySelectorAll('tbody tr:not(.filtered)')).forEach((row) => {
697
1131
  matched++;
698
1132
 
699
1133
  row.classList.add('filtered--matched');
@@ -705,22 +1139,22 @@ export const filterTable = (table, form, wrapper) => {
705
1139
  }
706
1140
  });
707
1141
 
708
- if (wrapper) {
709
- wrapper.setAttribute('data-total', matched);
710
- wrapper.setAttribute('data-show', showRows);
711
- wrapper.setAttribute('data-page', page);
1142
+ if (pagination) {
1143
+ pagination.setAttribute('data-total', matched);
1144
+ pagination.setAttribute('data-show', showRows);
1145
+ pagination.setAttribute('data-page', page);
712
1146
  }
713
1147
  };
714
1148
 
715
- export const populateDataQueries = (table, form, wrapper) => {
1149
+ export const populateDataQueries = (component, table, form): void | boolean => {
716
1150
  const dataQueries = Array.from(form.querySelectorAll('[data-query]'));
717
1151
 
718
- dataQueries.forEach((queryElement, index) => {
1152
+ dataQueries.forEach((queryElement) => {
719
1153
  const query = queryElement.getAttribute('data-query');
720
1154
  let numberOfMatchedRows = 0;
721
1155
 
722
1156
  if (query == 'total') {
723
- if (wrapper.hasAttribute('data-total')) numberOfMatchedRows = wrapper.getAttribute('data-total');
1157
+ if (component.hasAttribute('data-total')) numberOfMatchedRows = component.getAttribute('data-total');
724
1158
  else
725
1159
  numberOfMatchedRows = table.classList.contains('table--filtered')
726
1160
  ? table.querySelectorAll('tbody tr').length
@@ -742,7 +1176,7 @@ export const populateDataQueries = (table, form, wrapper) => {
742
1176
  numberOfMatchedRows = Array.from(table.querySelectorAll(`tbody tr:not(.filtered)`)).filter(function (row) {
743
1177
  let matched = true;
744
1178
 
745
- for (const [index, value] of Object.entries(queries)) {
1179
+ for (const value of Object.entries(queries)) {
746
1180
  const queryParts = value.split(' == ');
747
1181
 
748
1182
  if (
@@ -772,180 +1206,97 @@ export const populateDataQueries = (table, form, wrapper) => {
772
1206
  }
773
1207
  });
774
1208
  };
1209
+ // #endregion
775
1210
 
776
- // Pagination
777
- export const addPaginationEventListeners = function (table, form, pagination, wrapper) {
778
- if (wrapper.hasAttribute('data-no-submit')) {
779
- return false;
780
- }
781
-
782
- pagination.addEventListener('update-page', (event) => {
783
- const paginationInput = form.querySelector('[data-pagination]');
784
- const newPage = event.detail.page;
785
-
786
- // Set the filter value
787
- paginationInput.value = newPage;
788
- form.dispatchEvent(new Event('paginate'));
789
-
790
- // Reset the data attribute
791
- wrapper.setAttribute('data-page', newPage);
792
-
793
- if (table.hasAttribute('data-show-history')) {
794
- const url = new URL(location);
795
- url.searchParams.set('page', newPage);
796
- history.pushState({ type: 'pagination', form: form.getAttribute('id'), page: newPage }, '', url);
797
- }
798
-
799
- // scroll back to the top of the table
800
- if (!wrapper.hasAttribute('data-no-scroll')) {
801
- const yOffset = -250;
802
- const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
803
- window.scrollTo({ top: y, behavior: 'smooth' });
804
- }
805
- });
1211
+ export const setupSubmitTable = (component, table, form, pagination): void => {
1212
+ form.setAttribute('method', 'get');
806
1213
 
807
- pagination.addEventListener('update-show', (event) => {
808
- const showInput = form.querySelector('[data-show]');
809
- const showRows = event.detail.show;
810
- showInput.value = showRows;
811
- wrapper.setAttribute('data-show', showRows);
812
- form.dispatchEvent(new Event('submit'));
813
- });
814
- };
1214
+ const actionbar = component.querySelector('iam-actionbar');
815
1215
 
816
- // Export CSV Data
817
- export const addExportEventListeners = (button, table) => {
818
- if (!button) {
819
- return false;
1216
+ if (actionbar) {
1217
+ actionbar.addEventListener('change', (event) => {
1218
+ form.submit();
1219
+ });
820
1220
  }
821
-
822
- button.addEventListener('click', (event) => {
823
- exportAsCSV(table);
824
- });
825
1221
  };
826
1222
 
827
- export const exportAsCSV = function (table) {
828
- let csvData = [];
829
- // Get each row data
830
- const rows = table.getElementsByTagName('tr');
831
- for (let i = 0; i < rows.length; i++) {
832
- // Get each column data
833
- const cols = rows[i].querySelectorAll('td,th');
834
-
835
- // Stores each csv row data
836
- const csvRow = [];
837
- for (let j = 0; j < cols.length; j++) {
838
- // Get the text data of each cell of a row and push it to csvrow
839
- csvRow.push(`"${cols[j].textContent}"`);
840
- }
841
-
842
- // Combine each column value with comma
843
- csvData.push(csvRow.join(','));
844
- }
845
-
846
- // Combine each row data with new line character
847
- csvData = csvData.join('\n');
1223
+ // #region submit tables functions
848
1224
 
849
- // Create CSV file object and feed our csvData into it
850
- const CSVFile = new Blob([csvData], {
851
- type: 'text/csv',
852
- });
1225
+ // #endregion
853
1226
 
854
- // Create to temporary link to initiate download process
855
- const tempLink = document.createElement('a');
856
- tempLink.download = 'export.csv';
857
- const url = window.URL.createObjectURL(CSVFile);
858
- tempLink.href = url;
1227
+ export const setupAjaxTable = (component, table, form, pagination): void => {
1228
+ loadAjaxTable(component, table, form, pagination);
859
1229
 
860
- // This link should not be displayed
861
- tempLink.style.display = 'none';
862
- document.body.appendChild(tempLink);
1230
+ const actionbar = component.querySelector('iam-actionbar');
863
1231
 
864
- // Automatically click the link to trigger download
865
- tempLink.click();
866
- document.body.removeChild(tempLink);
867
- };
1232
+ form.addEventListener('submit', (event) => {
1233
+ loadAjaxTable(component, table, form, pagination);
868
1234
 
869
- // After table is loaded
870
- export const makeTableFunctional = function (table, form, pagination, wrapper) {
871
- addDataAttributes(table);
872
- createMobileButton(table, wrapper);
873
- populateDataQueries(table, form, wrapper);
874
-
875
- // Work out the largest width of the CTA's in the last column
876
- if (wrapper && wrapper.classList.contains('table--cta')) {
877
- const largestWidth = getLargestLastColWidth(table);
878
- wrapper.style.setProperty('--cta-width', `${largestWidth}rem`);
879
-
880
- function outputsize() {
881
- Array.from(table.querySelectorAll('tr')).forEach((row, index) => {
882
- const rowHeight = row.offsetHeight;
883
- row.style.setProperty('--row-height', `${rowHeight}px`);
884
- });
885
- }
1235
+ event.preventDefault();
1236
+ });
886
1237
 
887
- new ResizeObserver(outputsize).observe(table);
1238
+ if (actionbar) {
1239
+ actionbar.addEventListener('change', (event) => {
1240
+ loadAjaxTable(component, table, form, pagination);
1241
+ });
888
1242
  }
889
1243
  };
1244
+ // #region ajax tables functions
1245
+
1246
+ export const loadAjaxTable = async function (component, table, form, pagination): void {
1247
+ // Add actionbar inputs into form
1248
+ if (component.querySelector('iam-actionbar') && !component.querySelector('iam-actionbar').closest('form')) {
1249
+ if (!form.querySelector('.duplicate-actionbar'))
1250
+ form.insertAdjacentHTML(
1251
+ 'beforeend',
1252
+ `<div class="duplicate-actionbar" style="visibility: hidden; pointer-events: none; position: absolute;"></div>`
1253
+ );
890
1254
 
891
- const filterFilters = function (form) {
892
- const filters = new Object();
893
-
894
- // Filter
895
- const filterInputs = Array.from(form.querySelectorAll('[data-filter]'));
896
-
897
- filterInputs.forEach((filterInput, index) => {
898
- // Ignore uncked radio inputs
899
- if (filterInput.type == 'radio' && !filterInput.checked) {
900
- return;
901
- }
902
-
903
- if (filterInput.type == 'checkbox' && !filterInput.checked) {
904
- return;
905
- }
906
-
907
- if (filterInput && filterInput.value) {
908
- const dataFilter = filterInput.getAttribute('data-filter');
909
- let filterValue = filterInput.value;
910
-
911
- if (filterInput.hasAttribute('data-date-from')) filterValue += '-date-from';
912
-
913
- if (filterInput.hasAttribute('data-date-to')) filterValue += '-date-to';
1255
+ form.querySelector('.duplicate-actionbar').innerHTML = component.querySelector('iam-actionbar').innerHTML;
1256
+ }
914
1257
 
915
- if (!filters[dataFilter]) filters[dataFilter] = [];
1258
+ // Add pagination inputs into form
1259
+ if (!form.querySelector('input[name=show]'))
1260
+ form.insertAdjacentHTML(
1261
+ 'beforeend',
1262
+ `<input name="show" type="hidden" value="${component.getAttribute('data-show')}" />`
1263
+ );
916
1264
 
917
- filters[dataFilter].push(filterValue);
918
- }
919
- });
1265
+ if (!form.querySelector('input[name=page]'))
1266
+ form.insertAdjacentHTML(
1267
+ 'beforeend',
1268
+ `<input name="page" type="hidden" value="${component.getAttribute('data-page')}" />`
1269
+ );
920
1270
 
921
- return filters;
922
- };
1271
+ form.querySelector('input[name=page]').value = component.getAttribute('data-page');
1272
+ form.querySelector('input[name=show]').value = component.getAttribute('data-show');
923
1273
 
924
- export const loadAjaxTable = async function (table, form, pagination, wrapper) {
1274
+ // Construct form data to send to api
925
1275
  const formData = new FormData(form);
1276
+
926
1277
  const queryString = new URLSearchParams(formData).toString();
927
1278
  const columns = table.querySelectorAll('thead tr th:not(.expand-button-heading)');
928
1279
  const tbody = table.querySelector('tbody');
929
1280
  const ajaxURL = form.getAttribute('data-ajax');
930
1281
 
931
- wrapper.classList.add('table--loading');
1282
+ component.classList.add('table--loading');
932
1283
 
933
1284
  // Display the filter count
934
1285
  const filters = filterFilters(form);
935
1286
 
936
- Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element, index) => {
1287
+ Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element) => {
937
1288
  element.innerHTML = '';
938
1289
  element.parentNode.classList.remove('hover');
939
1290
  });
940
1291
 
941
1292
  let filterCount = 0;
942
- Object.values(filters).forEach((filter, index) => {
1293
+ Object.values(filters).forEach((filter) => {
943
1294
  if (typeof filter == 'object' && Object.values(filter).length) filterCount += Object.values(filter).length;
944
1295
  else filterCount++;
945
1296
  });
946
1297
 
947
1298
  if (filterCount) {
948
- Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element, index) => {
1299
+ Array.from(form.querySelectorAll('[data-filter-count]')).forEach((element) => {
949
1300
  element.innerHTML += `(${filterCount})`;
950
1301
  element.parentNode.classList.add('hover');
951
1302
  });
@@ -989,24 +1340,24 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper) {
989
1340
  const totalNumber = resolvePath(response, totalNumberSchema, 15);
990
1341
  const currentPage = resolvePath(response, currentPageSchema, 1);
991
1342
  const data = resolvePath(response, schema);
992
- const emptyMsg = wrapper.hasAttribute('data-empty-msg')
993
- ? wrapper.getAttribute('data-empty-msg')
1343
+ const emptyMsg = component.hasAttribute('data-empty-msg')
1344
+ ? component.getAttribute('data-empty-msg')
994
1345
  : 'No results found';
995
1346
 
996
1347
  if (data) {
997
1348
  tbody.innerHTML = '';
998
1349
 
999
- data.forEach((row, index) => {
1350
+ data.forEach((row) => {
1000
1351
  const table_row = document.createElement('tr');
1001
1352
 
1002
- columns.forEach((col, index) => {
1353
+ columns.forEach((col) => {
1003
1354
  let cellOutput = '';
1004
1355
  const table_cell = document.createElement('td');
1005
1356
  // Add some data to help with the mobile layout design
1006
1357
  table_cell.setAttribute('data-label', col.innerText);
1007
1358
 
1008
1359
  if (col.getAttribute('data-output')) {
1009
- var cellTemplate = col.getAttribute('data-output');
1360
+ const cellTemplate = col.getAttribute('data-output');
1010
1361
  // Use a regex to replace {var} with actual values from the json data
1011
1362
  cellOutput = cellTemplate.replace(new RegExp(/{(.*?)}/, 'gm'), function (matched) {
1012
1363
  return resolvePath(row, matched.replace('{', '').replace('}', ''));
@@ -1015,11 +1366,11 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper) {
1015
1366
 
1016
1367
  // If an output array is defined then the content is going to made of of multiple values from an array
1017
1368
  if (col.hasAttribute('data-output-array')) {
1018
- var cellTemplate = col.getAttribute('data-output');
1369
+ const cellTemplate = col.getAttribute('data-output');
1019
1370
  const arrValue = resolvePath(row, cellTemplate.replace('{', '').replace('}', ''));
1020
1371
 
1021
1372
  cellOutput = '';
1022
- arrValue.forEach((rowValue, i) => {
1373
+ arrValue.forEach((rowValue) => {
1023
1374
  const cellTemplateValue = col.getAttribute('data-output-array');
1024
1375
  let cellOutputValue = '';
1025
1376
 
@@ -1059,14 +1410,13 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper) {
1059
1410
  tbody.appendChild(table_row);
1060
1411
  });
1061
1412
 
1062
- createSearchDataList(table, form);
1063
- // Add data to the pagination
1064
- wrapper.setAttribute('data-total', parseInt(totalNumber));
1065
- wrapper.setAttribute('data-page', parseInt(currentPage));
1413
+ component.setAttribute('data-total', parseInt(totalNumber));
1414
+ component.setAttribute('data-page', parseInt(currentPage));
1066
1415
 
1067
- makeTableFunctional(table, form, pagination, wrapper);
1416
+ pagination.setAttribute('data-total', totalNumber);
1417
+ pagination.setAttribute('data-page', currentPage);
1068
1418
 
1069
- Array.from(form.querySelectorAll('[data-ajax-query]')).forEach((queryElement, index) => {
1419
+ Array.from(form.querySelectorAll('[data-ajax-query]')).forEach((queryElement) => {
1070
1420
  const totalNumber = resolvePath(response, queryElement.getAttribute('data-ajax-query'), '');
1071
1421
 
1072
1422
  if (queryElement.hasAttribute('data-total')) queryElement.setAttribute('data-total', totalNumber);
@@ -1077,7 +1427,7 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper) {
1077
1427
  tbody.innerHTML = `<tr><td colspan="100%"><span>${emptyMsg}</span></td></tr>`;
1078
1428
  }
1079
1429
 
1080
- wrapper.classList.remove('table--loading');
1430
+ component.classList.remove('table--loading');
1081
1431
 
1082
1432
  window.dataLayer = window.dataLayer || [];
1083
1433
  window.dataLayer.push({
@@ -1085,6 +1435,9 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper) {
1085
1435
  url: ajaxURL,
1086
1436
  formData: queryString,
1087
1437
  });
1438
+
1439
+ setupBasicTable(component, table, form, pagination);
1440
+ setupAdvancedTable(component, table, form, pagination);
1088
1441
  } else {
1089
1442
  tbody.innerHTML = '<tr><td colspan="100%"><span>Error loading table</span></td></tr>';
1090
1443
  }
@@ -1097,27 +1450,44 @@ export const loadAjaxTable = async function (table, form, pagination, wrapper) {
1097
1450
  console.log(error);
1098
1451
  }
1099
1452
  };
1453
+ // #endregion
1100
1454
 
1101
- export const formatCell = (format, cellOutput) => {
1102
- switch (format) {
1103
- case 'datetime':
1104
- return (
1105
- new Date(cellOutput).toLocaleDateString('en-gb', {
1106
- weekday: 'short',
1107
- year: '2-digit',
1108
- month: 'long',
1109
- day: 'numeric',
1110
- }) +
1111
- ' ' +
1112
- new Date(cellOutput).toLocaleTimeString('en-gb', { hour: '2-digit', minute: '2-digit' })
1113
- );
1114
- case 'date':
1115
- return new Date(cellOutput).toLocaleDateString('en-gb', {
1116
- day: 'numeric',
1117
- month: 'long',
1118
- year: '2-digit',
1119
- });
1120
- case 'capitalise':
1121
- return (cellOutput = ucfirst(cellOutput));
1122
- }
1455
+ /*
1456
+ // Pagination - still needed?
1457
+ export const addPaginationEventListeners = function (component, table, form, pagination): void | boolean {
1458
+
1459
+
1460
+ pagination.addEventListener('update-page', (event) => {
1461
+ const paginationInput = form.querySelector('[data-pagination]');
1462
+ const newPage = event.detail.page;
1463
+
1464
+ // Set the filter value
1465
+ paginationInput.value = newPage;
1466
+ form.dispatchEvent(new Event('paginate'));
1467
+
1468
+ // Reset the data attribute
1469
+ component.setAttribute('data-page', newPage);
1470
+
1471
+ if (table.hasAttribute('data-show-history')) {
1472
+ const url = new URL(location);
1473
+ url.searchParams.set('page', newPage);
1474
+ history.pushState({ type: 'pagination', form: form.getAttribute('id'), page: newPage }, '', url);
1475
+ }
1476
+
1477
+ // scroll back to the top of the table
1478
+ if (!component.hasAttribute('data-no-scroll')) {
1479
+ const yOffset = -250;
1480
+ const y = table.getBoundingClientRect().top + window.pageYOffset + yOffset;
1481
+ window.scrollTo({ top: y, behavior: 'smooth' });
1482
+ }
1483
+ });
1484
+
1485
+ pagination.addEventListener('update-show', (event) => {
1486
+ const showInput = form.querySelector('[data-show]');
1487
+ const showRows = event.detail.show;
1488
+ showInput.value = showRows;
1489
+ component.setAttribute('data-show', showRows);
1490
+ form.dispatchEvent(new Event('submit'));
1491
+ });
1123
1492
  };
1493
+ */