HTableForm.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  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. setTimeout(() => {
  61. const KeyName = event?.target?.getAttribute('keyname') || ''
  62. if (onRight) {
  63. onRight(event, KeyName)
  64. }
  65. }, 100)
  66. },
  67. //焦点事件
  68. getInformation() {
  69. },
  70. //日期选择事件
  71. datePickerChange(val, key) {
  72. this.formData[key] = val
  73. },
  74. //上传完成
  75. formUploadSuccess({src, key}) {
  76. this.formData[key] = src
  77. },
  78. //删除上传的文件
  79. delTableFormFile(key) {
  80. this.formData[key] = ''
  81. },
  82. //失去焦点事件
  83. getRegularExpression(event, reg, msg, a, b, leng) {
  84. const KeyName = event?.target?.getAttribute('keyname') || ''
  85. if (onBlur) {
  86. onBlur(event, KeyName, reg, this.formData[KeyName], msg, leng)
  87. }
  88. },
  89. //远程搜索处理
  90. formRemoteChange(data) {
  91. Object.keys(data).forEach(key => {
  92. this.formData[key] = data[key]
  93. })
  94. },
  95. //多选框处理
  96. checkboxGroupChange({key, val}) {
  97. this.formData[key] = val
  98. },
  99. //键盘事件 上键
  100. keyupShiftUp(event) {
  101. _this.setKeyupData(event, 'up', keys)
  102. },
  103. //键盘事件 下键
  104. keyupShiftDown(event) {
  105. _this.setKeyupData(event, 'down', keys)
  106. },
  107. //键盘事件 左键
  108. keyupShiftLeft(event) {
  109. _this.setKeyupData(event, 'left', keys)
  110. },
  111. //键盘事件 右键
  112. keyupShiftRight(event) {
  113. _this.setKeyupData(event, 'right', keys)
  114. },
  115. //日期时间框键盘事件
  116. dateKeydown({type, name}) {
  117. _this.setKeyupData(name, type, keys)
  118. },
  119. //输入左键点击事件
  120. inputLeftClick(event, key) {
  121. if (onLeftClick) {
  122. onLeftClick(key)
  123. }
  124. },
  125. }
  126. })
  127. app.mount(appId)
  128. return app
  129. }
  130. //处理日期范围数据
  131. static setPickerKey(data) {
  132. const pickerKey = data['pickerKey'] || ''
  133. if (pickerKey) {
  134. const pickerKeys = pickerKey.split(',')
  135. for (let i = 0; i < pickerKeys.length; i++) {
  136. const val = data[pickerKeys[i]] || ''
  137. if (val) {
  138. const dataVal = val.replace(/'/g, '"');
  139. data[pickerKeys[i]] = toParse(dataVal) || []
  140. } else {
  141. data[pickerKeys[i]] = []
  142. }
  143. }
  144. }
  145. return data
  146. }
  147. //处理日期时间框的切换事件
  148. static setByClassKeyup(keys) {
  149. try {
  150. let poppers = document.getElementsByClassName('hc-table-form-date-picker')
  151. for (let i = 0; i < poppers.length; i++) {
  152. let item = poppers[i], key = '';
  153. const ids = item.getAttribute('class').split('-form-id-')
  154. if (ids.length >= 1) {
  155. key = ids[1]
  156. }
  157. if (ids) {
  158. let panels = item.getElementsByClassName('el-picker-panel__content')
  159. this.setElementsEvent(panels, key, keys)
  160. }
  161. }
  162. } catch (e) {
  163. console.log(e)
  164. }
  165. }
  166. //设置事件
  167. static setElementsEvent(elements, key, keys) {
  168. if (elements.length > 0) {
  169. const _this = this;
  170. elements[0].addEventListener("keydown", e => {
  171. e.stopPropagation()
  172. if (e.key === 'ArrowUp') {
  173. _this.setKeyupData({target: {id: key}}, 'up', keys)
  174. } else if (e.key === 'ArrowDown') {
  175. _this.setKeyupData({target: {id: key}}, 'down', keys)
  176. } else if (e.key === 'ArrowLeft') {
  177. _this.setKeyupData({target: {id: key}}, 'left', keys)
  178. } else if (e.key === 'ArrowRight') {
  179. _this.setKeyupData({target: {id: key}}, 'right', keys)
  180. }
  181. }, {
  182. capture: true
  183. });
  184. }
  185. }
  186. //计算上下左右快捷键的
  187. static setKeyupData({target}, type, keys) {
  188. const key = target.id
  189. //处理快捷键数据和事件
  190. if (key && type && isArray(keys)) {
  191. //计算当前的位置
  192. let left = -1, top = -1;
  193. for (let i = 0; i < keys.length; i++) {
  194. if (isArray(keys[i])) {
  195. const index = keys[i].findIndex(id => id === key)
  196. if (index !== -1) {
  197. left = index
  198. top = i
  199. break;
  200. }
  201. }
  202. }
  203. if (type === 'up') {
  204. //向上移动
  205. if (top > 0) {
  206. let keyId = '';
  207. const tops = keys[top - 1]
  208. const keyLength = tops.length - 1;
  209. if (keyLength < left) {
  210. keyId = tops[keyLength]
  211. } else {
  212. keyId = tops[left]
  213. }
  214. this.setElementFocus(keyId)
  215. }
  216. } else if (type === 'down') {
  217. //向下移动
  218. const tops = keys.length - 1;
  219. if (tops > top) {
  220. let keyId = '';
  221. const tops = keys[top + 1]
  222. const keyLength = tops.length - 1;
  223. if (keyLength < left) {
  224. keyId = tops[keyLength]
  225. } else {
  226. keyId = tops[left]
  227. }
  228. this.setElementFocus(keyId)
  229. }
  230. } else if (type === 'left') {
  231. //向左移动
  232. if (left > 0) {
  233. const keyId = keys[top][left - 1]
  234. this.setElementFocus(keyId)
  235. }
  236. } else if (type === 'right') {
  237. //向右移动
  238. const lefts = keys[top]
  239. const leftLength = lefts.length - 1;
  240. if (leftLength > left) {
  241. const keyId = lefts[left + 1]
  242. this.setElementFocus(keyId)
  243. }
  244. }
  245. }
  246. }
  247. //设置元素焦点
  248. static setElementFocus(keyId) {
  249. if (keyId) {
  250. try {
  251. document.getElementById(keyId).focus();
  252. } catch {
  253. }
  254. }
  255. }
  256. //设置表单样式
  257. static setFormStyle(key, name = 'hc-red-border', add = false) {
  258. const dom = document.getElementById(key)
  259. let parent = dom?.parentElement ?? ''
  260. if (dom.tagName === 'INPUT') {
  261. parent = parent?.parentElement ?? ''
  262. this.setFormClass(parent, name, add)
  263. } else if (dom.tagName === 'TEXTAREA') {
  264. this.setFormClass(dom, name, add)
  265. }
  266. }
  267. static setFormClass(dom, name = 'hc-red-border', add = false) {
  268. const classStr = dom.getAttribute('class')
  269. const classArr = classStr.split(' ')
  270. const index = classArr.indexOf(name)
  271. if (index === -1 && add) {
  272. classArr.push(name)
  273. } else if (index !== -1 && add === false) {
  274. classArr.splice(index, 1)
  275. }
  276. dom.setAttribute('class', classArr.join(' '))
  277. }
  278. //设置选中样式
  279. static setCheckKeyStyle(key, remove = false) {
  280. if (remove) {
  281. this.setFormStyle(key, 'hc-green-border')
  282. } else {
  283. this.setFormStyle(key, 'hc-green-border', true)
  284. }
  285. }
  286. }