HTableForm.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. import {createApp} from "vue/dist/vue.esm-bundler.js";
  2. import {getTokenHeader} from '~src/api/request/header';
  3. import {toParse, isArray} from "vue-utils-plus";
  4. //自定义组件或二次封装的组件
  5. import HcTableFormUpload from "~com/plugins/table-form/hc-form-upload.vue"
  6. import HcFormSelectSearch from "~com/plugins/table-form/hc-form-select-search.vue"
  7. import HcFormCheckboxGroup from "~com/plugins/table-form/hc-form-checkbox-group.vue"
  8. import ElTimePicker from "~com/plugins/table-form/hc-time-picker.vue"
  9. import ElDatePicker from "~com/plugins/table-form/hc-date-picker-1.vue"
  10. import ElRadioGroup from "~com/plugins/table-form/hc-form-radio-group.vue"
  11. //修改过的组件
  12. import {ElSelect, ElOption} from 'z-element-plus'
  13. import {
  14. ElButton, ElTooltip, ElInput, ElUpload, ElInputNumber, ElRadio, ElCheckbox, ElCheckboxGroup
  15. } from 'element-plus'
  16. const components = {
  17. ElButton, ElTooltip, ElInput, ElUpload, ElInputNumber, ElSelect, ElOption,
  18. ElRadio, ElCheckbox, ElCheckboxGroup,
  19. ElDatePicker, ElTimePicker, HcTableFormUpload, ElRadioGroup,
  20. HcFormSelectSearch,
  21. HcFormCheckboxGroup
  22. }
  23. //表单渲染
  24. export default class HTableForm {
  25. static createForm({template, tableForm, keys, appId, onRight, onBlur, onLeftClick}) {
  26. const _this = this;
  27. const app = createApp({
  28. data() {
  29. return {
  30. getTokenHeader: getTokenHeader(),
  31. formData: tableForm,
  32. }
  33. },
  34. //html标签数据
  35. template,
  36. //自定义组件,需要把饿了么的组件,或者自定义组件手动传递进来绑定,否则渲染时,自定义组件不会生效
  37. components,
  38. //监听数据,伪双向绑定(v-model)
  39. watch: {
  40. tableForm: {
  41. handler(obj) {
  42. this.formData = obj
  43. },
  44. deep: true
  45. },
  46. formData: {
  47. handler(obj) {
  48. tableForm = obj
  49. },
  50. deep: true
  51. },
  52. },
  53. methods: {
  54. //鼠标右键菜单
  55. contextmenuClick(a, b, c, d, e, f, event) {
  56. event.preventDefault();
  57. },
  58. //鼠标右键事件
  59. RightClick(a, b, c, d, e, f, event) {
  60. const KeyName = event?.target?.getAttribute('keyname') || ''
  61. if (onRight) {
  62. onRight(event, KeyName)
  63. }
  64. },
  65. //焦点事件
  66. getInformation() {
  67. },
  68. //日期选择事件
  69. datePickerChange(val, key) {
  70. this.formData[key] = val
  71. },
  72. //上传完成
  73. formUploadSuccess({src, key}) {
  74. this.formData[key] = src
  75. },
  76. //删除上传的文件
  77. delTableFormFile(key) {
  78. this.formData[key] = ''
  79. },
  80. //失去焦点事件
  81. getRegularExpression(event, reg, msg, a, b, leng) {
  82. const KeyName = event?.target?.getAttribute('keyname') || ''
  83. if (onBlur) {
  84. onBlur(event, KeyName, reg, this.formData[KeyName], msg, leng)
  85. }
  86. },
  87. //远程搜索处理
  88. formRemoteChange(data) {
  89. Object.keys(data).forEach(key => {
  90. this.formData[key] = data[key]
  91. })
  92. },
  93. //多选框处理
  94. checkboxGroupChange({key, val}) {
  95. this.formData[key] = val
  96. },
  97. //键盘事件 上键
  98. keyupShiftUp(event) {
  99. _this.setKeyupData(event, 'up', keys)
  100. },
  101. //键盘事件 下键
  102. keyupShiftDown(event) {
  103. _this.setKeyupData(event, 'down', keys)
  104. },
  105. //键盘事件 左键
  106. keyupShiftLeft(event) {
  107. _this.setKeyupData(event, 'left', keys)
  108. },
  109. //键盘事件 右键
  110. keyupShiftRight(event) {
  111. _this.setKeyupData(event, 'right', keys)
  112. },
  113. //日期时间框键盘事件
  114. dateKeydown({type, name}) {
  115. _this.setKeyupData(name, type, keys)
  116. },
  117. //输入左键点击事件
  118. inputLeftClick(event, key) {
  119. if (onLeftClick) {
  120. onLeftClick(key)
  121. }
  122. },
  123. }
  124. })
  125. app.mount(appId)
  126. return app
  127. }
  128. //处理日期范围数据
  129. static setPickerKey(data) {
  130. const pickerKey = data['pickerKey'] || ''
  131. if (pickerKey) {
  132. const pickerKeys = pickerKey.split(',')
  133. for (let i = 0; i < pickerKeys.length; i++) {
  134. const val = data[pickerKeys[i]] || ''
  135. if (val) {
  136. const dataVal = val.replace(/'/g, '"');
  137. data[pickerKeys[i]] = toParse(dataVal) || []
  138. } else {
  139. data[pickerKeys[i]] = []
  140. }
  141. }
  142. }
  143. return data
  144. }
  145. //处理日期时间框的切换事件
  146. static setByClassKeyup(keys) {
  147. try {
  148. let poppers = document.getElementsByClassName('hc-table-form-date-picker')
  149. for (let i = 0; i < poppers.length; i++) {
  150. let item = poppers[i], key = '';
  151. const ids = item.getAttribute('class').split('-form-id-')
  152. if (ids.length >= 1) {
  153. key = ids[1]
  154. }
  155. if (ids) {
  156. let panels = item.getElementsByClassName('el-picker-panel__content')
  157. this.setElementsEvent(panels, key, keys)
  158. }
  159. }
  160. } catch (e) {
  161. console.log(e)
  162. }
  163. }
  164. //设置事件
  165. static setElementsEvent(elements, key, keys) {
  166. if (elements.length > 0) {
  167. const _this = this;
  168. elements[0].addEventListener("keydown", e => {
  169. e.stopPropagation()
  170. if (e.key === 'ArrowUp') {
  171. _this.setKeyupData({target: {id: key}}, 'up', keys)
  172. } else if (e.key === 'ArrowDown') {
  173. _this.setKeyupData({target: {id: key}}, 'down', keys)
  174. } else if (e.key === 'ArrowLeft') {
  175. _this.setKeyupData({target: {id: key}}, 'left', keys)
  176. } else if (e.key === 'ArrowRight') {
  177. _this.setKeyupData({target: {id: key}}, 'right', keys)
  178. }
  179. }, {
  180. capture: true
  181. });
  182. }
  183. }
  184. //计算上下左右快捷键的
  185. static setKeyupData({target}, type, keys) {
  186. const key = target.id
  187. //处理快捷键数据和事件
  188. if (key && type && isArray(keys)) {
  189. //计算当前的位置
  190. let left = -1, top = -1;
  191. for (let i = 0; i < keys.length; i++) {
  192. if (isArray(keys[i])) {
  193. const index = keys[i].findIndex(id => id === key)
  194. if (index !== -1) {
  195. left = index
  196. top = i
  197. break;
  198. }
  199. }
  200. }
  201. if (type === 'up') {
  202. //向上移动
  203. if (top > 0) {
  204. let keyId = '';
  205. const tops = keys[top - 1]
  206. const keyLength = tops.length - 1;
  207. if (keyLength < left) {
  208. keyId = tops[keyLength]
  209. } else {
  210. keyId = tops[left]
  211. }
  212. this.setElementFocus(keyId)
  213. }
  214. } else if (type === 'down') {
  215. //向下移动
  216. const tops = keys.length - 1;
  217. if (tops > top) {
  218. let keyId = '';
  219. const tops = keys[top + 1]
  220. const keyLength = tops.length - 1;
  221. if (keyLength < left) {
  222. keyId = tops[keyLength]
  223. } else {
  224. keyId = tops[left]
  225. }
  226. this.setElementFocus(keyId)
  227. }
  228. } else if (type === 'left') {
  229. //向左移动
  230. if (left > 0) {
  231. const keyId = keys[top][left - 1]
  232. this.setElementFocus(keyId)
  233. }
  234. } else if (type === 'right') {
  235. //向右移动
  236. const lefts = keys[top]
  237. const leftLength = lefts.length - 1;
  238. if (leftLength > left) {
  239. const keyId = lefts[left + 1]
  240. this.setElementFocus(keyId)
  241. }
  242. }
  243. }
  244. }
  245. //设置元素焦点
  246. static setElementFocus(keyId) {
  247. if (keyId) {
  248. try {
  249. document.getElementById(keyId).focus();
  250. } catch {
  251. }
  252. }
  253. }
  254. //设置表单样式
  255. static setFormStyle(key, name = 'hc-red-border', add = false) {
  256. const dom = document.getElementById(key)
  257. let parent = dom?.parentElement ?? ''
  258. if (dom.tagName === 'INPUT') {
  259. parent = parent?.parentElement ?? ''
  260. this.setFormClass(parent, name, add)
  261. } else if (dom.tagName === 'TEXTAREA') {
  262. this.setFormClass(dom, name, add)
  263. }
  264. }
  265. static setFormClass(dom, name = 'hc-red-border', add = false) {
  266. const classStr = dom.getAttribute('class')
  267. const classArr = classStr.split(' ')
  268. const index = classArr.indexOf(name)
  269. if (index === -1 && add) {
  270. classArr.push(name)
  271. } else if (index !== -1 && add === false) {
  272. classArr.splice(index, 1)
  273. }
  274. dom.setAttribute('class', classArr.join(' '))
  275. }
  276. //设置选中样式
  277. static setCheckKeyStyle(key, remove = false) {
  278. if (remove) {
  279. this.setFormStyle(key, 'hc-green-border')
  280. } else {
  281. this.setFormStyle(key, 'hc-green-border', true)
  282. }
  283. }
  284. }