Showing
4 changed files
with
92 additions
and
16 deletions
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2024-07-12 13:28:27 | 2 | * @Date: 2024-07-12 13:28:27 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-08-01 12:00:57 | 4 | + * @LastEditTime: 2024-08-01 15:48:02 |
| 5 | * @FilePath: /data-table/src/components/TEditor/index.vue | 5 | * @FilePath: /data-table/src/components/TEditor/index.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -12,6 +12,7 @@ | ... | @@ -12,6 +12,7 @@ |
| 12 | v-model="myValue" | 12 | v-model="myValue" |
| 13 | :init="tinymceOptions" | 13 | :init="tinymceOptions" |
| 14 | :id="tinymceId" | 14 | :id="tinymceId" |
| 15 | + @blur="onBlur" | ||
| 15 | ></editor> | 16 | ></editor> |
| 16 | </div> | 17 | </div> |
| 17 | </template> | 18 | </template> |
| ... | @@ -53,7 +54,7 @@ import Editor from "@tinymce/tinymce-vue"; | ... | @@ -53,7 +54,7 @@ import Editor from "@tinymce/tinymce-vue"; |
| 53 | // import "tinymce/plugins/fullscreen"; | 54 | // import "tinymce/plugins/fullscreen"; |
| 54 | 55 | ||
| 55 | 56 | ||
| 56 | -const emits = defineEmits(["update:modelValue", "setHtml"]); | 57 | +const emits = defineEmits(["update:modelValue", "setHtml", "blur"]); |
| 57 | //这里我选择将数据定义在props里面,方便在不同的页面也可以配置出不同的编辑器,当然也可以直接在组件中直接定义 | 58 | //这里我选择将数据定义在props里面,方便在不同的页面也可以配置出不同的编辑器,当然也可以直接在组件中直接定义 |
| 58 | const props = defineProps({ | 59 | const props = defineProps({ |
| 59 | value: { | 60 | value: { |
| ... | @@ -286,6 +287,11 @@ const handleGetContent = () => { | ... | @@ -286,6 +287,11 @@ const handleGetContent = () => { |
| 286 | return tinymce.activeEditor.getContent(); | 287 | return tinymce.activeEditor.getContent(); |
| 287 | }; | 288 | }; |
| 288 | 289 | ||
| 290 | +const onBlur = (e) => { | ||
| 291 | + // console.warn(e); | ||
| 292 | + emits("blur", handleGetContent()); | ||
| 293 | +} | ||
| 294 | + | ||
| 289 | defineExpose({ | 295 | defineExpose({ |
| 290 | handleSetContent, | 296 | handleSetContent, |
| 291 | handleGetContent, | 297 | handleGetContent, | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2022-08-29 14:31:20 | 2 | * @Date: 2022-08-29 14:31:20 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-08-01 13:17:05 | 4 | + * @LastEditTime: 2024-08-01 16:24:00 |
| 5 | * @FilePath: /data-table/src/components/TableField/index.vue | 5 | * @FilePath: /data-table/src/components/TableField/index.vue |
| 6 | * @Description: 文件描述 | 6 | * @Description: 文件描述 |
| 7 | --> | 7 | --> |
| ... | @@ -12,28 +12,37 @@ | ... | @@ -12,28 +12,37 @@ |
| 12 | <span :class="[ReadonlyShow ? 'readonly-show' : '']">{{ item.component_props.label }}</span> | 12 | <span :class="[ReadonlyShow ? 'readonly-show' : '']">{{ item.component_props.label }}</span> |
| 13 | </div> | 13 | </div> |
| 14 | <div class="tinymce-box"> | 14 | <div class="tinymce-box"> |
| 15 | - <TEditor ref="refEdit" ></TEditor> | 15 | + <TEditor ref="refEdit" @blur="onBlur" :readonly="item.component_props.readonly"></TEditor> |
| 16 | - <div @click="getValue">获取内容</div> | ||
| 17 | - <div @click="setValue">设置内容</div> | ||
| 18 | </div> | 16 | </div> |
| 19 | - <div> | 17 | + <!-- <div @click="getValue">获取内容</div> |
| 18 | + <div @click="setValue">设置内容</div> --> | ||
| 19 | + <!-- <div> | ||
| 20 | <div v-html="table_html" class="table-wrapper"></div> | 20 | <div v-html="table_html" class="table-wrapper"></div> |
| 21 | <div @click="setHtml">设置内容</div> | 21 | <div @click="setHtml">设置内容</div> |
| 22 | + </div> --> | ||
| 23 | + <div | ||
| 24 | + v-if="show_empty" | ||
| 25 | + class="van-field__error-message" | ||
| 26 | + style="padding: 1rem" | ||
| 27 | + > | ||
| 28 | + 表格不能为空 | ||
| 22 | </div> | 29 | </div> |
| 23 | </div> | 30 | </div> |
| 24 | </template> | 31 | </template> |
| 25 | 32 | ||
| 26 | <script setup> | 33 | <script setup> |
| 27 | import { useRoute } from "vue-router"; | 34 | import { useRoute } from "vue-router"; |
| 28 | -import { showSuccessToast, showFailToast } from 'vant'; | 35 | +import { showSuccessToast, showFailToast, showToast } from 'vant'; |
| 29 | // 初始化WX环境 | 36 | // 初始化WX环境 |
| 30 | import wx from 'weixin-js-sdk' | 37 | import wx from 'weixin-js-sdk' |
| 38 | +import $ from 'jquery' | ||
| 31 | import TEditor from "@/components/TEditor/index.vue"; | 39 | import TEditor from "@/components/TEditor/index.vue"; |
| 32 | 40 | ||
| 33 | const $route = useRoute(); | 41 | const $route = useRoute(); |
| 34 | const props = defineProps({ | 42 | const props = defineProps({ |
| 35 | item: Object, | 43 | item: Object, |
| 36 | }); | 44 | }); |
| 45 | +const emit = defineEmits(["active"]); | ||
| 37 | 46 | ||
| 38 | // 隐藏显示 | 47 | // 隐藏显示 |
| 39 | const HideShow = computed(() => { | 48 | const HideShow = computed(() => { |
| ... | @@ -46,7 +55,19 @@ const ReadonlyShow = computed(() => { | ... | @@ -46,7 +55,19 @@ const ReadonlyShow = computed(() => { |
| 46 | }); | 55 | }); |
| 47 | 56 | ||
| 48 | onMounted(() => { | 57 | onMounted(() => { |
| 49 | - props.item.value = props.item.component_props.default; | 58 | + $('.tinymce-box').width($('.table-field-page').width() + 'px'); |
| 59 | + // | ||
| 60 | + // table_html.value = props.item.component_props.default; | ||
| 61 | + // | ||
| 62 | + props.item.value = { | ||
| 63 | + key: "table", | ||
| 64 | + filed_name: props.item.key, | ||
| 65 | + value: props.item.component_props.default, | ||
| 66 | + }; | ||
| 67 | + emit("active", props.item.value); | ||
| 68 | + setTimeout(() => { | ||
| 69 | + refEdit.value.handleSetContent(props.item.component_props.default) | ||
| 70 | + }, 1000); | ||
| 50 | }); | 71 | }); |
| 51 | 72 | ||
| 52 | const refEdit = ref(null); | 73 | const refEdit = ref(null); |
| ... | @@ -61,8 +82,18 @@ const setValue = () => { | ... | @@ -61,8 +82,18 @@ const setValue = () => { |
| 61 | } | 82 | } |
| 62 | 83 | ||
| 63 | const table_html = ref(''); | 84 | const table_html = ref(''); |
| 64 | -const setHtml = () => { | 85 | +// const setHtml = () => { |
| 65 | - table_html.value = table | 86 | +// table_html.value = table |
| 87 | +// } | ||
| 88 | + | ||
| 89 | +const onBlur = (html) => { | ||
| 90 | + props.item.value = { | ||
| 91 | + key: "table", | ||
| 92 | + filed_name: props.item.key, | ||
| 93 | + value: html, | ||
| 94 | + }; | ||
| 95 | + emit("active", props.item.value); | ||
| 96 | + table_html.value = html; | ||
| 66 | } | 97 | } |
| 67 | 98 | ||
| 68 | const table = ` | 99 | const table = ` |
| ... | @@ -129,6 +160,24 @@ const table = ` | ... | @@ -129,6 +160,24 @@ const table = ` |
| 129 | </tbody> | 160 | </tbody> |
| 130 | </table> | 161 | </table> |
| 131 | ` | 162 | ` |
| 163 | +const show_empty = ref(false); | ||
| 164 | +// 校验模块 | ||
| 165 | +const validTableEditor = () => { | ||
| 166 | + if (props.item.component_props.disabled) { // 通过规则隐藏的属性,不校验 | ||
| 167 | + show_empty.value = false; | ||
| 168 | + } else { | ||
| 169 | + // 必填项 未上传文件 | ||
| 170 | + if (props.item.component_props.required && !refEdit.value.handleGetContent()) { | ||
| 171 | + show_empty.value = true; | ||
| 172 | + showToast(props.item.component_props.label + "必填项未填写"); | ||
| 173 | + } else { | ||
| 174 | + show_empty.value = false; | ||
| 175 | + } | ||
| 176 | + } | ||
| 177 | + return !show_empty.value; | ||
| 178 | +}; | ||
| 179 | + | ||
| 180 | +defineExpose({ validTableEditor }); | ||
| 132 | </script> | 181 | </script> |
| 133 | 182 | ||
| 134 | <style lang="less" scoped> | 183 | <style lang="less" scoped> |
| ... | @@ -142,6 +191,8 @@ const table = ` | ... | @@ -142,6 +191,8 @@ const table = ` |
| 142 | 191 | ||
| 143 | .tinymce-box { | 192 | .tinymce-box { |
| 144 | // width: 100%; | 193 | // width: 100%; |
| 194 | + display: block; | ||
| 195 | + margin-top: 1rem; | ||
| 145 | } | 196 | } |
| 146 | 197 | ||
| 147 | :deep(.table-wrapper) { | 198 | :deep(.table-wrapper) { | ... | ... |
| ... | @@ -207,7 +207,7 @@ export function createComponentType(data) { | ... | @@ -207,7 +207,7 @@ export function createComponentType(data) { |
| 207 | if (item.component_props.tag === 'volunteer_group') { | 207 | if (item.component_props.tag === 'volunteer_group') { |
| 208 | item.component = VolunteerGroupField; | 208 | item.component = VolunteerGroupField; |
| 209 | } | 209 | } |
| 210 | - if (item.component_props.tag === 'table') { | 210 | + if (item.component_props.tag === 'table_editor') { |
| 211 | item.component = TableField; | 211 | item.component = TableField; |
| 212 | } | 212 | } |
| 213 | }) | 213 | }) | ... | ... |
| 1 | <!-- | 1 | <!-- |
| 2 | * @Date: 2022-07-18 10:22:22 | 2 | * @Date: 2022-07-18 10:22:22 |
| 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com | 3 | * @LastEditors: hookehuyr hookehuyr@gmail.com |
| 4 | - * @LastEditTime: 2024-08-01 14:33:36 | 4 | + * @LastEditTime: 2024-08-01 16:33:00 |
| 5 | * @FilePath: /data-table/src/views/index.vue | 5 | * @FilePath: /data-table/src/views/index.vue |
| 6 | * @Description: 首页 | 6 | * @Description: 首页 |
| 7 | --> | 7 | --> |
| ... | @@ -282,6 +282,7 @@ const formatData = (data) => { | ... | @@ -282,6 +282,7 @@ const formatData = (data) => { |
| 282 | const area_picker = ref([]); | 282 | const area_picker = ref([]); |
| 283 | const image_uploader = ref([]); | 283 | const image_uploader = ref([]); |
| 284 | const file_uploader = ref([]); | 284 | const file_uploader = ref([]); |
| 285 | +const table_editor = ref([]); | ||
| 285 | const sign = ref([]); | 286 | const sign = ref([]); |
| 286 | const rate_picker = ref([]); | 287 | const rate_picker = ref([]); |
| 287 | const appointment = ref([]); | 288 | const appointment = ref([]); |
| ... | @@ -294,6 +295,9 @@ const setRefMap = (el, item) => { | ... | @@ -294,6 +295,9 @@ const setRefMap = (el, item) => { |
| 294 | if (item.component_props.tag === "file_uploader") { | 295 | if (item.component_props.tag === "file_uploader") { |
| 295 | file_uploader.value.push(el); | 296 | file_uploader.value.push(el); |
| 296 | } | 297 | } |
| 298 | + if (item.component_props.tag === "table_editor") { | ||
| 299 | + table_editor.value.push(el); | ||
| 300 | + } | ||
| 297 | // if (item.component_props.tag === "sign") { | 301 | // if (item.component_props.tag === "sign") { |
| 298 | // sign.value.push(el); | 302 | // sign.value.push(el); |
| 299 | // } | 303 | // } |
| ... | @@ -582,12 +586,12 @@ onMounted(async () => { | ... | @@ -582,12 +586,12 @@ onMounted(async () => { |
| 582 | 586 | ||
| 583 | // TEST 新组件 | 587 | // TEST 新组件 |
| 584 | // page_form.push({ | 588 | // page_form.push({ |
| 585 | - // "tag": "table", | 589 | + // "tag": "table_editor", |
| 586 | // "name": "name_2", | 590 | // "name": "name_2", |
| 587 | // "index": 2, | 591 | // "index": 2, |
| 588 | - // "label": "姓名", | 592 | + // "label": "表格", |
| 589 | // "unique": false, | 593 | // "unique": false, |
| 590 | - // "default": "", | 594 | + // "default": "<p>123</p>", |
| 591 | // "disabled": false, | 595 | // "disabled": false, |
| 592 | // "field_id": 799599, | 596 | // "field_id": 799599, |
| 593 | // "readonly": false, | 597 | // "readonly": false, |
| ... | @@ -1007,6 +1011,9 @@ const onActive = (item) => { | ... | @@ -1007,6 +1011,9 @@ const onActive = (item) => { |
| 1007 | if (item?.type === "picker") { // 下拉框控件 | 1011 | if (item?.type === "picker") { // 下拉框控件 |
| 1008 | postData.value[item.key] = item.value; | 1012 | postData.value[item.key] = item.value; |
| 1009 | } | 1013 | } |
| 1014 | + if (item?.key === "table_editor") { // 表单控件 | ||
| 1015 | + postData.value[item.filed_name] = item.value; | ||
| 1016 | + } | ||
| 1010 | // 检查规则,会影响字段显示 | 1017 | // 检查规则,会影响字段显示 |
| 1011 | checkRules(); | 1018 | checkRules(); |
| 1012 | }; | 1019 | }; |
| ... | @@ -1041,6 +1048,18 @@ const validOther = () => { | ... | @@ -1041,6 +1048,18 @@ const validOther = () => { |
| 1041 | } | 1048 | } |
| 1042 | }); | 1049 | }); |
| 1043 | } | 1050 | } |
| 1051 | + if (table_editor.value) { | ||
| 1052 | + // 文件上传 | ||
| 1053 | + table_editor.value.forEach((item, index) => { | ||
| 1054 | + if (table_editor.value[index].validTableEditor && !table_editor.value[index].validTableEditor()) { | ||
| 1055 | + valid = { | ||
| 1056 | + status: table_editor.value[index].validTableEditor(), | ||
| 1057 | + key: "table_editor", | ||
| 1058 | + }; | ||
| 1059 | + return false; | ||
| 1060 | + } | ||
| 1061 | + }); | ||
| 1062 | + } | ||
| 1044 | // if (sign.value) { | 1063 | // if (sign.value) { |
| 1045 | // // 电子签名 | 1064 | // // 电子签名 |
| 1046 | // sign.value.forEach((item, index) => { | 1065 | // sign.value.forEach((item, index) => { | ... | ... |
-
Please register or login to post a comment