Get child element on click - Vue JS - javascript

I need an equivalent of jQuery "this.find()" to get child element from this section on click.
So on click="showProd(6) I want to find "this .dropProd" inside a method ":
Image
<div class="sections" #click="showProd(6)">
<h2 class="padding-10">Limited Shelf Life</h2>
<div class="dropProd" :class="{ activate : active_el == 6}">
<div v-for="item in shelf" :key="item.id" class="niceBox">
<p class="prod_title">{{item.title}}</p>
<p class="prod_info">{{item.product_details}}</p>
</div>
</div>
</div>

You can use $refs:
<div class="sections" #click="showProd(6)">
<h2 class="padding-10">Limited Shelf Life</h2>
<!-- note the ref attribute below here -->
<div ref="dropProd" class="dropProd" :class="{ activate : active_el == 6}">
<div v-for="item in shelf" :key="item.id" class="niceBox">
<p class="prod_title">{{item.title}}</p>
<p class="prod_info">{{item.product_details}}</p>
</div>
</div>
</div>
Access it in <script> via this.$refs.dropProd

You could just use this.$refs with an appropriate reference name inside your function like this:
new Vue({
el: '#app',
data: function() {
return {
}
},
methods: {
showProd(){
console.log(this.$refs.referenceMe);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div class="sections"style="background-color: red" #click="showProd(6)">
<h2 class="padding-10">Limited Shelf Life</h2>
<div class="dropProd" ref="referenceMe">
</div>
</div>
</div>

Related

Vue.js: Textarea inside v-for loop is not working

v-model value inside v-for loop is not unique.
This is my template:
<template>
<div
id="FAQ"
v-for="(question, index) in questions.slice().reverse()"
:key="index"
class="m-2 col-7"
>
<div v-if="getloggedUser.role == 'tutor'">
<div id="divQuestion">
<p class="m-5">{{ question.text }}</p>
</div>
<div id="divAnswer" class="mt-2">
<p class="m-2">{{ question.answer }}</p>
</div>
</div>
<div v-else>
<div id="divQuestion">
<p class="m-5">{{ question.text }}</p>
</div>
<div id="divAnswer" class="mt-2">
<p class="m-2">{{ question.answer }}</p>
</div>
<div v-if="question.answer == null" id="divPsycAnswer">
<textarea cols="60" rows="3" style="border-radius:12px" v-model="answer.text"></textarea>
<button id="btnSend" #click="publishAnswer(question.id)">Responder</button>
</div>
</div>
</div>
</template>
This is the script (data):
data() {
return {
// arrayFAQ: [],
form: {
text: ""
},
answer: {
text: ''
},
questions: [],
message: "",
loading: false,
id: null
}
},
This way, everytime I write in one textarea, I write for all the others. I have tried adding [index] in the v-model but there's this error: "TypeError: Cannot use 'in' operator to search for '0' in "
Try this as your v-model
<textarea v-model="answers[`text${index}`]"></textarea>
The answer object could be an empty object.
It will give you text0, text1, text2, as answer's properties.
You can add anything instead of index, like your question's id for easy access and knowing which text is from which question.

How to hide div element on hover of mouse in Vuejs?

new Vue({
el: '#mouse',
data: {
showByIndex: null
},
methods: {
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="mouse">
<div class="parent" v-for="i in 1" #mouseover="showByIndex = i" #mouseout="showByIndex = null">
<div class="child-one">
Some dummy text
</div>
<div class="child-two" v-show="showByIndex === i">
Show me only on hover on "div.parent" element
</div>
</div>
</div>
Working example:- https://codepen.io/dhanunjayt/pen/XWgyqXW
With the above code i am able to show the text, when hover of the div element. But small issue is when hover first element should not reflect.
Like following snipppet?
new Vue({
el: '#mouse',
data: {
showByIndex: null
},
methods: {
}
})
.parent {
padding: 2em;
background: violet;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="mouse">
<div class="parent" v-for="i in 1" #mouseover="showByIndex = i" #mouseout="showByIndex = null">
<div class="child-one" v-show="showByIndex === null">
Some dummy text
</div>
<div class="child-two" v-show="showByIndex === i">
Show me only on hover on "div.parent" element
</div>
</div>
</div>

Accessing v-for list item object data in vue.js

<div v-for="deck in decks" :key="deck._id" slot="content">
<div class="level">
<div class="level-left">
<div>
<p>{{ deck._id }}</p>
<p class="has-text-weight-semibold">{{ deck.title }}</p>
<p>Boards: {{ deck.board1 }}</p>
<p>Primary color: {{ deck.board1Color }}</p>
<p>
L/W/H: {{ deck.deckLength }}ft, {{ deck.deckWidth }}ft,
{{ deck.deckHeight }}ft
</p>
</div>
</div>
<div class="level-right">
<form #submit.prevent="deleteDeck">
<button type="submit" class="button">Delete</button>
</form>
</div>
</div>
<br />
</div>
I'm able to access this object's id within the v-for loop, but not in the method called by the delete button.
methods: {
deleteDeck() {
const deckId = this.deck._id;
alert(deckId);
}
}
The id of this individual deck will be passed into an axios delete request, but for now I'm just trying to figure out how to access it. this.id contains the id from the greater object that this object belongs to.
All you have to do is pass the id to the method from the template:
Template HTML
...
<form #submit.prevent="deleteDeck(deck.id)">
<button type="submit" class="button">Delete</button>
</form>
Component
methods: {
deleteDeck (id) {
alert(id)
}
}
I would pass the object in a function argument.
In the template:
<div v-for="deck in decks" :key="deck._id" slot="content">
...
<form #submit.prevent="deleteDeck(deck)">...</form>
...
</div>
And in methods:
methods: {
deleteDeck(deck) {
/* use deck here */
}
}
You must pass deck as an argument of deleteDeck :
<form #submit.prevent="deleteDeck(deck)">
<button type="submit" class="button">Delete</button>
</form>
Vue.config.productionTip = false;
new Vue({
data() {
return {
decks: [
{_id: 1,title: "Foo"},
{_id: 2,title: "Bar"}
]
};
},
methods: {
deleteDeck(id) {
this.decks = this.decks.filter(deck => deck._id !== id);
}
}
}).$mount("#app");
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="deck in decks" :key="deck._id" slot="content">
<div class="level">
<div class="level-left">
<div>
<p>{{ deck._id }}</p>
<p class="has-text-weight-semibold">{{ deck.title }}</p>
</div>
</div>
<div class="level-right">
<button #click="deleteDeck(deck._id)" class="button">Delete</button>
</div>
</div>
</div>
</div>

Displaying information using v-if from an API

I want the tag that currently says true or false, I want it to say "FREE" if it's free and say "PAID" if it's not.
https://www.eventbriteapi.com/v3/events/search/?location.address=45+Depot+Ave.++Bronx%2C+NY+10457&location.within=50mi&token=6RXWSSZPE4APEYSWTJJF
I'm getting a response from data.events.is_free in the form of a boolean that's true if free and false if not.
I know I have nothing between the v-if tags, but the whole thing goes blank if add anything.
HTML:
<div id="app" class="container">
<h1 id="header" class="title is-1 has-text-centered">Event Lookup for ECH</h1>
<div v-for="event in info">
<h2 class="title is-4" id="eventName">{{ event.name.html }} <span v-if="" class="tag is-success">{{ event.is_free }}</span></h2>
<div id="eventDescription">{{ event.description.text }}</div>
<div id="eventDateTime">{{ event.start.local }} - {{ event.end.local }}</div>
</div>
</div>
Vue / JS
// The plan is to make this more extensive later
// https://www.eventbriteapi.com/v3/events/search/?location.address=45+Depot+Ave.++Bronx%2C+NY+10457&location.within=50mi&token=6RXWSSZPE4APEYSWTJJF
// This is a random address...
const baseUrl = 'https://www.eventbriteapi.com/v3/events/search/?location.address=45+Depot+Ave.++Bronx%2C+NY+10457&location.within=50mi&token=6RXWSSZPE4APEYSWTJJF';
new Vue({
el: '#app',
data () {
return {
info: null
}
},
mounted () {
axios
.get(baseUrl)
.then(response => (this.info = response.data.events))
},
computed () {
isFree
if (response.data.events.is_free == true) {
return true;
}
else {
return false;
}
}
})
https://codepen.io/Mortiferr/pen/qyajJd
Here's a link to my Codepen.
You can use v-if and v-else.
<div id="app" class="container">
<h1 id="header" class="title is-1 has-text-centered">Event Lookup for ECH</h1>
<div v-for="event in info">
<h2 class="title is-4" id="eventName">{{ event.name.html }}
<span v-if="event.is_free" class="tag is-success">Free</span>
<span v-else class="tag is-success">Paid</span>
</h2>
<div id="eventDescription">{{ event.description.text }}</div>
<div id="eventDateTime">{{ event.start.local }} - {{ event.end.local }}</div>
</div>
</div>
You don't need a computed property for this. You can use v-if and v-else.
Alternatively, if you know that you will only have the text "FREE" or "PAID" without any markup needed, you might want to consider just using a ternary expression:
<span class="tag is-success">{{event.is_free ? "FREE" : "PAID"}}</span>
I added a cost class just to make it a little easier to see.
const baseUrl = 'https://www.eventbriteapi.com/v3/events/search/?location.address=45+Depot+Ave.++Bronx%2C+NY+10457&location.within=50mi&token=6RXWSSZPE4APEYSWTJJF';
new Vue({
el: '#app',
data() {
return {
info: null,
isFree: false
}
},
mounted() {
axios
.get(baseUrl)
.then(response => {
this.info = response.data.events;
this.isFree = response.data.events
})
}
})
.cost {
color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.min.js"></script>
<div id="app" class="container">
<h1 id="header" class="title is-1 has-text-centered">Event Lookup for ECH</h1>
<div v-for="event in info">
<!-- Using v-if/else -->
<h2 class="title is-4" id="eventName">{{ event.name.html }}
<span v-if="event.is_free" class="cost tag is-success">FREE</span>
<span v-else class="cost tag is-success">PAID</span>
</h2>
<!-- Using ternary -->
<h2 class="title is-4" id="eventName">{{ event.name.html }}
<span class="cost tag is-success">{{event.is_free ? "FREE" : "PAID"}}</span>
</h2>
<!--<div id="eventDescription">{{ event.description.text }}</div>-->
<div id="eventDateTime">{{ event.start.local }} - {{ event.end.local }}</div>
</div>
</div>

- Cannot use v-for on stateful component root element because it renders multiple elements

Getting the error the error in the title, I am new to vue.js and I cannot figure it out
Cannot debug this for the life of me, can somebody help?
const app = new Vue({
el: '#location-box',
data: {
locations: [
{
name: "Europe",
desc: "Loren ipsum"
},
{
name: "America",
desc: "Loren ipsum"
}
],
},
})
My HTML:
<div id="location-section">
<div class="main-container">
<div class="location-grid-container">
<div id="info-box" class="outline">
</div>
<div>
<div id="location-box" v-for="location in locations" class="outline">
<h1>{{location.name}}</h1>
</div>
</div>
</div>
</div>
The root element that you pass to the el option of your new Vue app must be unique, and serve only as a placeholder.
Then you can use Vue directives on its children.
So in your case you could do:
<div id="location-section">
<div class="main-container">
<div class="location-grid-container">
<div id="info-box" class="outline">
</div>
<div id="location-box"><!-- Root element for your Vue app -->
<div v-for="location in locations" class="outline">
<h1>{{location.name}}</h1>
</div>
</div>
</div>
</div>
new Vue({
el: '#location-box',
// etc.
});

Categories