WidgetTable.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <template>
  2. <div
  3. class="widget-table widget-view"
  4. :class="{
  5. active: selectWidget.key && selectWidget.key == element.key,
  6. 'is_hidden': element.options.hidden,
  7. 'mobile': platform == 'mobile'
  8. }"
  9. @click.stop="handleSelectWidget(index)"
  10. @mouseover.stop="handleMouseover"
  11. @mouseout="handleMouseout"
  12. ref="widgetTable"
  13. >
  14. <el-form-item
  15. :label="element.options.hideLabel ? '' : element.name"
  16. :label-width="element.options.hideLabel ? '0px' : (element.options.isLabelWidth ? element.options.labelWidth + 'px' : '')"
  17. :class="{
  18. [element.options && element.options.customClass]: element.options.customClass?true: false,
  19. 'fm-label-wrap': element.options.labelWrap
  20. }"
  21. >
  22. <div v-if="element.options.tip" class="fm-item-tooltip" v-html="element.options.tip.replace(/\n/g, '<br/>')"></div>
  23. <div class="widget-table-wrapper" :class="{'mobile': platform == 'mobile'}">
  24. <el-table :data="[{}]" class="widget-table-left" :style="{width: widgetTableLeftWidth}" row-class-name="widget-table-row" v-if="platform != 'mobile'">
  25. <el-table-column v-if="element.options.selection"
  26. fixed
  27. type="selection"
  28. width="50">
  29. </el-table-column>
  30. <el-table-column label="#" width="50" fixed v-if="element.options.showControl">
  31. <template slot-scope="scope">{{scope.$index + 1}}</template>
  32. </el-table-column>
  33. </el-table>
  34. <div class="widget-table-top" v-if="platform == 'mobile'">
  35. <el-checkbox v-if="element.options.selection" style="margin-right: 10px;"></el-checkbox>
  36. # 1
  37. </div>
  38. <div class="widget-table-content" :class="{'mobile': platform == 'mobile'}">
  39. <div v-if="element.tableColumns.length == 0" class="table-empty">{{$t('fm.description.tableEmpty')}}</div>
  40. <draggable
  41. v-model="element.tableColumns"
  42. v-bind="{group:{name: 'people', put: handlePut}, ghostClass: 'ghost',animation: 200, handle: '.drag-widget'}"
  43. :no-transition-on-drag="true"
  44. @add="handleWidgetTableAdd($event, element)"
  45. @update="handleWidgetTableUpdate"
  46. @start="setDragging(true)"
  47. @end="setDragging(false)"
  48. >
  49. <transition-group name="fade" tag="div" class="widget-table-col" :style="{width: platform != 'mobile' ? columnsWidthStyle : '100%'}">
  50. <widget-table-item
  51. v-for="(item, index) in element.tableColumns" v-if="item.key"
  52. :key="item.key"
  53. :element="item"
  54. :tableElement="element"
  55. :select.sync="selectWidget"
  56. :index="index" :data="element.tableColumns"
  57. @select-change="handleSelectChange($event, item)"
  58. :platform="platform"
  59. :form-key="formKey"
  60. >
  61. </widget-table-item>
  62. </transition-group>
  63. </draggable>
  64. </div>
  65. </div>
  66. </el-form-item>
  67. <div class="widget-view-action widget-col-action" v-if="selectWidget.key == element.key">
  68. <i class="fm-iconfont icon-icon_clone" @click.stop="handleTableClone(index)" :title="$t('fm.tooltip.clone')"></i>
  69. <i class="fm-iconfont icon-trash" @click.stop="handleWidgetDelete(index)" :title="$t('fm.tooltip.trash')"></i>
  70. </div>
  71. <div class="widget-view-drag widget-col-drag" v-if="selectWidget.key == element.key">
  72. <i class="fm-iconfont icon-drag drag-widget"></i>
  73. </div>
  74. <div class="widget-view-model" :style="{'color': element.options.dataBind ? '' : '#666'}">
  75. <span>{{element.model}}</span>
  76. </div>
  77. <div class="widget-view-type ">
  78. <span>{{element.type ? this.$t('fm.components.fields.' + element.type) : ''}}</span>
  79. </div>
  80. </div>
  81. </template>
  82. <script>
  83. import Draggable from 'vuedraggable'
  84. import WidgetTableItem from './WidgetTableItem'
  85. import _ from 'lodash'
  86. import { CloneLayout } from '../util/layout-clone.js'
  87. import { EventBus } from '../util/event-bus.js'
  88. import { addClass, removeClass } from '../util'
  89. export default {
  90. components: {
  91. Draggable,
  92. WidgetTableItem
  93. },
  94. props: ['element', 'select', 'index', 'data', 'platform', 'formKey'],
  95. inject: ['setDragging', 'getDragging'],
  96. data () {
  97. return {
  98. selectWidget: this.select || {},
  99. columnsWidthStyle: '200px'
  100. }
  101. },
  102. computed: {
  103. widgetTableLeftWidth () {
  104. let width = 1
  105. if (this.element.options.showControl) {
  106. width += 50
  107. }
  108. if (this.element.options.selection) {
  109. width += 50
  110. }
  111. return width + 'px'
  112. }
  113. },
  114. mounted () {
  115. this.calcTableColumnsWidth()
  116. },
  117. methods: {
  118. handleMouseover (e) {
  119. !this.getDragging() && addClass(this.$refs['widgetTable'], 'is-hover')
  120. },
  121. handleMouseout (e) {
  122. removeClass(this.$refs['widgetTable'], 'is-hover')
  123. },
  124. handleSelectWidget (index) {
  125. this.selectWidget = this.data.list[index]
  126. },
  127. handleWidgetDelete (index) {
  128. if (this.data.list.length == 1) {
  129. this.$emit('select-change', -1)
  130. } else {
  131. if (this.data.list.length - 1 == index) {
  132. this.$emit('select-change', index - 1)
  133. } else {
  134. this.$emit('select-change', index)
  135. }
  136. }
  137. this.data.list.splice(index, 1)
  138. setTimeout(() => {
  139. EventBus.$emit('on-history-add-' + this.formKey)
  140. }, 20)
  141. },
  142. handleTableClone (index) {
  143. let cloneData = _.cloneDeep(this.data.list[index])
  144. this.data.list.splice(index + 1, 0, CloneLayout(cloneData))
  145. this.$nextTick(() => {
  146. this.selectWidget = this.data.list[index + 1]
  147. this.$nextTick(() => { EventBus.$emit('on-history-add-' + this.formKey) })
  148. })
  149. },
  150. handleWidgetTableUpdate (evt) {
  151. this.$nextTick(() => { EventBus.$emit('on-history-add-' + this.formKey) })
  152. },
  153. calcTableColumnsWidth () {
  154. // this.columnsWidth = (this.element.tableColumns.length+1)*200
  155. this.columnsWidthStyle = 'calc(200px)'
  156. let widthArray = []
  157. for (let i = 0; i < this.element.tableColumns.length; i++) {
  158. if (!this.element.tableColumns[i].options.width) {
  159. widthArray.push('200px')
  160. } else {
  161. widthArray.push(this.element.tableColumns[i].options.width)
  162. }
  163. }
  164. console.log('calc', widthArray)
  165. widthArray.length && (this.columnsWidthStyle = `calc(200px + ${widthArray.join(' + ')})`)
  166. },
  167. handlePut (a, b, c) {
  168. if (c.className.split(' ').indexOf('widget-col') >=0 ||
  169. c.className.split(' ').indexOf('widget-table') >= 0 ||
  170. c.className.split(' ').indexOf('widget-tab') >= 0 ||
  171. c.className.split(' ').indexOf('widget-report') >= 0 ||
  172. c.className.split(' ').indexOf('widget-inline') >= 0 ||
  173. c.className.split(' ').indexOf('widget-subform') >= 0 ||
  174. c.className.split(' ').indexOf('widget-dialog') >= 0 ||
  175. c.className.split(' ').indexOf('widget-card') >= 0 ||
  176. c.className.split(' ').indexOf('widget-group') >= 0 ||
  177. c.className.split(' ').indexOf('no-put') >= 0 ||
  178. c.children[0].className.split(' ').indexOf('no-put') >= 0) {
  179. return false
  180. }
  181. return true
  182. },
  183. handleWidgetTableAdd ($event, table) {
  184. const newIndex = $event.newIndex
  185. const key = Math.random().toString(36).slice(-8)
  186. this.$set(table.tableColumns, newIndex, _.cloneDeep(table.tableColumns[newIndex]))
  187. this.$set(table.tableColumns, newIndex, {
  188. ...table.tableColumns[newIndex],
  189. options: {
  190. ...table.tableColumns[newIndex].options,
  191. remoteFunc: table.tableColumns[newIndex].options.remoteFunc || 'func_'+key,
  192. remoteOption: table.tableColumns[newIndex].options.remoteOption || 'option_'+key,
  193. tableColumn: true,
  194. subform: this.subform ? true : false
  195. },
  196. novalid: {
  197. ...table.tableColumns[newIndex].novalid,
  198. },
  199. key: table.tableColumns[newIndex].key ? table.tableColumns[newIndex].key : key,
  200. model: table.tableColumns[newIndex].model ? table.tableColumns[newIndex].model : table.tableColumns[newIndex].type + '_' + key,
  201. rules: table.tableColumns[newIndex].rules ? [...table.tableColumns[newIndex].rules] : []
  202. })
  203. this.selectWidget = table.tableColumns[newIndex]
  204. this.$nextTick(() => { EventBus.$emit('on-history-add-' + this.formKey) })
  205. },
  206. handleSelectChange (index, item) {
  207. setTimeout(() => {
  208. index >=0 ? (this.selectWidget = this.element.tableColumns[index]) : (this.selectWidget = this.data.list[this.index])
  209. })
  210. }
  211. },
  212. watch: {
  213. select (val) {
  214. this.selectWidget = val
  215. },
  216. selectWidget: {
  217. deep: false,
  218. handler (val) {
  219. this.$emit('update:select', val)
  220. }
  221. },
  222. element: {
  223. deep: true,
  224. handler (val) {
  225. this.calcTableColumnsWidth()
  226. }
  227. }
  228. }
  229. }
  230. </script>