295 lines
8.0 KiB
Vue
295 lines
8.0 KiB
Vue
![]() |
<template>
|
||
|
<div class="row form-group mt-3" :key="$attrs.key">
|
||
|
<template v-if="enableSuggestion">
|
||
|
<label
|
||
|
:for="localFormElement.key"
|
||
|
:class="$attrs.labelClass ?? 'col-md-2'"
|
||
|
>{{ localFormElement.label }}:</label
|
||
|
>
|
||
|
<!-- <vue-tribute
|
||
|
:class="[$attrs.inputClass ?? ' col-md-10']"
|
||
|
:options="tributeOptions"
|
||
|
> -->
|
||
|
<textarea
|
||
|
@tribute-no-match="noMatchFound"
|
||
|
@tribute-replaced="textReplaced"
|
||
|
:ref="localFormElement.key"
|
||
|
class="form-control"
|
||
|
@focus="clearErrors"
|
||
|
@blur="validate"
|
||
|
@change="validate"
|
||
|
:placeholder="localFormElement.placeholder"
|
||
|
:id="localFormElement.key"
|
||
|
:name="localFormElement.key"
|
||
|
v-model="textValue"
|
||
|
cols="30"
|
||
|
:rows="getRows()"
|
||
|
>
|
||
|
</textarea>
|
||
|
<!-- </vue-tribute> -->
|
||
|
<context-menu
|
||
|
style="position: static; display: inline-flex"
|
||
|
v-if="contextMenu.length"
|
||
|
:id="'context-menu-' + localFormElement.key"
|
||
|
:contextMenu="contextMenu"
|
||
|
@other="methodName($event)"
|
||
|
>
|
||
|
</context-menu>
|
||
|
</template>
|
||
|
|
||
|
<template v-else>
|
||
|
<label
|
||
|
:for="localFormElement.key"
|
||
|
:class="$attrs.labelClass ?? 'col-md-3'"
|
||
|
>{{ localFormElement.label }}:</label
|
||
|
>
|
||
|
<div class="mt-2" :class="[$attrs.inputClass ?? ' col-md-9']">
|
||
|
<textarea
|
||
|
@tribute-no-match="noMatchFound"
|
||
|
@tribute-replaced="textReplaced"
|
||
|
:ref="localFormElement.key"
|
||
|
class="form-control"
|
||
|
@focus="clearErrors"
|
||
|
@blur="validate"
|
||
|
@change="validate"
|
||
|
:placeholder="localFormElement.placeholder"
|
||
|
:id="localFormElement.key"
|
||
|
:name="localFormElement.key"
|
||
|
v-model="textValue"
|
||
|
cols="30"
|
||
|
:rows="getRows()"
|
||
|
>
|
||
|
</textarea>
|
||
|
</div>
|
||
|
</template>
|
||
|
</div>
|
||
|
</template>
|
||
|
|
||
|
<script>
|
||
|
import formBuilderMixin from "~/extensions/formBuilderExtension.js";
|
||
|
// import VueTribute from "vue-tribute";
|
||
|
import apis from "~/apis/borhanApi.js";
|
||
|
|
||
|
export default {
|
||
|
props: {
|
||
|
enableSuggestion: {
|
||
|
default: false,
|
||
|
},
|
||
|
contextMenu: {
|
||
|
default() {
|
||
|
return [];
|
||
|
},
|
||
|
},
|
||
|
},
|
||
|
extends: formBuilderMixin,
|
||
|
|
||
|
data() {
|
||
|
return {
|
||
|
// tributeOptions: {
|
||
|
// // symbol or string that starts the lookup
|
||
|
// trigger: "",
|
||
|
|
||
|
// // element to target for @mentions
|
||
|
// iframe: null,
|
||
|
|
||
|
// // class added in the flyout menu for active item
|
||
|
// selectClass: "highlight",
|
||
|
|
||
|
// // class added to the menu container
|
||
|
// containerClass: "tribute-container",
|
||
|
|
||
|
// // class added to each list item
|
||
|
// itemClass: "my-tribute-class",
|
||
|
|
||
|
// // function called on select that returns the content to insert
|
||
|
// selectTemplate: function (item) {
|
||
|
// return item.original.value;
|
||
|
// // return "@" + item.original.value;
|
||
|
// },
|
||
|
|
||
|
// // template for displaying item in menu
|
||
|
// menuItemTemplate: function (item) {
|
||
|
// return item.string;
|
||
|
// },
|
||
|
|
||
|
// // template for when no match is found (optional),
|
||
|
// // If no template is provided, menu is hidden.
|
||
|
// noMatchTemplate:
|
||
|
// '<span class="no-result">مورد مشابهی ثبت نشده است.</span>',
|
||
|
|
||
|
// // specify an alternative parent container for the menu
|
||
|
// // container must be a positioned element for the menu to appear correctly ie. `position: relative;`
|
||
|
// // default container is the body
|
||
|
// menuContainer: document.body,
|
||
|
|
||
|
// // column to search against in the object (accepts function or string)
|
||
|
// lookup: "key",
|
||
|
|
||
|
// // column that contains the content to insert by default
|
||
|
// fillAttr: "value",
|
||
|
|
||
|
// // REQUIRED: array of objects to match or a function that returns data (see 'Loading remote data' for an example)
|
||
|
// values: [
|
||
|
// {
|
||
|
// key: "سلام",
|
||
|
// value: "سلام",
|
||
|
// },
|
||
|
// {
|
||
|
// key: "باسلام",
|
||
|
// value: "باسلام",
|
||
|
// },
|
||
|
// {
|
||
|
// key: "علیک سلام",
|
||
|
// value: "علیک سلام",
|
||
|
// },
|
||
|
// {
|
||
|
// key: "بی سلام",
|
||
|
// value: "بی سلام",
|
||
|
// },
|
||
|
// {
|
||
|
// key: "صدتا سلام",
|
||
|
// value: "صدتا سلام",
|
||
|
// },
|
||
|
// ],
|
||
|
// // values: ["سلام", "باسلام", "علیک سلام", "بی سلام", "صدتا سلام"],
|
||
|
// // values: (text, cb) => {
|
||
|
// // this.remoteSearch(text, (items) => cb(items));
|
||
|
// // },
|
||
|
// // When your values function is async, an optional loading template to show
|
||
|
// loadingItemTemplate: null,
|
||
|
|
||
|
// // specify whether a space is required before the trigger string
|
||
|
// requireLeadingSpace: true,
|
||
|
|
||
|
// // specify whether a space is allowed in the middle of mentions
|
||
|
// allowSpaces: true,
|
||
|
|
||
|
// // optionally specify a custom suffix for the replace text
|
||
|
// // (defaults to empty space if undefined)
|
||
|
// // replaceTextSuffix: "",
|
||
|
|
||
|
// // specify whether the menu should be positioned. Set to false and use in conjuction with menuContainer to create an inline menu
|
||
|
// // (defaults to true)
|
||
|
// positionMenu: true,
|
||
|
|
||
|
// // when the spacebar is hit, select the current match
|
||
|
// spaceSelectsMatch: false,
|
||
|
|
||
|
// // turn tribute into an autocomplete
|
||
|
// autocompleteMode: true,
|
||
|
|
||
|
// // Customize the elements used to wrap matched strings within the results list
|
||
|
// // defaults to <span></span> if undefined
|
||
|
// searchOpts: {
|
||
|
// pre: "<span>",
|
||
|
// post: "</span>",
|
||
|
// skip: false, // true will skip local search, useful if doing server-side search
|
||
|
// },
|
||
|
|
||
|
// // Limits the number of items in the menu
|
||
|
// menuItemLimit: 25,
|
||
|
|
||
|
// // specify the minimum number of characters that must be typed before menu appears
|
||
|
// menuShowMinLength: 0,
|
||
|
// },
|
||
|
httpService: undefined,
|
||
|
};
|
||
|
},
|
||
|
beforeMount() {
|
||
|
this.httpService = useNuxtApp()["$http"];
|
||
|
},
|
||
|
mounted() {},
|
||
|
methods: {
|
||
|
getRows() {
|
||
|
if (this.localFormElement?.rows) return this.localFormElement?.rows;
|
||
|
return "3";
|
||
|
},
|
||
|
noMatchFound(args) {
|
||
|
console.info(args);
|
||
|
},
|
||
|
textReplaced(args) {
|
||
|
console.info(args);
|
||
|
},
|
||
|
methodName(action, index = 0) {
|
||
|
try {
|
||
|
this[action](index);
|
||
|
} catch (err) {
|
||
|
this.$emit(action, index);
|
||
|
}
|
||
|
},
|
||
|
remoteSearch(input, callback) {
|
||
|
console.info(input);
|
||
|
|
||
|
return this.httpService
|
||
|
.getRequest(apis.concept.annotations.read + "?ontology_id=" + input)
|
||
|
.then((res) => {
|
||
|
callback(res.data);
|
||
|
})
|
||
|
.catch((e) => {
|
||
|
callback([]);
|
||
|
})
|
||
|
.finally(() => {
|
||
|
this.fetchingData = false;
|
||
|
});
|
||
|
},
|
||
|
},
|
||
|
components: {
|
||
|
// VueTribute,
|
||
|
},
|
||
|
};
|
||
|
</script>
|
||
|
|
||
|
<style scoped>
|
||
|
.form-control {
|
||
|
height: auto !important;
|
||
|
}
|
||
|
</style>
|
||
|
|
||
|
<style>
|
||
|
.tribute-container {
|
||
|
position: absolute;
|
||
|
top: 0;
|
||
|
left: 0;
|
||
|
height: auto;
|
||
|
overflow: auto;
|
||
|
max-height: 25em;
|
||
|
overflow: auto;
|
||
|
display: block;
|
||
|
z-index: 999999;
|
||
|
|
||
|
transform: translate(-80px, 7px);
|
||
|
box-shadow: 0 9px 8px -3px rgba(64, 60, 67, 0.24),
|
||
|
8px 0 8px -7px rgba(64, 60, 67, 0.24),
|
||
|
-8px 0 8px -7px rgba(64, 60, 67, 0.24);
|
||
|
|
||
|
box-shadow: 0px 0px 14px 0px #eee;
|
||
|
|
||
|
border-radius: 0.3em;
|
||
|
background: #ededed;
|
||
|
}
|
||
|
|
||
|
.tribute-container ul {
|
||
|
margin: 0;
|
||
|
margin-top: 2px;
|
||
|
padding: 0;
|
||
|
list-style: none;
|
||
|
/* background: #efefef; */
|
||
|
}
|
||
|
.tribute-container li {
|
||
|
padding: 0.5em 1em;
|
||
|
cursor: pointer;
|
||
|
}
|
||
|
.tribute-container li.highlight {
|
||
|
/* background: #ddd; */
|
||
|
}
|
||
|
.tribute-container li span {
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
.tribute-container li.no-match {
|
||
|
cursor: default;
|
||
|
}
|
||
|
.tribute-container .menu-highlighted {
|
||
|
font-weight: bold;
|
||
|
}
|
||
|
</style>
|