summaryrefslogtreecommitdiffstats
path: root/src/components/CopyableInput.vue
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/CopyableInput.vue')
-rw-r--r--src/components/CopyableInput.vue142
1 files changed, 142 insertions, 0 deletions
diff --git a/src/components/CopyableInput.vue b/src/components/CopyableInput.vue
new file mode 100644
index 0000000..951fded
--- /dev/null
+++ b/src/components/CopyableInput.vue
@@ -0,0 +1,142 @@
+<template>
+ <div class="input-group">
+ <input
+ :id="id"
+ ref="input"
+ v-model="model"
+ :type="type"
+ class="form-control"
+ :placeholder="placeholder"
+ :autocomplete="autocomplete"
+ :required="required"
+ :readonly="readonly"
+ :disabled="disabled"
+ >
+
+ <!-- A hidden textarea for copying text on non-https -->
+ <textarea ref="hiddenTextarea" style="position: fixed; left: -999999px; top: -999999px;"></textarea>
+
+ <a class="btn btn-outline-primary" @click="copyToClipboard(model)">
+ <font-awesome-icon :icon="icon" />
+ </a>
+ </div>
+</template>
+
+<script>
+
+let timeout;
+
+export default {
+ props: {
+ /** ID of this input */
+ id: {
+ type: String,
+ default: ""
+ },
+ /** Type of input */
+ type: {
+ type: String,
+ default: "text"
+ },
+ /** The value of the input */
+ modelValue: {
+ type: String,
+ default: ""
+ },
+ /** A placeholder to use */
+ placeholder: {
+ type: String,
+ default: ""
+ },
+ /** Should the field auto complete */
+ autocomplete: {
+ type: String,
+ default: undefined,
+ },
+ /** Is the input required? */
+ required: {
+ type: Boolean
+ },
+ /** Should the input be read only? */
+ readonly: {
+ type: String,
+ default: undefined,
+ },
+ /** Is the input disabled? */
+ disabled: {
+ type: String,
+ default: undefined,
+ },
+ },
+ emits: [ "update:modelValue" ],
+ data() {
+ return {
+ visibility: "password",
+ icon: "copy",
+ };
+ },
+ computed: {
+ model: {
+ get() {
+ return this.modelValue;
+ },
+ set(value) {
+ this.$emit("update:modelValue", value);
+ }
+ }
+ },
+ created() {
+
+ },
+ methods: {
+
+ /**
+ * Show the input
+ * @returns {void}
+ */
+ showInput() {
+ this.visibility = "text";
+ },
+
+ /**
+ * Hide the input
+ * @returns {void}
+ */
+ hideInput() {
+ this.visibility = "password";
+ },
+
+ /**
+ * Copy the provided text to the users clipboard
+ * @param {string} textToCopy Text to copy to clipboard
+ * @returns {Promise<void>}
+ */
+ copyToClipboard(textToCopy) {
+ this.icon = "check";
+
+ clearTimeout(timeout);
+ timeout = setTimeout(() => {
+ this.icon = "copy";
+ }, 3000);
+
+ // navigator clipboard api needs a secure context (https)
+ // For http, use the text area method (else part)
+ if (navigator.clipboard && window.isSecureContext) {
+ // navigator clipboard api method'
+ return navigator.clipboard.writeText(textToCopy);
+ } else {
+ // text area method
+ let textArea = this.$refs.hiddenTextarea;
+ textArea.value = textToCopy;
+ textArea.focus();
+ textArea.select();
+ return new Promise((res, rej) => {
+ // here the magic happens
+ document.execCommand("copy") ? res() : rej();
+ });
+ }
+ }
+
+ }
+};
+</script>