VueJS import and parse CSV (frontend only) - vue.js

can you please share a working example of parsing CSV file from client?
I can't seem to find any working example at all ...
I have been playing around with vue-papa-parser and vue-csv-import but can make it work :(
Here is my component file (using the latter package):
<template lang="html">
<div class="container">
<h1 class="h2">CSV Upload</h1>
<div class="dragndrop text-muted d-flex flex-column justify-content-center align-items-center border border-secondary">
<vue-csv-import
v-model="csv"
:fields="{name: {required: false, label: 'Name'}, age: {required: true, label: 'Age'}}"
>
<vue-csv-toggle-headers></vue-csv-toggle-headers>
<vue-csv-errors></vue-csv-errors>
<vue-csv-input></vue-csv-input>
<vue-csv-map :auto-match="false"></vue-csv-map>
</vue-csv-import>
</div>
</div>
</template>
<script>
import { VueCsvImport } from 'vue-csv-import';
export default {
name: "CSVUpload",
components: {
VueCsvImport
},
data() {
return {
csv: null
}
},
methods: {
}
}
</script>
<style lang="css" scoped>
.dragndrop {
background-color: #f5f5f5;
height: 50vh;
width: 80%;
margin: 2.5em auto;
}
</style>
but on the console I am getting this:
[Vue warn]: Error in render: "TypeError: Cannot read property 'VueCsvImportData' of undefined"
found in
---> <VueCsvImport>
<CallRecordUpload> at src/components/admin/Upload/Upload.vue
<Home> at src/components/Home.vue
<App> at src/App.vue
<Root>
and thus I cannot even see any INPUT TYPE="FILE" to try to upload ... there is something wrong with the vue-csv-import :(
any thoughts?
EDIT: SOLVED
I had to install lower version (v4 is for vue3 only!)
npm install vue-csv-import#2.3.4 --save
works for me great!
thx #marsnebulasoup for the tip !!

bad version .. it automatically uses the latest version 4 (which is for vue3 only .. for vue2 I had to use 2.3.4 and it worked great :) )
see the changelog

Related

Tailwind color not working on dynamic classes Vue + Vite

First time Im using tailwind and I can't figure out why colors are not working. This is a fresh install of Laravel Jetstream which comes with Tailwind, Vue3, Vite & Inertia.
seems like the relevant styling is not imported from tailwind if classes are added dynamically.
Here's some basic component
<template>
<div :class="style" class="border-l-4 p-4" role="alert">
<p><slot name="headline"></slot></p>
<p class="pt-3" v-if="slots.error"><span class="font-bold">Message:</span><slot name="error"></slot></p>
<div class="my-3" v-if="slots.info"><slot name="info"></slot></div>
</div>
</template>
<script setup>
import { useSlots } from 'vue'
const slots = useSlots()
</script>
<script>
export default {
name: 'Alert',
props: {
color: {type: String, default: 'red'}
},
computed: {
style() {
return `bg-${this.color}-100 border-${this.color}-500 text-${this.color}-700`
}
}
}
</script>
and using something like this does not have any color related styling although the class is there
<Alert color="orange" class="my-5">
<template #headline>Test</template>
</Alert>
but if the dynamic classes are also specified somewhere in the same page then everything works.
i.e.
<div class="bg-orange-100 border-orange-500 text-orange-700"></div>
<Alert color="orange" class="my-5">
<template #headline>Test</template>
</Alert>
This was relatively an easy fixed, it was mentioned in here to avoid constructing class name dynamically
https://tailwindcss.com/docs/content-configuration#dynamic-class-names
so, in the computed style I just specify full class name conditionally with all the possible values
changed from this.
style() {
return `bg-${this.color}-100 border-${this.color}-500 text-${this.color}-700`
}
to this
style() {
const styles = {
default : 'bg-cyan-100 border-cyan-500 text-cyan-700',
red : 'bg-red-100 border-red-500 text-red-700',
orange: 'bg-orange-100 border-orange-500 text-orange-700',
green: 'bg-green-100 border-green-500 text-green-700',
blue: 'bg-blue-100 border-blue-500 text-blue-700',
}
return styles[this.color] ?? styles.default
}
now everything works perfectly
The method I always use is to simply put in all the possible classes inside the file when dealing with some basic dynamic classes. I noticed that even if the classes are specified in commented lines, tailwind still import the styling of those classes when found inside any file
here's an example
<template>
<div :class="`bg-${color}-100 border-${color}-500 text-${color}-700`" class="border-l-4 p-4" role="alert">
test
</div>
</template>
<script>
/* all supported classes for color props
bg-red-100 border-red-500 text-red-700
bg-orange-100 border-orange-500 text-orange-700
bg-green-100 border-green-500 text-green-700
bg-blue-100 border-blue-500 text-blue-700
*/
export default {
name: 'Alert',
props: {
color: {type: String, default: 'red'}
}
}
</script>
So now all these would work fine
<Alert color="red"></Alert>
<Alert color="orange"></Alert>
<Alert color="green"></Alert>
<Alert color="blue"></Alert>
but this one wont have any styling as the generated classes for purple are not pre specified in any files
<Alert color="purple"></Alert>

How to load a q-img using a relative path from an object?

My Vue 3 / TypeScript app is using Quasar. I have an object holding the relative path to my images, and I'm trying to use that to load the relative path for a quasar q-img.
Here is the example code:
<template>
<q-page class="flex flex-center">
<q-item-section
v-for="(plan, index) in plans"
:key="index"
:class="plan.class"
class="col"
>
<q-img :src="plan.imageSrc" style="margin: auto; max-width: 64px" />
</q-item-section>
</q-page>
</template>
<script setup lang="ts">
const plans = [
{
imageSrc: "~/src/assets/paper-plane.png",
monthlyPrice: "699",
class: "starter",
},
{
imageSrc: "~/src/assets/airport.png",
monthlyPrice: "2,789",
class: "growth",
},
];
</script>
It should display the image at the relative path found at plan.imageSrc but no images are shown.
And the console also throws these errors:
http://localhost:8080/~/src/assets/paper-plane.png 404 (Not Found)
http://localhost:8080/~/src/assets/airport.png 404 (Not Found)
Also I tried using require as per below, and it also does not work:
<q-img :src="require(plan.imageSrc)" style="margin: auto; max-width: 64px" />
It throws console errors like this:
Error: Cannot find module '~/src/assets/paper-plane.png'
What am I doing wrong?
I'm able to dynamically load assets from /src/assets in a <q-img> using import.meta.url, like explained on https://vitejs.dev/guide/assets.html#new-url-url-import-meta-url
const plans = [
{
imageSrc: new URL('../assets/paper-plane.png', import.meta.url).href,
monthlyPrice: "699",
class: "starter",
},
{
imageSrc: new URL('../assets/airport.png', import.meta.url).href,
monthlyPrice: "2,789",
class: "growth",
},
];

d3 graph rendering with vue

Because of non compatible dependencies, I have to downgrade from vue3 to vue2.
I have created a force directed graph with D3 library. Everything worked find with vue3 using composition api. I am not familiar with vue 2 and adapting my graph to vue2 has not been working out for me.
In vue3 it was very straitforward and ref() made it pretty easy to accomplish.
As for vue2, I have tried making good use of lifecycle hooks such as computed and watch
Any help is more than welcome
Here is a minimalistic representation of my working component in vue3. This component creates the graph in a svg and then renders it in the template.
<template>
<div class="col" style="position: absolute; width:100%; height:100%" >
<div class="main-map-container" style="overflow: hidden; width: 100%;">
<div ref="graph" class="canvas">
</div>
</div>
</div>
</template>
<script >
import {onMounted, onBeforeMount, ref} from 'vue'
export default {
setup(){
const graph = ref()
const links = [{src:"Amazon",target:"Aurora"},{src:"Amazon",target:"Aurora"},{src:"Amazon",target:"Zoox"},{src:"Amazon",target:"Rivian"}]
const nodes = [{id:"Amazon"},{id:"Aurora"},{id:"Zoox"},{id:"Rivian"}]
onBeforeMount( async ()=>{
const svgobj = ForceGraph(nodes, links)
graph.value.appendChild(svgobj);
})
function ForceGraph(
nodes,
links
){
// The code for the graph has been removed since it is much too long
return Object.assign( svg.node() );
}
return { graph }
}
}
</script>
<style></style>
This is the vue2 component that i have emptied for this post
<template>
<div class="col" style="position: absolute; width:100%; height:100%" >
<div class="main-map-container" style="overflow: hidden; width: 100%;">
<div ref="graph" class="canvas">
</div>
</div>
</div>
</template>
<script>
export default {
setup(){
},
methods: {
},
watch: {
},
props: {
},
computed: {
},
created() {
},
mounted() {
},
updated(){
},
data() {
return {
}}
}
</script>
<style>
</style>
You can use Vue3 composition API in vue 2. Install the composition api and then just keep your code the same, with the setup method exactly as it was.
The setup method, lifecycle hooks, and all the reactivity (refs and reactive objects) are made available to you, with very few incompatibilities.
We use d3 with Vue2 in this fashion all the time. 100% compatible.
https://github.com/vuejs/composition-api

How to include external html in Nuxt app from object in js file with http url provided by bot constructor?

I try to include a bot developed with landbot.io in my nuxt web app (NUXT.js framework).
Below, there is the code that the landbot's guide provides me.
Code to include:
<script src="https://static.landbot.io/landbot-widget/landbot-widget-1.0.0.js"></script>
<div id="myLandbot" style="width: 100%; height: 500px"></div>
<script>
var myLandbot = new LandbotFrameWidget({
container: '#myLandbot',
index: 'https://landbot.io/u/..../index.html',
});
</script>
But i don't know what i should do with the second script tag because i always get this error:
"LandbotFrameWidget do not definied"
I include the first script tag in nuxt.config.js like that:
head: {
script: [
{ src: 'https://static.landbot.io/umicore/UmiAccessPoint.js' },
{ src: 'https://static.landbot.io/landbot-widget/landbot-widget-1.0.0.js' }
]
}
Your nuxt.config.js config is correct, but the first script src is not needed.
I've created a working example in this codesandbox, take a look at the code used in the index.vue file:
<template>
<section>
<div>
<div id="myLandbot" style="width: 100vw; height: 100vh"></div>
</div>
</section>
</template>
<script>
export default {
mounted() {
var myLandbot = new LandbotFrameWidget({
container: "#myLandbot",
index: "https://landbot.io/u/H-117144-ZGUSSI5IM2OI5NYH/index.html"
});
}
};
</script>
Hope it helps!

GSAP implementing to Vue.js app with webpack

i have a problem with implementing GSAP to my vue.js app which i created with vue-cli and webpack
What i wanna do?
1- I tried to create tween beforeComponent mounting, in some function.
What i tried?
1- I create my vue app,
2- I already installed this package, with:
npm install greensock --save
everything is was okey with installation, then;
3- I imported TweenMax to main.js with this way:
import { TweenMax } from 'greensock';
4- I created some div into my component for animating with TweenMax.
5- I create some functions into methods of my component which wrapping the Tween,
methods: {
animate: function() {
TweenMax.to(".rect", 1, {x:100, alpha:0, ease:Sine.easeIn});
console.log('test');
}
},
and then i call this function on before mounting component;
beforeMount(){
this.animate()
}
so my tween not working, i'm not getting some error in my console.
I print the console.log("test"); for testing the function is work or not?.
result is function work. I'm getting the test message on console. But tween is no there :) .
Where i make mistake ?
Fully code of my component:
<template>
<div class="container">
<div class="home">
<h1>
HELLO
</h1>
<h4>
How are u doing?
</h4>
</div>
<div class="rect">
</div>
</div>
</template>
<script>
export default {
name: 'Home',
methods: {
animate: function() {
TweenMax.to(".rect", 1, {x:100, alpha:0, ease:Sine.easeIn});
console.log('test');
}
},
beforeMount(){
this.animate()
}
}
</script>
<style lang="scss">
.rect {
background-color:blue;
width: 10vw;
height: 100px;
position: absolute;
z-index: -1;
}
</style>
FIX . ///////////
While i wait to answer :) found the solution myself,
everything is fine with code, just need to call function not on beforeMount(), need to call it on mounted();