hookehuyr

fix 表格控件操作逻辑完善

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) => {
......