form-item.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. import XEUtils from 'xe-utils/ctor'
  2. import VXETable from '../../v-x-e-table'
  3. import { UtilTools } from '../../tools'
  4. import GlobalConfig from '../../conf'
  5. function renderPrefixIcon (h, titlePrefix) {
  6. return h('span', {
  7. class: 'vxe-form--item-title-prefix'
  8. }, [
  9. h('i', {
  10. class: titlePrefix.icon || GlobalConfig.icon.FORM_PREFIX
  11. })
  12. ])
  13. }
  14. function renderSuffixIcon (h, titleSuffix) {
  15. return h('span', {
  16. class: 'vxe-form--item-title-suffix'
  17. }, [
  18. h('i', {
  19. class: titleSuffix.icon || GlobalConfig.icon.FORM_SUFFIX
  20. })
  21. ])
  22. }
  23. function renderTitle (h, _vm) {
  24. const { title, titlePrefix, titleSuffix } = _vm
  25. const titles = []
  26. if (titlePrefix) {
  27. titles.push(
  28. (titlePrefix.content || titlePrefix.message)
  29. ? h('vxe-tooltip', {
  30. props: {
  31. content: UtilTools.getFuncText(titlePrefix.content || titlePrefix.message),
  32. enterable: titlePrefix.enterable,
  33. theme: titlePrefix.theme
  34. }
  35. }, [
  36. renderPrefixIcon(h, titlePrefix)
  37. ])
  38. : renderPrefixIcon(h, titlePrefix)
  39. )
  40. }
  41. titles.push(
  42. h('span', {
  43. class: 'vxe-form--item-title-label'
  44. }, UtilTools.getFuncText(title))
  45. )
  46. if (titleSuffix) {
  47. titles.push(
  48. (titleSuffix.content || titleSuffix.message)
  49. ? h('vxe-tooltip', {
  50. props: {
  51. content: UtilTools.getFuncText(titleSuffix.content || titleSuffix.message),
  52. enterable: titleSuffix.enterable,
  53. theme: titleSuffix.theme
  54. }
  55. }, [
  56. renderSuffixIcon(h, titleSuffix)
  57. ])
  58. : renderSuffixIcon(h, titleSuffix)
  59. )
  60. }
  61. return titles
  62. }
  63. export default {
  64. name: 'VxeFormItem',
  65. props: {
  66. title: String,
  67. field: String,
  68. size: String,
  69. span: [String, Number],
  70. align: String,
  71. titleAlign: String,
  72. titleWidth: [String, Number],
  73. className: [String, Function],
  74. titleOverflow: { type: [Boolean, String], default: null },
  75. titlePrefix: Object,
  76. titleSuffix: Object,
  77. resetValue: { default: null },
  78. visible: { type: Boolean, default: null },
  79. visibleMethod: Function,
  80. folding: Boolean,
  81. collapseNode: Boolean,
  82. itemRender: Object
  83. },
  84. inject: {
  85. $vxeform: {
  86. default: null
  87. }
  88. },
  89. data () {
  90. return {
  91. showError: false,
  92. showRule: null
  93. }
  94. },
  95. computed: {
  96. vSize () {
  97. return this.size || this.$parent.size || this.$parent.vSize
  98. },
  99. isRequired () {
  100. const { $vxeform, field } = this
  101. if ($vxeform && $vxeform.rules) {
  102. const rules = $vxeform.rules[field]
  103. if (rules) {
  104. return rules.some(rule => rule.required)
  105. }
  106. }
  107. return false
  108. },
  109. errRule () {
  110. const { $vxeform, field } = this
  111. if ($vxeform) {
  112. return XEUtils.find($vxeform.invalids, ({ property }) => field === property)
  113. }
  114. return null
  115. }
  116. },
  117. watch: {
  118. errRule (value) {
  119. clearTimeout(this.showErrTimeout)
  120. this.showError = false
  121. if (value) {
  122. this.showRule = value.rule
  123. setTimeout(() => {
  124. this.showError = true
  125. }, 30)
  126. } else {
  127. this.showErrTimeout = setTimeout(() => {
  128. this.showRule = null
  129. }, 350)
  130. }
  131. }
  132. },
  133. render (h) {
  134. const { _e, $scopedSlots, $vxeform, title, folding, visible, visibleMethod, field, className, collapseNode, itemRender, isRequired, showError, showRule, titleOverflow } = this
  135. const compConf = itemRender ? VXETable.renderer.get(itemRender.name) : null
  136. const span = this.span || $vxeform.span
  137. const align = this.align || $vxeform.align
  138. const titleAlign = this.titleAlign || $vxeform.titleAlign
  139. const titleWidth = this.titleWidth || $vxeform.titleWidth
  140. const collapseAll = $vxeform.collapseAll
  141. let itemVisibleMethod = visibleMethod
  142. const itemOverflow = (XEUtils.isUndefined(titleOverflow) || XEUtils.isNull(titleOverflow)) ? $vxeform.titleOverflow : titleOverflow
  143. const showEllipsis = itemOverflow === 'ellipsis'
  144. const showTitle = itemOverflow === 'title'
  145. const showTooltip = itemOverflow === true || itemOverflow === 'tooltip'
  146. const hasEllipsis = showTitle || showTooltip || showEllipsis
  147. const params = { data: $vxeform.data, property: field, item: this, $form: $vxeform }
  148. if (visible === false) {
  149. return _e()
  150. }
  151. if (!itemVisibleMethod && compConf && compConf.itemVisibleMethod) {
  152. itemVisibleMethod = compConf.itemVisibleMethod
  153. }
  154. let contentVNs = []
  155. if (compConf && compConf.renderItemContent) {
  156. contentVNs = compConf.renderItemContent.call(this, h, itemRender, params)
  157. } else if (compConf && compConf.renderItem) {
  158. // 在 v4 中废弃 renderItem
  159. UtilTools.warn('vxe.error.delFunc', ['renderItem', 'renderItemContent'])
  160. contentVNs = compConf.renderItem.call(this, h, itemRender, params)
  161. } else if ($scopedSlots && $scopedSlots.default) {
  162. contentVNs = $scopedSlots.default.call(this, params, h)
  163. } else if (field) {
  164. contentVNs = [`${XEUtils.get($vxeform.data, field)}`]
  165. }
  166. const ons = showTooltip && $vxeform ? {
  167. mouseenter (evnt) {
  168. $vxeform.triggerHeaderHelpEvent(evnt, params)
  169. },
  170. mouseleave: $vxeform.handleTargetLeaveEvent
  171. } : {}
  172. return h('div', {
  173. class: ['vxe-form--item', span ? `vxe-col--${span} is--span` : null, className, {
  174. 'is--title': title,
  175. 'is--required': isRequired,
  176. 'is--hidden': folding && collapseAll,
  177. 'is--active': !itemVisibleMethod || itemVisibleMethod(params),
  178. 'is--error': showError
  179. }]
  180. }, [
  181. h('div', {
  182. class: 'vxe-form--item-inner'
  183. }, [
  184. title ? h('div', {
  185. class: ['vxe-form--item-title', titleAlign ? `align--${titleAlign}` : null, {
  186. 'is--ellipsis': hasEllipsis
  187. }],
  188. style: titleWidth ? {
  189. width: isNaN(titleWidth) ? titleWidth : `${titleWidth}px`
  190. } : null,
  191. attrs: {
  192. title: showTitle ? UtilTools.getFuncText(title) : null
  193. },
  194. on: ons
  195. }, renderTitle(h, this)) : null,
  196. h('div', {
  197. class: ['vxe-form--item-content', align ? `align--${align}` : null]
  198. }, contentVNs.concat(
  199. [
  200. collapseNode ? h('div', {
  201. class: 'vxe-form--item-trigger-node',
  202. on: {
  203. click: this.toggleCollapseEvent
  204. }
  205. }, [
  206. h('span', {
  207. class: 'vxe-form--item-trigger-text'
  208. }, collapseAll ? GlobalConfig.i18n('vxe.form.unfolding') : GlobalConfig.i18n('vxe.form.folding')),
  209. h('i', {
  210. class: ['vxe-form--item-trigger-icon', collapseAll ? GlobalConfig.icon.FORM_FOLDING : GlobalConfig.icon.FORM_UNFOLDING]
  211. })
  212. ]) : null,
  213. showRule && $vxeform.validOpts.showMessage ? h('div', {
  214. class: 'vxe-form--item-valid',
  215. style: showRule.maxWidth ? {
  216. width: `${showRule.maxWidth}px`
  217. } : null
  218. }, showRule.message) : null
  219. ])
  220. )
  221. ])
  222. ])
  223. },
  224. methods: {
  225. toggleCollapseEvent (evnt) {
  226. const $form = this.$vxeform
  227. $form.toggleCollapse()
  228. $form.$emit('toggle-collapse', { collapse: !$form.collapseAll, data: $form.data, $form, $event: evnt }, evnt)
  229. }
  230. }
  231. }