Copy data(text) to Clipboard in Vue(Nuxt js) - javascript

When I click the vs-button, the single_download_link.pdfId should be copied on clipboard.
I tried like this. But it was not working. And I will not use v-clipboard node module.
Please help me. Regards.
DOM code:
<div ref="text" class="w-full">{{single_download_link.pdfId}}
</div>
<vs-button block #click="copy()">
Copy this link to clipboard.
</vs-button>
//this is my function
<script>
import "../../assets/css/products.css";
export default {
name: 'Products',
components:{
Vinput,
},
data () {
return {
single_download_link:{
pdfId:"",
pdfRandomName:"",
uploaderUserName:"",
uploaderUserId:"",
uploaderUserEmail:""
}
}
},
methods:{
copy(){
this.$refs.text.select();
document.execCommand('copy');
},
},
}
</script>

Update 2021:
document.execCommand() is marked as depreciated
Alternative.
Simply
copyToClipBoard(textToCopy){
navigator.clipboard.writeText(textToCopy);
},
Previous answer:
This worked for me, just put it into your methods and pass any String you wanted to copy.
copyToClipBoard(textToCopy){
const tmpTextField = document.createElement("textarea")
tmpTextField.textContent = textToCopy
tmpTextField.setAttribute("style","position:absolute; right:200%;")
document.body.appendChild(tmpTextField)
tmpTextField.select()
tmpTextField.setSelectionRange(0, 99999) /*For mobile devices*/
document.execCommand("copy")
tmpTextField.remove()
},

Related

Is there any way to switch JSON files for the same script?

I'm trying to implement dark mode on my web where I have the particlesj script and I need to modify the color of the particles for the light mode. Is there any way to switch between JSON files? Let's say particles.json and particles-light.json. Appreciate any help so much.
I've made a sample using themes with tsParticles here: https://codepen.io/matteobruni/pen/vYejMNr
You can have a single config with configured themes like in the sample above.
I'll show below more in details how to achieve it.
// the particles container, used for calling the loadTheme method
let themeableContainer;
document.getElementById("btnLight").addEventListener("click", () => {
if (themeableContainer) {
// the theme name must be used when loading theme
themeableContainer.loadTheme("light");
}
});
document.getElementById("btnDark").addEventListener("click", () => {
if (themeableContainer) {
// the theme name must be used when loading theme
themeableContainer.loadTheme("dark");
}
});
tsParticles.loadJSON("tsparticles", "particles.json").then((container) => {
// assigning the loaded container
themeableContainer = container;
});
and the config looks like this
{
"fpsLimit":60,
"particles":{
"move":{
"bounce":false,
"direction":"none",
"enable":true,
"outModes":"out",
"random":false,
"speed":2,
"straight":false
},
"number":{
"density":{
"enable":true,
"area":800
},
"value":80
},
"opacity":{
"value":0.5
},
"shape":{
"type":"circle"
},
"size":{
"value":{
"min":1,
"max":5
}
}
},
"themes":[
{
"name":"light",
"default":{
"value":true,
"mode":"light"
},
"options":{
"background":{
"color":"#fff"
},
"particles":{
"color":{
"value":"#000"
}
}
}
},
{
"name":"dark",
"default":{
"value":true,
"mode":"dark"
},
"options":{
"background":{
"color":"#000"
},
"particles":{
"color":{
"value":"#fff"
}
}
}
}
]
}
The theme object accept those values, the options inside are a whole options so you can override everything from the background to the particles options.
In the GitHub reop you can find the following example:
particlesJS.load('particles-js', 'assets/particles.json', function() {
console.log('callback - particles.js config loaded');
});
I guess that you can probably call this load() function with a new JSON file when needed.
Alright so I've been trying and finally came to a solution. What I've done is to create a function associated to the theme selector checkbox.
particlesJS.load('particles-js', 'assets/particles.json');
function ThemeSwitch() {
if (document.getElementById('checkbox').value === 'dark') {
particlesJS.load('particles-js', 'assets/particles-light.json');
document.getElementById('checkbox').value = 'light';
} else {
particlesJS.load('particles-js', 'assets/particles.json');
document.getElementById('checkbox').value = 'dark';
}
}
And this is the input.
<input type="checkbox" id="checkbox" name="check" value="dark" onclick="ThemeSwitch()"/>
Good or bad (have no JS idea pretty much), it is working.

