Nuxt3 and Bootstrap 5 Dropdown: Document is not defined error - vuejs3

Is it possible to use the Bootstrap 5 dropdown component in a Nuxt 3 app?
My attempt failed with the following error:
[nuxt] [request error] document is not defined
Thus, I tried to wrap the dropdown component in a <ClientOnly> component but that did not help.
Anyone got a suggestion on how I can get the dropdown to work?
Here's my code:
https://stackblitz.com/edit/nuxt-starter-4jphlx?file=components/Dropdown.vue
App.vue:
<template>
<div>
<ClientOnly>
<Dropdown />
</ClientOnly>
</div>
</template>
Dropdown.vue:
<template>
<div class="dropdown">
<button
class="btn btn-secondary dropdown-toggle"
type="button"
id="dropdownMenuButton1"
data-bs-toggle="dropdown"
aria-expanded="false"
>
Dropdown button
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
</template>
<script setup>
import Dropdown from 'bootstrap/js/dist/dropdown.js';
</script>

Related

Bootstrap 5 with Vue and shadow dom

I am trying to use bootstrap 5 with Vuejs and shadow dom (Vue custom element). The standard bootstrap css classes work, but the bootstrap components do not seem to work.
I have tried the solution suggested in https://ilikekillnerds.com/2022/08/how-to-use-bootstrap-javascript-components-inside-of-shadow-dom-web-components/ which initializes the bootstrap 5 component properly but all the event handlers are not bound.
I have tried implementing the dropdown component by initializing the Dropdown component from bootstrap myself.
<template>
<div class="dropdown" ref="dropdown">
<button
class="btn btn-secondary dropdown-toggle"
type="button"
id="dropdownMenuButton1"
data-bs-toggle="dropdown"
aria-expanded="false"
>
Dropdown button
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuButton1">
<li><a class="dropdown-item" href="#">Action</a></li>
<li><a class="dropdown-item" href="#">Another action</a></li>
<li><a class="dropdown-item" href="#">Something else here</a></li>
</ul>
</div>
</template>
<script setup lang="ts">
import { Dropdown } from 'bootstrap'
import { ref } from 'vue'
const dropdown = ref()
let dropdownEl: Dropdown
onMounted(() => {
if (dropdown.value) {
dropdownEl = new Dropdown(dropdown.value)
}
})
The dropdown does not work(I'm assuming due to the shadow dom, this works on non-shadow dom vuejs project). Do all events like closing/opening the dropdown have to be manually implemented?

Vue Single Page Application Bootstrap 5 Nav not shrinking on mobile

I am building a Single Page Website using Vue 3, and I am using Bootstrap 5 for css. The navbar is one of the standard templates on the bootstrap examples page. My issue is that on mobile, when the collapsed navbar is exposed, it doesn't close. I assume this is because it's a single page application, and the nav holds it's state.
I would like the navbar to automatically collapse on the click of one of the router links. I have seen a number of answers on other StackOverflow threads that use Jquery, but I would like to use plain JS if possible. If there is a fix with bootstrap classes, that would also be great.
I have tried adding the data-bs-toggle and the data-bs-targetto the router links, but that just breaks the router links, and doesn't change anything.
Thanks in advance
Here is the html for the nav:
<nav class="navbar navbar-expand-lg navbar-dark fixed-top bg-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#"><img class="bike" :src="bikeSVG" /></a>
<button
type="button"
class="navbar-toggler"
data-bs-toggle="collapse"
data-bs-target="#navbarCollapse"
>
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<ul class="navbar-nav me-auto mb-2 mb-md-0">
<li class="nav-item">
<router-link to="/" class="nav-link active">Home</router-link>
</li>
<li class="nav-item">
<router-link :to="{ name: 'Events' }" class="nav-link active"
>Events</router-link
>
</li>
</ul>
<div v-if="!this.$store.state.auth.status.loggedIn">
<router-link
class="nav-item mx-2 btn btn-yellow fw-bold"
:to="{ name: 'LogIn' }"
>Log In</router-link
>
<router-link
class="mx-2 btn btn-yellow fw-bold"
:to="{ name: 'SignUp' }"
>Sign Up</router-link
>
</div>
<div v-else>
<div class="btn-group">
<button
type="button"
class="btn btn-red dropdown-toggle"
data-bs-toggle="dropdown"
aria-expanded="false"
>
Profile
</button>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<router-link
class="dropdown-item"
type="button"
:to="{ name: 'Profile' }"
>Your Profile</router-link
>
</li>
<hr />
<li><a class="dropdown-item" #click="logout">Logout</a></li>
</ul>
</div>
</div>
</div>
</div>
</nav>

Bootstrap NAVBAR item t on the left of dropdown list

this is my code:
<div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
App
App
<nav >
{% if user.is_authenticated %}
<a class="nav-link" href="#">Link 1</a>
<ul class="navbar-nav">
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{ user.username }}</a>
<div class="dropdown-menu dropdown-menu-right text-right" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="{% url 'listingfournisseur' %}">Update fournisseur list</a>
<a class="dropdown-item" href="{% url 'updatepayables' %}">Eletronic Payment</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{% url 'listingclient' %}">Update Clients list</a>
<a class="dropdown-item" href="{% url 'account_logout' %}">Log Out</a>
</div>
</li>
</ul>
{% else %}
<a class="p-2 text-dark" href="{% url 'account_login' %}">Log In</a>
<a class="btn btn-outline-primary" href="{% url 'account_signup' %}">Sign Up</a>
{% endif %}
</nav>
</div>
I m tring to have link1 item just on the left of dropdown.
I don t understand why it is up to dropdown ?
this is what I see:
thanks for help
In you nav add the CSS property display: flex and you will have it one next to the other. But after you will just have to play with the size because an tag don't have "padding" but tag have top, left and bottom "padding".
<nav class="b">
<div>ets</div>
<div><ul>test</ul></div>
</nav>
<style>
.b{
display:flex;
}
</style>

