<template> <div class="app-form-json"> <div :id='id' :innerHTML="id"></div> <el-input type="textarea" :rows="10" placeholder="请输入内容" v-model="CurrentVal"> </el-input> </div> </template> <script lang="ts"> import { Component, Vue, Prop, Model, Watch } from "vue-property-decorator"; import { VNode, CreateElement } from "vue"; import { interval, Subject, Subscription } from "rxjs"; import { Http,Util } from '@/utils'; import JSONEditor from "@json-editor/json-editor"; import BootstrapVue from "bootstrap-vue"; import "bootstrap/dist/css/bootstrap.css"; import "bootstrap-vue/dist/bootstrap-vue.css"; import "./select2.js"; import "select2/dist/css/select2.min.css" import 'jquery/dist/jquery.min.js' import $ from 'jquery' import "../app-form-json/app-form-json.less"; JSONEditor.defaults.resolvers.unshift(schema => { if(schema.type === "selectnew" ) { return "selectnew"; } else if(schema.type === "link" ) { return "link"; } // If no valid editor is returned, the next resolver function will be used }); JSONEditor.defaults.editors.selectnew = JSONEditor.defaults.editors.select.extend({ remoteCached : {}, getRemoteItems: function(url){ var self = this if(self.remoteCached[url]) return self.remoteCached[url]; const token = window.localStorage.getItem('token'); var new_items = []; $.ajax({ url: url, headers: { "Authorization":"Bearer "+token//此处放置请求到的用户token }, type: 'get', contentType: 'application/json', dataType: 'text', async: false, // 同步 success: function (result) { var resObj = JSON.parse(result); resObj.forEach((item: any)=>{ new_items.push(item); }); self.remoteCached[url]=new_items; }, error: function (result) { } }); return new_items; }, onWatchedFieldChange: function() { var self = this, vars, j; // If this editor uses a dynamic select box if(this.enumSource) { vars = this.getWatchedFieldValues(); var select_options = []; var select_titles = []; for(var i=0; i<this.enumSource.length; i++) { // Constant values if(Array.isArray(this.enumSource[i])) { select_options = select_options.concat(this.enumSource[i]); select_titles = select_titles.concat(this.enumSource[i]); } else { var items = []; // Static list of items if(Array.isArray(this.enumSource[i].source)) { items = this.enumSource[i].source; // A watched field } else { items = vars[this.enumSource[i].source]; } if(items) { // Only use a predefined part of the array if(this.enumSource[i].slice) { items = Array.prototype.slice.apply(items,this.enumSource[i].slice); } // Filter the items if(this.enumSource[i].filter) { var new_items = []; for(j=0; j<items.length; j++) { if(this.enumSource[i].filter({i:j,item:items[j],watched:vars})) new_items.push(items[j]); } items = new_items; } if(this.enumSource[i].url) { var url=this.enumSource[i].url; var p0=vars[this.enumSource[i].p0]; var p1=vars[this.enumSource[i].p1]; var p2=vars[this.enumSource[i].p2]; var p3=vars[this.enumSource[i].p3]; if(p0&&p0!='null') url=url.replace('${p0}',p0); if(p1&&p1!='null') url=url.replace('${p1}',p1); if(p2&&p2!='null') url=url.replace('${p2}',p2); if(p3&&p3!='null') url=url.replace('${p3}',p3); var localdata; if(url.indexOf("${localdata.")>0) { localdata = window.localStorage.getItem('localdata'); if(localdata) { url=url.replace('${localdata.dstsystemid}',localdata["dstsystemid"]); } } var new_items = []; if(url.indexOf("${")<0) { var firstObj = (JSON.parse(JSON.stringify(items[0]))); items = JSON.parse(JSON.stringify(this.getRemoteItems(url))); items.unshift(firstObj); } else { new_items.unshift(JSON.parse(JSON.stringify(items[0]))); items = new_items; } } if(this.enumSource[i].filterText) { var filterText=vars[this.enumSource[i].filterText]; if(filterText) { var new_items = []; new_items=items.filter(item22 => ((item22.text&&item22.text.indexOf(filterText)>=0)|| (item22.value&&item22.value.indexOf(filterText)>=0)|| (item22.filter&&item22.filter.indexOf(filterText)>=0))); new_items.unshift({text:"--",id:""}); items = new_items; } } var item_titles = []; var item_values = []; for(j=0; j<items.length; j++) { var item = items[j]; // Rendered value if(this.enumSource[i].value) { item_values[j] = this.typecast(this.enumSource[i].value({ i: j, item: item })); } // Use value directly else { item_values[j] = items[j]; } // Rendered title if(this.enumSource[i].title) { item_titles[j] = this.enumSource[i].title({ i: j, item: item }); } // Use value as the title also else { item_titles[j] = item_values[j]; } } // TODO: sort select_options = select_options.concat(item_values); select_titles = select_titles.concat(item_titles); } } } var prev_value = this.value; this.theme.setSelectOptions(this.input, select_options, select_titles); this.enum_options = select_options; this.enum_display = select_titles; this.enum_values = select_options; if(this.select2) { this.select2.select2('destroy'); } // If the previous value is still in the new select options, stick with it if(select_options.indexOf(prev_value) !== -1) { this.input.value = prev_value; this.value = prev_value; } // Otherwise, set the value to the first select option else { this.input.value = select_options[0]; this.value = this.typecast(select_options[0] || ""); if(this.parent) this.parent.onChildEditorChange(this); else this.jsoneditor.onChange(); this.jsoneditor.notifyWatchers(this.path); } this.setupSelect2(); } // { var vars; if(this.header_template) { vars = $.extend(this.getWatchedFieldValues(),{ key: this.key, i: this.key, i0: (this.key*1), i1: (this.key*1+1), title: this.getTitle() }); var header_text = this.header_template(vars); if(header_text !== this.header_text) { this.header_text = header_text; this.updateHeaderText(); this.notify(); //this.fireChangeHeaderEvent(); } } if(this.link_watchers.length) { vars = this.getWatchedFieldValues(); for(var i=0; i<this.link_watchers.length; i++) { this.link_watchers[i](vars); } } // } }, getLink: function(data) { var holder, link; // Get mime type of the link var mime = data.mediaType || 'application/javascript'; var type = mime.split('/')[0]; // Template to generate the link href var href = this.jsoneditor.compileTemplate(data.href,this.template_engine); var relTemplate = this.jsoneditor.compileTemplate(data.rel ? data.rel : data.href,this.template_engine); // Template to generate the link's download attribute var download = null; if(data.download) download = data.download; if(download && download !== true) { download = this.jsoneditor.compileTemplate(download, this.template_engine); } { link = holder = this.theme.getBlockLink(); //holder.setAttribute('target','_blank'); holder.textContent = data.rel; // When a watched field changes, update the url this.link_watchers.push(function(vars) { var url = href(vars); var rel = relTemplate(vars); holder.setAttribute('href',url); holder.textContent = rel || url; }); } if(download && link) { if(download === true) { link.setAttribute('download',''); } else { this.link_watchers.push(function(vars) { link.setAttribute('download',download(vars)); }); } } if(data.class) link.classList.add(data.class); if(this.jsoneditor.options.no_link_holder){ holder.hidden = true; }else{ holder.hidden = false; } return holder; } }); JSONEditor.defaults.editors.link = JSONEditor.defaults.editors.string.extend({ getLink: function(data) { var holder, link; // Get mime type of the link var mime = data.mediaType || 'application/javascript'; var type = mime.split('/')[0]; // Template to generate the link href var href = this.jsoneditor.compileTemplate(data.href,this.template_engine); var relTemplate = this.jsoneditor.compileTemplate(data.rel ? data.rel : data.href,this.template_engine); // Template to generate the link's download attribute var download = null; if(data.download) download = data.download; if(download && download !== true) { download = this.jsoneditor.compileTemplate(download, this.template_engine); } // Image links if(type === 'image') { holder = this.theme.getBlockLinkHolder(); link = document.createElement('a'); link.setAttribute('target','_blank'); var image = document.createElement('img'); this.theme.createImageLink(holder,link,image); // When a watched field changes, update the url this.link_watchers.push(function(vars) { var url = href(vars); var rel = relTemplate(vars); link.setAttribute('href',url); link.setAttribute('title',rel || url); image.setAttribute('src',url); }); } // Audio/Video links else if(['audio','video'].indexOf(type) >=0) { holder = this.theme.getBlockLinkHolder(); link = this.theme.getBlockLink(); link.setAttribute('target','_blank'); var media = document.createElement(type); media.setAttribute('controls','controls'); this.theme.createMediaLink(holder,link,media); // When a watched field changes, update the url this.link_watchers.push(function(vars) { var url = href(vars); var rel = relTemplate(vars); link.setAttribute('href',url); link.textContent = rel || url; media.setAttribute('src',url); }); } // Text links else { link = holder = this.theme.getBlockLink(); //holder.setAttribute('target','_blank'); holder.textContent = data.rel; // When a watched field changes, update the url this.link_watchers.push(function(vars) { var url = href(vars); var rel = relTemplate(vars); holder.setAttribute('href',url); holder.textContent = rel || url; }); } if(download && link) { if(download === true) { link.setAttribute('download',''); } else { this.link_watchers.push(function(vars) { link.setAttribute('download',download(vars)); }); } } if(data.class) link.classList.add(data.class); if(this.jsoneditor.options.no_link_holder){ holder.hidden = true; }else{ holder.hidden = false; } return holder; } }); @Component({}) export default class AppFormJson extends Vue { /** * 双向绑定值 * * @type {*} * @memberof AppFormJson */ @Model("change") itemValue?: any; /** * 表单数据 * * @type {*} * @memberof AppFormJson */ @Prop() public data!: any; /** * 数据格式 * * @type {*} * @memberof AppFormJson */ @Prop() public schema?: any; /** * 格式选项 * * @type {*} * @memberof AppFormJson */ @Prop() public options?: any; /** * 当前值 * * @return {*} * @memberof AppFormJson */ get CurrentVal() { return this.itemValue; } /** * 设置值 * * @param {*} [value] * @memberof AppFormJson */ set CurrentVal(val: any) { this.$emit("change", val); } /** * 表单状态 * * @type {Subject<any>} * @memberof AppFormJson */ @Prop() public formState?: Subject<any>; /** * 表单状态事件 * * @private * @type {(Unsubscribable | undefined)} * @memberof AppFormJson */ private formStateEvent: Subscription | undefined; /** * Vue生命周期(实例销毁后) * * @memberof AppFormJson */ public destroyed() { if (this.editor) this.editor = null; window["showdetail"]=null; } /** * Vue生命周期(实例挂载后) * * @memberof AppFormJson */ public mounted() { if (!this.formState) { return; } this.formStateEvent = this.formState.subscribe(($event: any) => { if (Object.is($event.type, "load")) { this.renderJsoneditor(); } if (Object.is($event.type, 'save')) { this.renderJsoneditor(); } // 表单项更新 if (Object.is($event.type, 'updateformitem')) { if (!$event.data) { return; } this.renderJsoneditor(); } }); window["showdetail"]=this.showdetail; } /** * 编辑器对象 * * @type {*} * @memberof AppFormJson */ public editor: any; public id: any = this.$util.createUUID(); public async getSchema(): Promise<any>{ if(this.schema) return this.schema; else return {}; } public async getOptions(): Promise<any>{ let _options={ theme: "bootstrap3", iconlib: "fontawesome4", disable_edit_json: true, display_required_only: true, disable_collapse: true, disable_array_delete_last_row: true, ajax: true, }; _options["schema"]=await this.getSchema(); if (this.CurrentVal) { _options["startval"] = JSON.parse(this.CurrentVal); } if(this.options){ return Object.assign({},_options,this.options) } return _options; } /** * 编辑器生成 * * @memberof AppFormJson */ public async renderJsoneditor() { var _this = this; var element = document.getElementById(_this.id); if (this.editor) { this.editor.destroy(); } let opt:any = await _this.getOptions(); this.editor = new JSONEditor(element, opt); this.editor.on("change", () => { let value = _this.editor.getValue(); _this.CurrentVal = JSON.stringify(value); }); } /** * 设置编辑器值 * * @param {*} [val] * @memberof AppFormJson */ public setEditValue(val: any): void { if (val) { this.editor.setValue(val); } else { this.editor.setValue({}); } } public showdetail(path:any,arg:any) { const view: any = { viewname: path, height: 0, width: 0, title: '查看', }; this.$appmodal.openModal(view, arg, {}); } } </script>