SelectClassByCourse.vue 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <template>
  2. <el-dialog
  3. :visible.sync="modalIsShow"
  4. append-to-body
  5. top="20px"
  6. width="900px"
  7. title="选择班级"
  8. :close-on-click-modal="false"
  9. :close-on-press-escape="false"
  10. :show-close="false"
  11. @opened="visibleChange"
  12. >
  13. <el-row :gutter="20">
  14. <el-col :span="12">
  15. <div class="class-part-title">班级列表</div>
  16. <div class="class-part-filter">
  17. <el-input
  18. v-model.trim="filterLabel"
  19. placeholder="请输入班级名称"
  20. clearable
  21. size="mini"
  22. prefix-icon="el-icon-search"
  23. @input="labelChange"
  24. ></el-input>
  25. </div>
  26. <div class="class-part-body">
  27. <el-checkbox-group
  28. v-model="classIds"
  29. class="block-checkbox-group"
  30. @change="classChange"
  31. >
  32. <div v-for="item in classDataList" :key="item.id">
  33. <el-checkbox :label="item.name" :disabled="item.disabled">{{
  34. item.name
  35. }}</el-checkbox>
  36. </div>
  37. </el-checkbox-group>
  38. </div>
  39. </el-col>
  40. <el-col :span="12">
  41. <div class="class-part-title">已选班级</div>
  42. <div class="class-part-body">
  43. <el-tag
  44. v-for="item in classIds"
  45. :key="item"
  46. class="tag-spin tag-wrap"
  47. style="display: block"
  48. size="medium"
  49. >{{ item }}</el-tag
  50. >
  51. </div>
  52. </el-col>
  53. </el-row>
  54. <div slot="footer">
  55. <el-button type="primary" @click="confirm">确认</el-button>
  56. <el-button @click="cancel">取消</el-button>
  57. </div>
  58. </el-dialog>
  59. </template>
  60. <script>
  61. export default {
  62. name: "select-class-by-course",
  63. props: {
  64. classList: {
  65. type: Array,
  66. default() {
  67. return [];
  68. },
  69. },
  70. selectedIds: {
  71. type: Array,
  72. default() {
  73. return [];
  74. },
  75. },
  76. disableIds: {
  77. type: Array,
  78. default() {
  79. return [];
  80. },
  81. },
  82. required: {
  83. type: Boolean,
  84. default: false,
  85. },
  86. },
  87. data() {
  88. return {
  89. modalIsShow: false,
  90. dataList: [],
  91. classDataList: [],
  92. classIds: [],
  93. filterLabel: "",
  94. };
  95. },
  96. methods: {
  97. visibleChange() {
  98. this.classIds = [...this.selectedIds];
  99. this.dataList = this.classList.map((item) => {
  100. return {
  101. id: item,
  102. name: item,
  103. disabled: false,
  104. };
  105. });
  106. this.dataList.forEach((item) => {
  107. item.disabled = this.disableIds.includes(item.id);
  108. });
  109. this.classDataList = this.dataList;
  110. },
  111. labelChange() {
  112. if (!this.filterLabel) {
  113. this.classDataList = this.dataList;
  114. return;
  115. }
  116. const escapeRegexpString = (value = "") =>
  117. String(value).replace(/[|\\{}()[\]^$+*?.]/g, "\\$&");
  118. const reg = new RegExp(escapeRegexpString(this.filterLabel), "i");
  119. this.classDataList = this.dataList.filter((item) => reg.test(item.name));
  120. },
  121. cancel() {
  122. this.modalIsShow = false;
  123. },
  124. open() {
  125. this.modalIsShow = true;
  126. },
  127. classChange() {
  128. this.$emit("change", this.classIds);
  129. },
  130. // confirm
  131. confirm() {
  132. if (this.required && !this.classIds.length) {
  133. this.$message.error("请选择班级");
  134. return;
  135. }
  136. this.$emit("confirm", this.classIds);
  137. this.cancel();
  138. },
  139. },
  140. };
  141. </script>
  142. <style lang="scss" scoped>
  143. .class-part {
  144. &-title {
  145. height: 28px;
  146. line-height: 26px;
  147. border-radius: 5px;
  148. background-color: #f0f0f0;
  149. border: 1px solid #e0e0e0;
  150. text-align: center;
  151. margin-bottom: 5px;
  152. }
  153. &-body {
  154. height: 400px;
  155. overflow-y: auto;
  156. border: 1px solid #e0e0e0;
  157. padding: 5px 10px;
  158. border-radius: 3px;
  159. }
  160. &-filter {
  161. height: 28px;
  162. margin-bottom: 5px;
  163. + .class-part-body {
  164. height: 367px;
  165. }
  166. }
  167. }
  168. </style>