How to customize bootstrap-vue dropdown menu using bootstrap-vue icon? - vue.js

I am working with vue js and bootstrap-vue. I am tring to implement bootstrap vue datatables.In the table I want to use dropdownt using tree-dot-vertical icon in the action column.
Here my table view..
My table view
In the above table the iconic dropdown menu in the action column there are two icon .One is three dot vertical icon and the other is arrow sign. I want to remove the arrow sign and border from the dropdown menu.
Here the code for dropdown menu..
<template v-slot:cell(actions)="data">
<div>
<b-dropdown id="dropdown-1" variant="outline-info">
<template #button-content>
<b-icon
icon="three-dots-vertical"
aria-hidden="true"
></b-icon>
</template>
<b-dropdown-item
variant="primary"
:to="{
name: 'QuizEditPage',
params: { id: data.item.id },
}"
>Edit</b-dropdown-item
>
<b-dropdown-item
variant="danger"
#click="deleteQuiz(data.item.id)"
>Delete</b-dropdown-item
>
</b-dropdown>
</div>
</template>
How can solve the proble?Please help.

Using no-caret solves your problem.
Note that you can replace <custom-icon /> with <b-icon icon='three-dots-vertical' />
Vue.component('customIcon', {
template: `<svg xmlns="http://www.w3.org/2000/svg" width="15.352" height="15.355" viewBox="0 0 15.352 15.355">
<path id="Union_19" data-name="Union 19" d="M-19.5-15958.5l-7.5,7.5,7.5-7.5-7.5-7.5,7.5,7.5,7.5-7.5-7.5,7.5,7.5,7.5Z" transform="translate(27.176 15966.178)" fill="none" stroke="#bbb" stroke-width="0.5"/>
</svg>`
})
new Vue({
el: "#app",
});
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap#4.5.3/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.css" />
<script src="https://unpkg.com/vue#2.6.12/dist/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.21.2/dist/bootstrap-vue.min.js"></script>
<div id="app">
<b-dropdown no-caret>
<template #button-content>
Custom Dropdown
<custom-icon /> // or any other icons for example b-icon
</template>
<b-dropdown-item>First Action</b-dropdown-item>
<b-dropdown-item>Second Action</b-dropdown-item>
</b-dropdown>
</div>

Related

Show different component conditionally if parent tag contains active class - Vue Bootstrap

I want to customize tab component's title part on Vue Bootstrap. If the tab is active, I want to show different type of tab item. Of course we can solve it by using css classes by setting .active class. But In my situation, I want to display a different component if that tab is active.
I believe this can be done using 'v-if' but I dont know how to get its tag's classes contains active class. If tab is active, I want to render a spinner component, else I only want to render name of that tab.
Do you have any idea?
<b-tabs fill>
<b-tab title="First">
<template #title v-if="active">
<b-spinner type="grow" small variant="success"></b-spinner> <b>Active Title</b>
</template>
<template #title v-else>
<b>Title</b>
</template>
</b-tab>
<b-tab title="Second">
<template #title v-if="active">
<b-spinner type="grow" small variant="success"></b-spinner> <b>Second Title</b>
</template>
<template #title v-else>
<b>Title</b>
</template>
</b-tab>
You could bind a property to <b-tabs> v-model, which will contain the index of the active tab. Then use this to check inside your v-if whether the tab is active or not.
new Vue({
el: '#app',
data() {
return {
currentTab: 0
}
}
});
<link href="https://unpkg.com/bootstrap#4.5.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://unpkg.com/vue#2.6.12/dist/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app" class="p-4">
<b-tabs v-model="currentTab" fill>
<b-tab title="First">
<template #title v-if="currentTab === 0">
<b-spinner type="grow" small variant="success"></b-spinner> <b>Active Title</b>
</template> Tab 1 content
</b-tab>
<b-tab title="Second">
<template #title v-if="currentTab === 1">
<b-spinner type="grow" small variant="success"></b-spinner> <b>Second Title</b>
</template> Tab 2 content
</b-tab>
</b-tabs>
</div>

Bootstrap vue Tab component is not working when an Index is used to navigate trough the tabs

