Added vuejs variable to html tag - vue.js

I am trying to use this dropdown list
https://bootstrap-vue.js.org/docs/components/collapse/
<div>
<b-btn v-b-toggle.collapse1 variant="primary">Toggle Collapse</b-btn>
<b-collapse id="collapse1" class="mt-2">
<b-card>
<p class="card-text">Collapse contents Here</p>
</b-card>
</b-collapse>
</div>
but instead i'm using a v-for to create multiple drop down boxes. Obviously I need a unique identifier to distinguish which drop down was clicked. Which is this code v-b-toggle.collapse1 and id=collapse1.
I can get the id to work with v-bind:id but I don't know how (Or if it's possible) to add my custom variable to v-b-toggle.collapse1.
Here is what I am trying to do:
<div role="tablist" class="client_contacts">
<h2>Clients</h2>
<div v-for="clients in getClientContacts">
<b-btn block href="#" v-b-toggle.{{clients.id}} variant="info" role="button">
{{ clients.first_name }} {{ clients.last_name }}
</b-btn>
<b-collapse v-bind:id="clients.id" accordion="my-accordion" role="tabpanel">
<p class="card-text">
Some test text
</p>
</b-collapse>
</div>
</div>
Is it possible to use variables in tags without an id, class, href etc tag?
Thanks

This works for me.
<div v-for="clients in getClientContacts">
<b-btn block href="#" v-b-toggle="'accordion-' + clients.first_name" variant="info">
{{ clients.first_name }} {{ clients.last_name }}
</b-btn>
<b-collapse :id="'accordion-' + clients.first_name" accordion="my-accordion" role="tabpanel">
<p class="card-text">
I start opened because <code>visible</code> is <code>true</code>
</p>
</b-collapse>
</div>
https://github.com/bootstrap-vue/bootstrap-vue/issues/1420

Related

Vue JS: How to make two Vue Instances to work together on the same page?

I created a recipe website, you can find it here https://hungry-vegetarian.com/.
The tab on the index page is a vue instance. I'm trying to create a search bar that is also a vue instance.
The problem occurs when I try to display searched recipes on the index page. It just shows the search result on top of the search bar.
Ideally, only searched recipes should appear on the tab just like they are now but without any indications on top of the tab like Breakfast, Salad, Bakery, etc.
I don't know how to make two objects work together. For now, they work separately without communicating with each other.
SEARCH
<div id="search">
<div class="main-search">
<h1 class="search-question">What are you in the mood for?</h1>
<div class="search-box">
<input type="text" v-model="searchQuery" class="input-search" placeholder="Bread">
<button class="btn-search"><i class="fa fa-search"></i></button>
</div>
</div>
<div class="container">
<div class="recipe" v-for="post in filteredList">
<div v-if="searchQuery">
<a v-bind:href="post.url" class="recipe-card__card-link" target="_blank">
<img v-bind:src="post.image" alt="" class="recipe-card__image"/>
<div class="recipe-card__text-wrapper">
<h2 class="recipe-card__title">{{post.name}}</h2>
<div class="recipe-card__details-wrapper">
<p class="recipe-card__excerpt">{{post.body}}</p>
<a v-bind:href="post.url" class="recipe-card__read-more">Read more <i class="fa fa-arrow-right"></i></a>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
</div>
tab
<main id="tab">
<header>
<nav>
<ul>
<div id="arrow">
<span></span>
<span></span>
<span></span>
</div>
<li v-for="(tab, tabName) in tabs" :key="tabName">
<button class="tab" #click="setTabActive(tabName)" :class="{'active': tabName === activeTab}">
<span class="tab-copy">{{ tabName }}</span>
<span class="tab-background">
</span>
</button>
</li>
</ul>
</nav>
</header>
<article>
<div class="container">
<transition name="fade" mode="out-in" appear :duration="500">
<tab-content v-for="(tabContent, t) in tabs" :data="tabContent" :key="'content'+t" v-if="t === activeTab" inline-template>
<div class="content-wrapper">
<div class="recipes" v-for="(recipe, i) in data.recipes" :key="i">
<a v-bind:href="recipe.url" class="recipe-card__card-link"></a>
<img :src="recipe.image" alt="" class="recipe-card__image">
<div class="recipe-card__text-wrapper">
<h2 class="recipe-card__title">{{recipe.name}}</h2>
<div class="recipe-card__details-wrapper">
<p class="recipe-card__excerpt">{{recipe.body}}</p>
<a v-bind:href="recipe.url" class="recipe-card__read-more">Read more <i class="fa fa-arrow-right"></i></a>
</div>
</div>
</div>
</div>
</tab-content>
</transition>
</div>
</article>
</main>
I tried to combine instances search and tab into just one instance tab, but it always gives me a Vue warning:
[Vue warn]: Property or method "searchQuery" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property.
Also, I feel like I can have just the wrong approach to this problem I am trying to solve. Please, any suggestions are welcome. I am stuck.

Alternating v-for DOM elements on same level

