当前位置:   article > 正文

Element UI Table实现可编辑表格+校验(行和行,列和列)_element table 可编辑

element table 可编辑

Table:

  1. <template>
  2. <div class="as-details-section">
  3. <span class="title">任务分解表</span>
  4. <div class="as-detail-list">
  5. <el-table
  6. :data="tableData"
  7. :row-key="getRowKeys"
  8. border
  9. style="width: 100%">
  10. <el-table-column
  11. prop="stageName"
  12. label="阶段"
  13. width="120">
  14. </el-table-column>
  15. <el-table-column
  16. prop="taskName"
  17. label="任务"
  18. width="190">
  19. </el-table-column>
  20. <el-table-column
  21. prop="planStartTime"
  22. label="计划开始时间"
  23. className="editable"
  24. width="120">
  25. <template slot-scope="{ row, column, $index }">
  26. <table-date-picker
  27. v-if="row.isTask && !row.isDisabled"
  28. v-model="row.planStartTime"
  29. :valueValid="row.planStartTimeValid"
  30. :valueEmpty="row.planStartTimeEmpty"
  31. @change="change(row, column, $index)"
  32. @blur="onBlur(row, column)">
  33. </table-date-picker>
  34. <span v-else class="cell-value">{{row.planStartTime | dateFormat}}</span>
  35. </template>
  36. </el-table-column>
  37. <el-table-column
  38. prop="planEndTime"
  39. label="计划结束时间"
  40. className="editable"
  41. width="120">
  42. <template slot-scope="{ row, column, $index }">
  43. <table-date-picker
  44. v-if="row.isTask && !row.isDisabled"
  45. v-model="row.planEndTime"
  46. :valueValid="row.planEndTimeValid"
  47. :valueEmpty="row.planEndTimeEmpty"
  48. isEndDate
  49. @change="change(row, column, $index)"
  50. @blur="onBlur(row, column)">
  51. </table-date-picker>
  52. <span v-else class="cell-value">{{row.planEndTime | dateFormat}}</span>
  53. </template>
  54. </el-table-column>
  55. <el-table-column
  56. prop="actualStartTime"
  57. label="实际开始"
  58. className="editable"
  59. width="120">
  60. <template slot-scope="{ row, column, $index }">
  61. <table-date-picker
  62. v-if="row.isTask && !row.isDisabled"
  63. v-model="row.actualStartTime"
  64. :valueValid="row.actualStartTimeValid"
  65. :valueEmpty="row.actualStartTimeEmpty"
  66. :disabled="row.isActualDisabled"
  67. :pickerOptions="pickerOptions"
  68. @change="changeRealDate(row, column, $index)">
  69. </table-date-picker>
  70. <span v-else class="cell-value">{{row.actualStartTime | dateFormat}}</span>
  71. </template>
  72. </el-table-column>
  73. <el-table-column
  74. prop="actualEndTime"
  75. label="实际结束"
  76. className="editable"
  77. width="120">
  78. <template slot-scope="{ row, column, $index }">
  79. <table-date-picker
  80. v-if="row.isTask && !row.isDisabled"
  81. v-model="row.actualEndTime"
  82. :valueValid="row.actualEndTimeValid"
  83. :valueEmpty="row.actualEndTimeEmpty"
  84. :disabled="row.isActualDisabled"
  85. :pickerOptions="pickerOptions"
  86. isEndDate
  87. @change="changeRealDate(row, column, $index)">
  88. </table-date-picker>
  89. <span v-else class="cell-value">{{row.actualEndTime | dateFormat}}</span>
  90. </template>
  91. </el-table-column>
  92. <el-table-column
  93. prop="projectWbsTaskResourceList"
  94. label="资源及投入比例"
  95. min-width="200">
  96. <template slot-scope="{ row, column, $index }">
  97. <table-person-picker
  98. v-if="row.isTask && !row.isDisabled"
  99. v-model="row.projectWbsTaskResourceList"
  100. :projectWbsTrackId="row.id"
  101. :valueEmpty="row.projectWbsTaskResourceListEmpty"
  102. @change="percentChange(row, column, $index)"
  103. @blur="onBlur(row, column)"
  104. ></table-person-picker>
  105. <span v-else class="cell-value">{{ resourceFormat(row.projectWbsTaskResourceList) }}</span>
  106. </template>
  107. </el-table-column>
  108. <el-table-column
  109. prop="planWorkHour"
  110. label="预计工时(天)"
  111. width="120">
  112. </el-table-column>
  113. <el-table-column
  114. prop="actualWorkHour"
  115. label="实际工时(天)"
  116. width="120">
  117. </el-table-column>
  118. <el-table-column
  119. prop="planWorkDay"
  120. label="预计工期(天)"
  121. width="120">
  122. </el-table-column>
  123. <el-table-column
  124. prop="actualWorkDay"
  125. label="实际工期(天)"
  126. width="120">
  127. </el-table-column>
  128. </el-table>
  129. </div>
  130. <el-dialog
  131. title="流转确认"
  132. :visible.sync="dialogVisible"
  133. :close-on-click-modal="false"
  134. width="400px">
  135. <el-row v-if="!isShowRollback">确认要流转至下一阶段吗?</el-row>
  136. <el-row v-else>确认要流转至下一阶段吗?</el-row>
  137. <span slot="footer" class="dialog-footer">
  138. <el-button v-if="!isShowRollback" @click="dialogVisible = false">取 消</el-button>
  139. <el-button v-if="isShowRollback" @click="promoteProject(true)">回滚至2</el-button>
  140. <el-button type="primary" @click="promoteProject()">确 定</el-button>
  141. </span>
  142. </el-dialog>
  143. </div>
  144. </template>