Why this very simple bootstrap vue script does not work, on pressing the toggle button it just does not increment the value tabIndex.
tabIndex starts in 0, user presses tabIndex, value still 0.
if tabIndex is removed from disabled attribute it will work but it will not follow the purpose I require.
Script can be seen here:
https://jsfiddle.net/Xarina/tkoyph4x/1/
<div id="app">
<b-card no-block>{{tabIndex}}
<b-tabs small card ref="tabs" v-model="tabIndex">
<b-tab title="General">
I'm the first fading tab
</b-tab>
<b-tab title="Edit profile" :disabled="tabIndex < 1">
I'm the second tab
</b-tab>
<b-tab title="Premium Plan" :disabled="tabIndex < 2">
Sibzamini!
</b-tab>
</b-tabs>
</b-card>
<button #click="tabIndex++">
Click to toggle disable
</button>
</div>
You can bind a custom class to each tab using title-item-class according to the tabIndex:
window.app = new Vue({
el: '#app',
data: () => ({ tabs: [], tabCounter: 0, disabled: false, tabIndex: 0 }),
});
.disabledTab .nav-link { pointer-events: none; color: #666666; }
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap/dist/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<script src="https://unpkg.com/babel-polyfi0ll#latest/dist/polyfill.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-card no-block>{{tabIndex}}
<b-tabs small card ref="tabs" v-model="tabIndex">
<b-tab title="General">I'm the first fading tab</b-tab>
<b-tab title="Edit profile" :title-item-class="{ disabledTab: tabIndex < 1 }">I'm the second tab</b-tab>
<b-tab title="Premium Plan" :title-item-class="{ disabledTab: tabIndex < 2 }">Sibzamini!</b-tab>
</b-tabs>
</b-card>
<button #click="tabIndex++">Click to toggle disable</button>
</div>
This happens because you can't swap to a tab that's disabled. And the check happens before the index is disabled, meaning it will set the tab index back to 0.
You can get around this by using two data properties, one for disabling the tabs, and one for the <b-tabs> v-model. Then updating the property using for disabling first, and the v-model property in the a $nextTick callback.
In the example below i utilize a watcher to set the second property automatically when the other changes.
new Vue({
el: '#app',
data() {
return {
currentTab: 0,
disabledTabIndex: 0
}
},
watch: {
disabledTabIndex(newVal) {
this.$nextTick(() => {
this.currentTab = newVal;
})
}
}
});
<link href="https://unpkg.com/bootstrap#4.5.3/dist/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.min.js"></script>
<script src="https://unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.js"></script>
<div id="app">
<b-card no-block>
Current tab: {{ currentTab }}
<b-tabs small card ref="tabs" v-model="currentTab">
<b-tab title="General">I'm the first fading tab</b-tab>
<b-tab title="Edit profile" :disabled="disabledTabIndex < 1">
I'm the second tab
</b-tab>
<b-tab title="Premium Plan" :disabled="disabledTabIndex < 2">
Sibzamini!
</b-tab>
</b-tabs>
</b-card>
<button #click="disabledTabIndex++">Click to toggle disable</button>
</div>

quasar UMD in a php project

I need to create a component which can be used in a php project as well. Do I have to crate the component in vue and duplicate the same code in php page using UMD? or is there any other method?
I am testing below code in a html page but getting blank page
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/#quasar/extras/material-icons/material-icons.css">
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.min.css">
<script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar/dist/quasar.umd.min.js"></script>
<div id="q-app">
<q-layout view="hHh lpR fFf">
<q-header elevated class="bg-primary text-white" height-hint="98">
<q-toolbar>
<q-btn dense flat round icon="menu" #click="left = !left" />
<q-btn dense flat round icon="menu" #click="right = !right" />
</q-toolbar>
</q-header>
<q-drawer show-if-above v-model="left" side="left" bordered>
</q-drawer>
<q-drawer show-if-above v-model="right" side="right" bordered>
</q-drawer>
<q-page-container>
</q-page-container>
<q-footer elevated class="bg-grey-8 text-white">
<q-toolbar>
<q-toolbar-title>
Title
</q-toolbar-title>
</q-toolbar>
</q-footer>
</q-layout>
</div>
<script>
new Vue({
el: '#q-app',
data: function () {
return {
version: Quasar.version,
left: false,
right: false
}
},
methods: {
notify: function () {
this.$q.notify('Running on Quasar v' + this.$q.version)
}
}
})
</script>
It actually works.
See in action: https://codepen.io/disfated/pen/QWyYQXN
I only removed self-closed q-btn tags:
<q-btn dense flat round icon="menu" #click="left = !left"></q-btn>
<q-btn dense flat round icon="menu" #click="right = !right"></q-btn>
(You can read more on why it's needed and other caveats when using in-DOM templates, here)
Also added some content to demonstrate that everything functions well.
It appears that something from "outside world" is somehow prevents your code from working.
Take a closer look to Console and Network tabs in browser console. Something there should give you a hint about what's causing the issue.

VueJs Lazy initialization of tab's component just once

I'm trying to make the bootstrap-vue tabs initialization lazy and though it works if i set the lazy attribute on true, it render the component every time i'm visiting a specific tab:
BtabsWrapper.vue:
<b-tabs
:lazy="true"
>
<b-tab
v-for="(tab, index) in tabs"
:key="'li-tab-' + index"
:title="tab.title"
:href="'#' + tab.id"
>
<slot
:name="tab.id"
/>
</b-tab>
</b-tabs>
I need more of a lazy initialization of each tab(just once) rather than re rendering the tab's component every time the user visits it. Any ideas?
If you wrap the content of each tab in a v-if and change that condition once when they're loaded you should get your desired outcome.
And in your case if you're using a v-for, you can utilize the index in your v-for in the includes part as visitedTabs.includes(index)
window.onload = () => {
new Vue({
el: '#app',
data() {
return {
visitedTabs: []
}
},
methods: {
onInput(value) {
if(!this.visitedTabs.includes(value)){
this.visitedTabs.push(value)
}
}
}
})
}
body {
padding: 1em;
}
<link href="https://unpkg.com/bootstrap#4.3.1/dist/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://unpkg.com/bootstrap-vue#2.0.4/dist/bootstrap-vue.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.js"></script>
<script src="https://unpkg.com/bootstrap-vue#2.0.4/dist/bootstrap-vue.js"></script>
<div id="app">
<b-card clas no-body>
<b-tabs card #input="onInput">
<b-tab title="First tab">
<div v-if="visitedTabs.includes(0)">
Hello World
</div>
</b-tab>
<b-tab title="Second tab">
<div v-if="visitedTabs.includes(1)">
<b-input />
</div>
</b-tab>
<b-tab title="Third tab">
<div v-if="visitedTabs.includes(2)">
<b-checkbox />
</div>
</b-tab>
</b-tabs>
</b-card>
</div>

How to add a class and then remove that same class in the vuejs?

I have the following div:
<div class="col bg-color-red-4">
<a href="#" v-on:click="showMobileMenu = !showMobileMenu">
<i class="hamburger hamburger--3dx " v-bind:class="{ 'is-active': showMobileMenu }" >
<span class="hamburger-box">
<span class="hamburger-inner"></span>
</span>
</i>
</a>
<p>3DX</p>
</div>
data(){
return {
showMobileMenu: false
}
},
That is visually like this:
basically it's a button that allows me to open the left panel:
When you click on the button you add the class 'is-active' that allows the change of form, leaving it like this:
and it effectively opens the left panel, but after turning off the left panel, that is, returning to the view that I was in, this one finds the class added.
then I need that when I click, I change the shape to an "X", when I open the left panel, but when I come back I do not have the form "X", that is, it does not contain the class 'is-active' anymore
Beforehand thank you very much.
At first read the official docs:
[https://v2.vuejs.org/v2/guide/class-and-style.html#ad][1]
At second - check Matt Oestreich's answer
At third - you can also bind classes to the variables like this:
<div
class="static"
v-bind:class="{ active: isActive, 'text-danger': hasError }"
/>
And in a Vue.js script:
data: {
isActive: true,
hasError: false
}
You can bind to the class attribute and supply specific classes that way..
[CodePen Mirror]
Code Snippet:
const vm = new Vue({
el: "#app",
data: {
status: false,
bars: "fa fa-bars",
times: "fa fa-times",
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.10/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.5.14/vuetify.min.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/font-awesome#4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<link href="https://cdn.jsdelivr.net/npm/vuetify#1.5.6/dist/vuetify.min.css" rel="stylesheet" />
<div id="app">
<v-app>
<v-content>
<v-container>
<i
style="cursor:pointer;"
:class="status ? times : bars"
#click="status = !status"
></i>
<h1>Click The Icon</h1>
<h3>It is currently {{ status ? 'open' : 'closed' }}</h3>
</v-container>
</v-content>
</v-app>
</div>