I am trying to have two alternating loops after each other on the same level. If I wrap it in a parent element and loop thru it brakes the styles.
Here is an example of what I am trying to do:
<div v-for="category in items" class="cat-name">{{ category.name }}</div>
<div v-for="category in items" class="cat-meta">{{ category.metaData }}</div>
Wanted Result:
<div class="cat-name">name1</div>
<div class="cat-meta">metadata1</div>
<div class="cat-name">name2</div>
<div class="cat-meta">metadata2</div>
<div class="cat-name">name3</div>
<div class="cat-meta">metadata3</div>
and so on...
I really hope that this is possible since it completely breaks the styles when I tried:
<div v-for="category in items">
<div class="cat-name">{{ category.name }}</div>
<div class="cat-meta">{{ category.metaData }}</div>
</div>
Really appreciate any help and input.
Thanks, -J
You could wrap both your elements in a template tag.
Unlike a basic tag, this one will not be rendered in the DOM.
<template v-for="category in items">
<div class="cat-name">{{ category.name }}</div>
<div class="cat-meta">{{ category.metaData }}</div>
</template>

All tab elements are active when using uk-tab with Vue.js

I am using getuikit's tab component ( https://getuikit.com/docs/tab ) in my Vue-App:
Now I see that every tab is active, if I use v-for to iterate through an array.
<ul class=" uk-tab-left" uk-tab>
<li v-for="test in tests" id="test">{{ test }}</li>
</ul>
In my codepen example you can see, that the class uk-active is always inserted automatically:
https://codepen.io/spqrinc/pen/Ydzbez
Is there a possibility to change this behavior?
You can add a empty li element before the loop to make sure the active class will not be added to the others.
Don't forget to add a key to the loop and bind the id.
<div id="app">
<div>
<div uk-grid>
<div class="uk-width-1-4#m">
<ul class=" uk-tab-left" data-uk-tab>
<li></li>
<li v-for="test in tests" :key="test" :id="test">
{{ test }}
</li>
</ul>
</div>
</div>
</div>
</div>
<div id="app">
<div>
<div uk-grid>
<div class="uk-width-1-4#m">
<ul class=" uk-tab-left" data-uk-tab>
<template v-for="test in tests">
<li :key="test" :id="test">
{{ test }}
</li>
</template>
</ul>
</div>
</div>
</div>
</div>

Vue v-else without corresponding v-if

What is my code failing to compile v-else used on element <div> without corresponding v-if. ?
In the <div class="card">, I want to conditionally render the input and also show either the editor-container or ql-editor.
<template>
<li
class="component composition">
<div
v-if="editable == true"
class="drag-handle">
<icon-drag-handle></icon-drag-handle>
</div>
<div class="card">
<input
v-if="component"
#keypress="setUnsaved(true); autosave($event, "title", editorTitleId)">
</input>
<div
v-if="editable==true"
#keypress="setUnsaved(true); autosave($event, "content", editorContentId)"
class="editor-container">
</div>
<div
v-else
v-html="compositionContentHTML"
class="ql-editor">
</div>
</div>
<div
v-if="editable == true"
class="component-actions">
<a #click.prevent.stop="deleteComponent">
<icon-times></icon-times>
</a>
</div>
</li>
</template>

Bind a click event to a :title in Vue

So I'm trying to bind the click event so it only runs when the actually href title is clicked on. here is my code.
<collapse :multiple-active="false">
<div v-for="(campaign, index) in allCampaigns" :key="index">
<collapse-item :title="campaign.campaign_name" #click.native.prevent="grabClientFacebookData(campaign.id)">
<div v-if="spinner == true" style="text-align: center"><img src="../../../../img/spinner.gif"></div>
<div v-if="search == true">
<vue-good-table
:columns="columns"
:rows="tableData"
styleClass="vgt-table striped bordered"/>
<highcharts :options="chartOptions"></highcharts>
</div>
</collapse-item>
</div>
</collapse>
And here is the parent element:
<div class="card card-plain">
<div role="tab" id="headingOne" class="card-header">
<a data-toggle="collapse"
data-parent="#accordion"
:href="`#${itemId}`"
#click.prevent="activate"
:aria-expanded="active"
:aria-controls="`content-${itemId}`">
<slot name="title" #click.prevent="grabClientFacebookData(campaign.id)">
{{title}}
</slot>
<i class="now-ui-icons arrows-1_minimal-down"></i>
</a>
</div>
<collapse-transition :duration="animationDuration">
<div v-show="active"
:id="`content-${itemId}`"
role="tabpanel"
:aria-labelledby="title"
class="collapsed">
<div class="card-body">
<slot></slot>
</div>
</div>
</collapse-transition>
I am fairly new to vue and was wondering if it's possible. My problem is that the click event shoots whenever any port of the collapse is clicked, not just the title.
have you tried wrapping {{title}} in a span with the event bound to that? i.e.
<span #click.prevent="grabClientFacebookData(campaign.id)">{{title}}</span>