TablePersonPicker:

  1. <template>
  2. <div class="table-date-picker">
  3. <div class="cell-content-wrap">
  4. <span class="cell-content">{{displayValue}}</span>
  5. <i
  6. class="el-icon-edit-outline"
  7. style="float: right"
  8. ></i>
  9. </div>
  10. </div>
  11. </template>
  12. <script>
  13. import TablePersonPickerDialog from '@/components/projectManagement/TablePersonPickerDialog'
  14. export default {
  15. name: 'TablePersonPicker',
  16. model: {
  17. prop: 'value',
  18. event: 'change'
  19. },
  20. props: {
  21. value: {
  22. type: Array,
  23. default() {
  24. return [];
  25. }
  26. },
  27. valueValid: {
  28. type: Boolean,
  29. default() {
  30. return true;
  31. }
  32. },
  33. valueEmpty: {
  34. type: Boolean,
  35. default() {
  36. return false;
  37. }
  38. },
  39. disabled: {
  40. type: Boolean,
  41. default() {
  42. return false;
  43. }
  44. },
  45. projectWbsTrackId: {
  46. type: String,
  47. default() {
  48. return null;
  49. }
  50. }
  51. },
  52. data() {
  53. return {
  54. newValue: [],
  55. displayValue: '',
  56. pencentArr: []
  57. };
  58. },
  59. mounted() {
  60. // 点击表格td,编辑状态,输入框获取焦点
  61. this.$el.parentNode.parentNode.onclick = () => {
  62. if (!this.disabled) {
  63. this.showDialog();
  64. }
  65. }
  66. },
  67. methods: {
  68. showDialog() {
  69. this.$utils.create(TablePersonPickerDialog, {
  70. context: this,
  71. keyName: this.id,
  72. deliveryDept: this.options,
  73. value: this.value
  74. });
  75. },
  76. confirm(data) {
  77. this.pencentArr = data;
  78. this.displayValue = this.formatDisaplyValue();
  79. this.$emit('change', this.pencentArr);
  80. },
  81. getItemById(personId) {
  82. let item = null;
  83. // 新增人员
  84. for (const obj of this.data) {
  85. if (obj.personId === personId) {
  86. item = obj;
  87. break;
  88. }
  89. }
  90. return item;
  91. },
  92. formatDisaplyValue() {
  93. const displayArr = [];
  94. for (const item of this.pencentArr) {
  95. displayArr.push(`${item.personLabel}(${item.inputPercentage}%)`)
  96. }
  97. return displayArr.join(',');
  98. },
  99. formatOptions() {
  100. const optons = [];
  101. let option = null;
  102. for (const item of this.$store.state.DICT_DATA.delivery_dept) {
  103. option = {
  104. id: item.dictValue,
  105. personLabel: item.dictName,
  106. disabled: true
  107. };
  108. optons.push(option);
  109. }
  110. return optons;
  111. }
  112. },
  113. created() {
  114. this.options = this.formatOptions();
  115. let template = null;
  116. for (const item of this.value) {
  117. this.newValue.push(item.personId);
  118. template = {
  119. personId: item.personId,
  120. projectWbsTrackId: this.projectWbsTrackId,
  121. inputPercentage: item.inputPercentage,
  122. personLabel: item.personLabel
  123. };
  124. this.pencentArr.push(template);
  125. }
  126. this.displayValue = this.formatDisaplyValue();
  127. },
  128. watch: {
  129. valueEmpty() {
  130. if (this.valueEmpty) {
  131. this.$el.parentNode.parentNode.style.background = '#FEF0F0';
  132. } else {
  133. this.$el.parentNode.parentNode.style.background = 'none';
  134. }
  135. },
  136. valueValid() {
  137. if (!this.valueValid) {
  138. this.$el.parentNode.parentNode.style.background = '#FEF0F0';
  139. } else {
  140. this.$el.parentNode.parentNode.style.background = 'none';
  141. }
  142. }
  143. }
  144. };
  145. </script>
  146. <style scoped lang="scss">
  147. .table-date-picker {
  148. display: flex;
  149. flex-flow: row;
  150. align-items: center;
  151. .cell-content-wrap {
  152. display: flex;
  153. flex-flow: row;
  154. align-items: center;
  155. i {
  156. color: #20a0ff;
  157. margin-left: 8px;
  158. cursor: pointer;
  159. }
  160. }
  161. .cell-content {
  162. padding: 0 8px;
  163. flex: 1;
  164. }
  165. }
  166. </style>