Split button dropdown aligned to first button

The images show a comparison of Bootstrap 3 and Bootstrap 4 split button dropdown alignments. I much prefer Bootstrap 3 which aligns it to the left of the first button, unlike Bootstrap 4 which aligns it only according to the second button.
Anyone have a quick solution to aligning the menus to the left of the first button?
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<!-- Example split danger button -->
<div class="btn-group">
<button type="button" class="btn btn-danger">Action</button>
<button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Separated link</a>
</div>
</div>
The dropdown automatically aligns with the base of your <button> element. The problem in your case is that you're using a 'split button dropdown', which by default makes use of two different <button> elements.
As such, you have three options.
1) Add the dropdown-menu-right class to .dropdown-menu (preferred):
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<!-- Example split danger button -->
<div class="d-flex justify-content-center">
<div class="btn-group">
<button type="button" class="btn btn-danger">Action</button>
<button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu dropdown-menu-right">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Separated link</a>
</div>
</div>
</div>
2) Only use one <button>:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<!-- Example single danger button -->
<div class="btn-group">
<button type="button" class="btn btn-danger dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Action
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Separated link</a>
</div>
</div>
3) Modify the transform that gets added to the button:
.dropdown-toggle-split + .dropdown-menu {
transform: translate(0px, 36px) !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet" />
<!-- Example split danger button -->
<div class="btn-group">
<button type="button" class="btn btn-danger">Action</button>
<button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Separated link</a>
</div>
</div>
Unfortunately transform is an inline rule, so you'll need !important for higher specificity.
The reason this is happening is because there is another transform on the element so all you need to do is override it using !important.
.dropdown-menu {
transform: translate(0px, 36px) !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.bundle.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<!-- Example split danger button -->
<div class="btn-group">
<button type="button" class="btn btn-danger">Action</button>
<button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Separated link</a>
</div>
</div>
use data-reference="parent"
see https://getbootstrap.com/docs/4.6/components/dropdowns/#dropdown-options
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/css/bootstrap.min.css" integrity="sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.6.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-Piv4xVNRyMGpqkS2by6br4gNJ7DXjqk09RmUpJ8jgGtD7zP9yug3goQfGII0yAns" crossorigin="anonymous"></script>
<div class="btn-group">
<button type="button" class="btn btn-secondary">Reference</button>
<button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" id="dropdownMenuReference" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-reference="parent">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuReference">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Separated link</a>
</div>
</div>

image background instead of button for dropdown

I already have a dropdown with the following code:
note: class='bg_r' is in CSS for the background image (url) globe
<span class="bg_r">
Language: <a id="Lang" href="#">DropUpâ–˛</a>
</span>
<div id="language_menu" class="lang_switch_panel">
<div class="lang_switch">
<ul>
<li>Action</li>
<li>Action</li>
<li>Action</li>
</ul>
</div>
</div>
The output for above code is as shown in figure 1 below:
Now, I'm doing similar to that(above figure) using bootstrap 4.But i'm not able to override the button style using background image.Instead of button type I replaced with anchor tag but of no use(its wrong method but i tried).
Following is the code I tried so far:
<span class="bg_r">
Language:
<button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropup
</button>
</span>
<!--<span class="bg_r">Language:
<a type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropup
</a>
</span>-->
<div class="dropdown-menu">
<!-- Dropdown menu links -->
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Action</a>
</div>
The output for the code using bootstrap is as shown in figure 2 below:
How can I override button type with (background) image to get output similar to figure 1?
Thanks in advance.
Add btn-link class to button
Additionally add these styles to center align it
.bg_r {
background-color: aqua;
display: inline-flex;
align-items: center;
}
or add these 2 classes d-inline-flex align-items-center to bg_r span
.bg_r {
background-color: aqua;
}
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous">
<span class="bg_r d-inline-flex align-items-center p-1">
Language:
<button class="btn btn-sm btn-link dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropup
</button>
</span>
<div class="dropdown-menu">
<!-- Dropdown menu links -->
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Action</a>
</div>
You can also use bg-transparent on the button that will remove the background-color from button, but will not remove the focus styles when you click on the button ! So preferably add btn-link class to it only.
The above answer works, or you can also replace this line
<button type="button" class="btn btn-sm dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropup</button>
by
Dropup

Resources