Quill Editor: cannot paste any text, input loses focus

I'm trying to paste any random text into the quill#1.3.7 editor, but all of my paste events are pretty much ignored. In addition, the cursor disappears - ie, the <div> loses focus.
Do I have to do something to get basic/default clipboard paste to work? According the docs, those should be turned on by default since they are required.
I have debug turned on, and this is what I see in Chrome.
Here is how I'm initializing the editor:
<div ref="editorElement" class="ql-editor" contenteditable="true"></div>
import Quill from 'quill';
#customElement('quill-editor')
export class QuillEditorComponent {
#bindable({ defaultBindingMode: bindingMode.twoWay }) value: string;
editorElement: any;
editor: Quill;
attached() {
var toolbarOptions = [/* removed for brevity */];
this.editor = new Quill(this.editorElement, {
debug: true,
modules: {
toolbar: toolbarOptions,
clipboard: {
matchVisual: false
}
},
placeholder: 'I have something to say...',
theme: 'snow'
});
this.editor.root.innerHTML = this.value;
}
}
UPDATE:
Filed an issue, as this seems to be a Chrome related issue:
https://github.com/quilljs/quill/issues/3512

Tinymce insert/edit image fields on pop up are not editable(focused) inside vuetify's dialog

I am aware with the tweaks required for enabling focus inside the tinymce pop up when in bootstrap modal.
But currently I am working with a vuetify dialog. Which does'nt seem to focus the pop up fields of tinymce.
I have gone through this question but it does not work in context to vuetify
TinyMCE 4 links plugin modal in not editable
Below is my code I have removed some methods just for clean up and have kept basic things that I have tried in mounted event & editor init.
<no-ssr placeholder="Loading Editor..">
<tinymce
id="content"
:toolbar2="toolbar2"
:toolbar1="type=='BASIC'?'':toolbar1"
:plugins="plugins"
:other_options="other_options"
v-model="content"
#input="handleInput"
v-on:editorInit="initCallBack"
/>
</no-ssr>
</template>
<script>
//https://dyonir.github.io/vue-tinymce-editor/?en_US
export default {
props: {
value: { type: String },
type: { type: String }
},
data() {
return {
content: this.value,
plugins: this.getPlugins(),
toolbar2: "",
toolbar1: this.getToolbar1(),
other_options: {
menubar: this.getMenubar(),
height: "320",
file_browser_callback: this.browseFile,
auto_focus: '#content'
}
};
},
mounted(event) {
// window.tinyMCE.activeEditor.focus();
// window.tinymce.editors["content"]
console.log(this.$el, event);
let list=document.getElementsByClassName("mce-textbox");
for (let index = 0; index < list.length; ++index) {
list[index].setAttribute("tabindex", "-1");
}
// if ((event.target).closest(".mce-window").length) {
// e.stopImmediatePropagation();
// }
// this.$refs.refToElement ..$el.focus())
// this.el.addEventListener('focusin', e => e.stopPropagation());
},
methods: {
handleInput(e) {
this.$emit("input", this.content);
},
initCallBack(e) {
window.tinymce.editors["content"].setContent(this.value);
window.tinymce.editors["content"].getBody().focus();
// console.log(this.$refs);
// const focusable = this.$refs.content.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])')
// focusable.length && focusable[0].focus()
document.getElementById("content").addEventListener("onfocusin", console.log("fucssed"));
// tinymce.activeEditor.fire("focus");
this.$el.querySelector(".mce-tinymce").addEventListener('focusin', e =>{ e.stopImmediatePropagation();console.log('event',e)});
const element = this.$el.querySelector(".mce-tinymce");
let _this=this;
if (element)
this.$nextTick(() => {
element.focus();
console.log("FOCUSED",element,_this);
// element.stopImmediatePropagation();
});
// window.tinyMCE.activeEditor.focus();
// console.log(this.$el,e);
// if ((e).closest(".mce-window").length) {
// e.stopImmediatePropagation();
// }
}
};
</script>```
I am using the component : https://github.com/dyonir/vue-tinymce-editor
But fields of the pop are not getting focussed/edited.
From vuetify 2.0 onwards there is a new prop 'retain-focus' which you can set to false in order to fix the above issue.
<v-dialog :retain-focus="false">
Tab focus will return to the first child of the dialog by default. Disable this when using external tools that require focus such as TinyMCE or vue-clipboard.
Edit:
Here is the link to retain-focus prop implementation GitHub:
https://github.com/vuetifyjs/vuetify/issues/6892
Modify the z-index of v-dialog:
Current:
z-index: 202
Modified:
<style>
.v-dialog__content {z-index: 203 !important;}
</style>
Do not forget the !important to give priority to style.

how to change head meta data when switch the language in VUE?

is there anyone ask that question yet ? if yes, please give me the link to read this question, if not, how to do that ?
I want to change the head tittle and description each user switch the language , how can I do that ?? I do love to get some help, I am. a beginner for this :D
i have gallery.vue
i am using nuxt js here
and using nuxt-i18n
based vue-i18n
<template lang="html">
<div class="">
<p> {{ $t('post') }}</p>
</div>
</template>
<script>
export default {
head () {
return {
tittle: // how to change tittle here for the spesific languange
}
}
}
</script>
<style lang="css">
</style>
i want the result like
when in english the head tittle to be Gallery
and when user switch the italianq , the head will be the Galleria
This maybe a bit late but to help new comers.
As per documentation you may use function to set meta data so with function you access data and computed (including this), check the code:
head() {
return {
title: this.$t('myTitle'),
htmlAttrs: {
lang: this.$i18n.locale,
},
meta: [
{
hid: 'description',
name: 'description',
content: this.$t('myDescription'),
},
],
}
},
source: https://nuxtjs.org/docs/2.x/features/meta-tags-seo#local-settings
Look for vue-meta library. I'm using it for this purposes. In App.vue:
<script>
export default {
name: 'App',
metaInfo () {
return {
htmlAttrs: {
lang: this.$i18n.locale
},
...
}
},
data () {
...
}
</script>
i got it
just add head function and return the tittle: this.$i18n.messages[this.$i18n.locale].yourPropHere

VueJS and tinyMCE, custom directives

I've been struggling hard with getting VueJS and TinyMCE to work together. I've come to the conclusion that using directives would be the way to go.
So far I've been able to pass in the body as a directive parameter, and tinyMCE sets the content. However, I can't get the two way binding to work. I'm also afraid that I'm doing things completely wrong based on the tinyMCE api.
The relevant tinyMCE functions I assume would be:
http://community.tinymce.com/wiki.php/api4:method.tinymce.Editor.setContent
// Sets the content of a specific editor (my_editor in this example)
tinymce.get('my_editor').setContent(data);
and
http://community.tinymce.com/wiki.php/api4:method.tinymce.Editor.getContent
// Get content of a specific editor:
tinymce.get('content id').getContent()
HTML
<div id="app">
<h3>This is the tinyMCE editor</h3>
<textarea id="editor" v-editor :body="body"></textarea>
<hr>
<p>This input field is properly binded</p>
<input v-model="body">
<hr>
<pre>data binding: {{ body }} </pre>
</div>
JS
tinymce.init({
selector:'#editor',
});
Vue.directive('editor', {
twoWay: true,
params: ['body'],
bind: function () {
tinyMCE.get('editor').setContent(this.params.body);
tinyMCE.get('editor').on('change', function(e) {
alert("changed");
});
},
update: function (value) {
$(this.el).val(value).trigger('change')
},
});
var editor = new Vue({
el: '#app',
data: {
body: 'The message'
}
})
Fiddle
https://jsfiddle.net/nf3ftm8f/
With Vue.js 2.0, the directives are only used for applying low-level direct DOM manipulations. They don't have this reference to Vue instance data anymore. (Ref: https://v2.vuejs.org/v2/guide/migration.html#Custom-Directives-simplified)
Hence I recommend to use Component instead.
TinymceComponent:
// Use JSPM to load dependencies: vue.js 2.1.4, tinymce: 4.5.0
import Vue from 'vue/dist/vue';
import tinymce from 'tinymce';
// Local component
var TinymceComponent = {
template: `<textarea class="form-control">{{ initValue }}</textarea>`,
props: [ 'initValue', 'disabled' ],
mounted: function() {
var vm = this,
tinymceDict = '/lib/jspm_packages/github/tinymce/tinymce-dist#4.5.1/';
// Init tinymce
tinymce.init({
selector: '#' + vm.$el.id,
menubar: false,
toolbar: 'bold italic underline | bullist numlist',
theme_url: tinymceDict + 'themes/modern/theme.js,
skin_url: tinymceDict + 'skins/lightgray',
setup: function(editor) {
// If the Vue model is disabled, we want to set the Tinymce readonly
editor.settings.readonly = vm.disabled;
if (!vm.disabled) {
editor.on('blur', function() {
var newContent = editor.getContent();
// Fire an event to let its parent know
vm.$emit('content-updated', newContent);
});
}
}
});
},
updated: function() {
// Since we're using Ajax to load data, hence we have to use this hook because when parent's data got loaded, it will fire this hook.
// Depends on your use case, you might not need this
var vm = this;
if (vm.initValue) {
var editor = tinymce.get(vm.$el.id);
editor.setContent(vm.initValue);
}
}
};
// Vue instance
new Vue({
......
components: {
'tinymce': TinymceComponent
}
......
});
Vue Instance (simplified)
new Vue({
el: '#some-id',
data: {
......
description: null
......
},
components: {
'tinymce': TinymceComponent
},
methods: {
......
updateDescription: function(newContent) {
this.description = newContent;
},
load: function() {
......
this.description = "Oh yeah";
......
}
......
},
mounted: function() {
this.load();
}
});
HTML (MVC view)
<form id="some-id">
......
<div class="form-group">
<tinymce :init-value="description"
v-on:content-updated="updateDescription"
:id="description-tinymce"
:disabled="false">
</tinymce>
</div>
......
</form>
The flows
First the data is loaded through remote resources, i.e., AJAX. The description got set.
The description got passed down to the component via props: initValue.
When the component is mounted, the tinymce is initialized with the initial description.
It also sets up the on blur event to get the updated content.
Whenever the user loses focus on the editor, a new content is captured and the component emits an event content-updated, letting the parent know that something has happened.
On Html you have v-on:content-updated. Since the parent is listening to the content-updated event, the parent method updateDescription will be called when the event is emited.
!!Couple Important Notes!!
By design, the component has 1 way binding, from parent to component. So when the description gets updated from Vue instance, the component's initValue property should be updated as well, automatically.
It would be nice if we can pass whatever the user types in tinymce editor back to the parent Vue instance but 2 ways bindings is not supposed. That's when you need to use $emit to fire up events and notify parents from components.
You don't have to define a function in parent and do v-on:content-updated="updateDescription". You can just directly update the data by doing v-on:content-updated="description = $event". The $event has the parameter you defined for the function inside the component - the newContent parameter.
Hope I explained things clearly. This whole thing took me 2 weeks to figure it out!!
Here's a Tinymce component for Vue.
http://jsbin.com/pucubol/edit?html,js,output
It's also good to know about v-model and custom input components:
https://v2.vuejs.org/v2/guide/components.html#Form-Input-Components-using-Custom-Events
Vue.component('tinymce', {
props: ['value'],
template: `<div><textarea rows="10" v-bind:value="value"></textarea></div>`,
methods: {
updateValue: function (value) {
console.log(value);
this.$emit('input', value.trim());
}
},
mounted: function(){
var component = this;
tinymce.init({
target: this.$el.children[0],
setup: function (editor) {
editor.on('Change', function (e) {
component.updateValue(editor.getContent());
})
}
});
}
});
<tinymce v-model="whatever"></tinymce>
Try this:
Vue.directive('editor', {
twoWay: true,
params: ['body'],
bind: function () {
tinyMCE.get('editor').setContent(this.params.body);
var that = this;
tinyMCE.get('editor').on('change', function(e) {
that.vm.body = this.getContent();
});
}
});
The trick was storing the directive in the temporary variable "that" so you could access it from within the change event callback.
There is now an npm package which is a thin wrapper around TinyMCE, making it easier to use in a Vue application.
It is open source with code on GitHub.
Installation:
$ npm install #tinymce/tinymce-vue
Usage:
import Editor from '#tinymce/tinyme-vue';
Templates:
<editor api-key="API_KEY" :init="{plugins: 'wordcount'}"></editor>
Where API_KEY is your API key from tiny. The init section is the same as the default init statement except you do not need the selector. For an example see the documentation.

Categories