输入校验:

  1. /**
  2. * 表格预计开始时间和预计结束时间注册事件
  3. */
  4. change(row, column, $index) {
  5. const { property } = column;
  6. const value = row[property];
  7. if ((!value || value === '') && value !== 0) {
  8. row[`${property}Empty`] = true;
  9. } else {
  10. row[`${property}Empty`] = false;
  11. // 时间发生变化,往下开始计算时间
  12. this.calculatePlanDate(row, column, $index);
  13. // 计算预计工时和预计工期
  14. this.caculatePlanData();
  15. // 任务预计开始时间小于任务结束时间
  16. const isValid = this.validateDate(row.planStartTime, row.planEndTime);
  17. if (!isValid) {
  18. this.$message.error('预计结束时间必须大于等于预计开始时间!');
  19. }
  20. // 任务的预计开始时间大于上一个阶段的结束时间
  21. const isStartDateValid = this.validateTaskStartDate(row, property, $index);
  22. if (!isStartDateValid) {
  23. this.$message.error('任务的预计开始时间和预计结束时间必须大于上一个阶段的预计结束时间');
  24. }
  25. if (isValid && isStartDateValid) {
  26. row[`${property}Valid`] = true;
  27. } else {
  28. row[`${property}Valid`] = false;
  29. }
  30. this.$set(this.tableData, $index, Object.assign({}, row));
  31. }
  32. },

效果图:

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/201161
推荐阅读
相关标签
  

闽ICP备14008679号