Bootstrap Dropdown Button Changes Position - javascript

I was following the documentation found here: https://getbootstrap.com/docs/4.1/components/dropdowns/
and added the following dropdown button:
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Example 1</button>
</div>
The issue I'm having is that when the button is clicked on to display the dropdown-menu, the button changes it's position. This happens with both dropdown buttons I have.
Buttons Without Dropdown Clicked
Dropdown Clicked & Button Changed Position Example 1
Dropdown Clicked & Button Changed Position Example 2
You can see example code of this issue occurring: https://codepen.io/danfuentes/pen/MWaYOgz
How can I get it so that the button stays in place with the menu items appearing below it?

Surround your elements in a parent div element with btn-grp class like so:
<div class="btn-group" role="group">
<button id="btnGroupDrop1" type="button" class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</button>
<div class="dropdown-menu" aria-labelledby="btnGroupDrop1">
<a class="dropdown-item" href="#">Dropdown link</a>
<a class="dropdown-item" href="#">Dropdown link</a>
</div>
</div>

You will need to provide the HTML that surrounds the button element along with the css for all of those elements.
Can you update your question with this information so that we can see what's going on beyond just the button tag?
Update after seeing codepen:
You had a couple of div tags in the incorrect place, please see below for the solution:
<div class="btn-group">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Example 1</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu2">
<a class="dropdown-item" href="#">Dropdown tesdt</a>
<a class="dropdown-item" href="#">Dropdown 2</a>
<a class="dropdown-item" href="#">Dropdown 3</a>
<a class="dropdown-item" href="#">Dropdown 4</a>
<a class="dropdown-item" href="#">Dropdown 5</a>
</div>
</div>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Example 2</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenu2">
<a class="dropdown-item" href="#">Dropdown 1</a>
<a class="dropdown-item" href="#">Dropdown 2</a>
<a class="dropdown-item" href="#">Dropdown 3</a>
<a class="dropdown-item" href="#">Dropdown 4</a>
<a class="dropdown-item" href="#">Dropdown 5</a>
</div>
</div>
<button type="button" class="btn btn-primary" onclick="#">Regular Button 1</button>
<button type="button" class="btn btn-primary" onclick="#">Regular Button 2</button>
</div>
Basically you want to wrap all of your buttons within a single div with a class of "dropdown".
The dropdown class declares the css position:relative which will ensure the positioning is correct for the dropdowns to display correctly without shifting other elements on the page around.
Update 2: I've updated the HTML above to resolve the new problem you encountered. You will need to wrap the individual dropdowns in div's with the class of "dropdown" to ensure they can have individual links. To make sure they do not shift from their intended positions all of the buttons are now wrapped in a div with the class of "btn-group".
The "btn-group" class ensures the position is set to relative however by default it introduces a few other styling quirks such as removing the spacing between the buttons. In order to override this I've also added the following to the css:
button {
margin: 10px !important
}
The above grabs all buttons on the page and gives them an all-round margin of 10px.
If you want to overwrite any bootstrap class stylings you will need to set the !important property on those elements.
Codepen with the solution:
https://codepen.io/pen/pojvprg

Related

How to prevent event bubbling in blazor server side?

In my blazor server side application I have cards representing datasets, which the user can manage.
They look like this:
The relevant code looks like this:
<div class="card h-100 text-dark" #onclick="() => OnDatasetSelected(dataset)">
<!-- header image -->
<div class="card-body position-relative">
<div class="dropdown dropstart">
<button type="button" data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-three-dots-vertical"></i>
</button>
<ul class="dropdown-menu">
<!-- menu content -->
</div>
<!-- card content -->
</div>
As one can see from the code, I'm currently adding the context menu (three vertical dots) using the template code from bootstraps dropdown (dropleft in my case) component.
This works fine - or rather it would if it weren't for the #onclick event on the card, which calls the code to select the dataset and navigate to another page.
Question basically is: How can I prevent the OnClick event, if an element inside is being clicked on. I guess, what I'm asking is: How can I prevent event bubbling in HTML? Is it possible without adding code to the inner dropdown element (display of bootstrap-dropdowns is done with popper.js, which is external)
Lol, found the answer here 5 minutes after posting:
Simply use onclick="event.stopPropagation();" to prevent the event bubbling.
So in the end I just add this to the dropdown container:
<div class="dropdown dropstart position-absolute top-0 end-0 " onclick="event.stopPropagation();">
<button type="button" class=" btn btn-outline-secondary fs-5 p-0 m-2 border-0"
data-bs-toggle="dropdown" aria-expanded="false">
<i class="bi bi-three-dots-vertical"></i>
</button>
<ul class="dropdown-menu">
<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>
And now I can click my menu button:
Important Edit:
In case you have issues with onclick="event.stopPropagation();" preventing the #onclick event of the inner button to be fired, one can use the following directly at the inner button:
<button type="button" #onclick="MyFunction"
#onclick:stopPropagation="true">
Button Text
</button>
This will call MyFunction when clicking the button, but prevents the event to be propagated to the parent elements.

Multiple Bootstrap dropdown in same div class

Is it possible to have multiple dropdown menus in the same nav class in bootstrap, without putting each menu item in a separate div?
What is happening is that when I click on the dropdown menu , the same dropdown opens up every time( I have two dropdowns for two separate menu items)
I have tried using data-target to open only the dropdown with a specific id but this returns a console error.
<nav>
<a>Menu item 1</a>
<a>Menu item 2</a>
<a class="dropdown dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Menu item 3(dropdown menu 1)</a>
<div class="dropdown-menu" aria-labelledby="dropdown">
<a class="dropdown-item" href="/">dropdown item 1</a>
</div>
<a class="dropdown dropdown-toggle" href="#" style= "display:none;" id="certdropdown" data-toggle="dropdown" data-target="#dropdown2" aria-haspopup="true" aria-expanded="false">Menu item 3 ( dropdown menu 2)</a>
<div class="dropdown-menu" aria-labelledby="dropdown" id ="dropdown2">
<a class="dropdown-item" href="/">dropdown item 1</a>
</div></nav>
If i separate both menu items in separate div, it works but my css gets ruined
No, it's not possible to have two dropdown menus inside the same div. They need to be separated since the code to toggle them looks for the first element in the parent div of the button/anchor. So if they are in the same parent div only the first will be toggled.
Since you haven't provided what part of your CSS gets ruined, I'm gonna guess two problems you might encounter with this.
The dropdown buttons gets wrapped to the next row.
You're selecting links inside your nav by doing nav > a, which ignores the links inside the <div class="dropdown"></div> or you're selecting links inside your nav by doing nav a, which includes the links inside the dropdown-menu.
First solution:
If your dropdown buttons/links gets placed on their own row, it's because they have the display value of block. Add the class d-inline to the <div class="dropdown"> to fix this.
Second solution:
Select and style your links inside the nav with this code:
nav a:not(.dropdown-item) {
// styling
}
This will ignore the links inside the dropdown but style all other links.
If you're having some other problem with your CSS please explain what it is and I will try to help you.
The suggestion here looks good. Essentially, you need to use btn-groups, as shown in this example and just above it in the docs.
Using your code with the display none style and the unnecessary id taken off of the second dropdown:
<nav>
<a>Menu item 1</a>
<a>Menu item 2</a>
<div class="btn-group">
<a class="dropdown dropdown-toggle" href="#" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Menu item 3(dropdown menu 1)
</a>
<div class="dropdown-menu" aria-labelledby="dropdown">
<a class="dropdown-item" href="/">dropdown item 1</a>
</div>
</div>
<div class="btn-group">
<a class="dropdown dropdown-toggle" href="#" id="certdropdown" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Menu item 3 ( dropdown menu 2)
</a>
<div class="dropdown-menu" aria-labelledby="dropdown">
<a class="dropdown-item" href="/">dropdown item 1</a>
</div>
</div>
</nav>
You can read more specifics about button groups here.

Bootstrap dropdown not working when parent has a click event

I have a Bootstrap dropdown menu inside a container that triggers an event--the way I want it to work is, if you click the dropdown button, the menu items are displayed as normal. If you click anywhere else within the container, the parent event should be triggered (in this case displaying a Javascript alert). Instead, the event is being triggered even when I click the dropdown button.
Is there some way I can get the dropdown click event to "override" its parent event, so that if it's clicked its own evnet will be triggered the parent event won't?
<div class='main-container' onClick='alert("a thing was clicked!")'>
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown button
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Action 1</a>
<a class="dropdown-item" href="#">Action 2</a>
<a class="dropdown-item" href="#">Action 3</a>
</div>
</div>
</div>
http://jsfiddle.net/0fpbcy2L/12/

Uncaught TypeError: Cannot read property 'setAttribute' of undefined at Object.onLoad

Any ideas what might be causing this error?
List of my includes:
<link rel="stylesheet" href="../../node_modules/semantic-ui/dist/semantic.min.css">
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../../node_modules/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../../node_modules/fullcalendar/dist/fullcalendar.min.css">
<script src="../../node_modules/semantic-ui/dist/semantic.min.js"></script>
<script src="../../node_modules/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="../../node_modules/moment/min/moment.min.js"></script>
<script src="../../node_modules/fullcalendar/dist/fullcalendar.min.js"></script>
HTML Element:
<div class="ui floating dropdown labeled search icon button" style="width: 95%; margin: 0 auto;" id="monthDrop">
<i class="calendar icon"></i>
<span class="text">Choose a Month</span>
<div class="menu">
<div class="item">January</div>
<div class="item">February</div>
<div class="item">March</div>
<div class="item">April</div>
<div class="item">May</div>
<div class="item">June</div>
<div class="item">July</div>
<div class="item">August</div>
<div class="item">September</div>
<div class="item">October</div>
<div class="item">November</div>
<div class="item">December</div>
</div>
</div>
Script:
$('#monthDrop').dropdown();
It renders fine and everything and no errors on load, just this when I try to click on it:
We ran into the same error with the following html:
<select class="btn btn-secondary dropdown-toggle" data-toggle="dropdown" role="button" v-model="selected" aria-haspopup="true" aria-expanded="false">
<option disabled value="">Please select one</option>
<option class="dropdown-item" value="type1">Carrier</option>
<option class="dropdown-item" value="type2">Shipper</option>
</select>
We tried removing data-toggle="dropdown" from the <select> tag; the error no longer occurred, and the dropdown menu still functioned. Not sure why this works, but it got rid of the error for us. Must be a conflict somehow? Anyways, if someone else is looking for a solution, this workaround may work for them.
I got this same error in Bootstrap 4.x because my dropdown menu did not have the same parent as the dropdown button I was using.
<span class="project-sort-by">Sort by: <a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Recent</a></span>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<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>
This does not work because the dropdown.js code looks for the menu using this code:
_getMenuElement() {
if (!this._menu) {
const parent = Dropdown._getParentFromElement(this._element)
if (parent) {
this._menu = parent.querySelector(SELECTOR_MENU)
}
}
return this._menu
}
To fix this, move the menu so it has the same parent as the toggle.
<span class="project-sort-by">Sort by:
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Recent</a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<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>
</span>
CSS Frameworks
First of all you have to choose whether you're using Bootstrap 4 or Semantic-UI, because these are two different CSS Frameworks and using both of them is a mess.
Bootstrap 4
Assuming you choose Bootstrap 4 as it's simpler and easier to learn especially for the beginners (but of course you can choose Semantic-UI, Foundation or any other if you'd like) you should have these two scripts inside your code: jQuery and Popper.js.
From Bootstraps Documentation:
Many of our components require the use of JavaScript to function. Specifically, they require jQuery, Popper.js, and our own JavaScript plugins.
Dropdown
Again, as you can find in docs:
Dropdowns are built on a third party library, Popper.js, which provides dynamic positioning and viewport detection. Be sure to include popper.min.js before Bootstrap’s JavaScript or use bootstrap.bundle.min.js / bootstrap.bundle.js which contains Popper.js. Popper.js isn’t used to position dropdowns in navbars though as dynamic positioning isn’t required.
When you decide which CSS Framework you'd like to use you'll be able to set your Dropdowns in a proper way. Just to have better point of view you should also look into Semantic-UI Documentation about Dropdown.
NodeJS Environment != Browser JavaScript Environment
As I can see you install your scripts through npm, but I'm now sure if it is intended by you. In shorthand:
npm is a package manager for Node.js packages
I'm guessing that what you're trying to do is to have simple versions of these packages just in your local folders like ./project_name/javascript/bootstrap.js or ./project_name/css/bootstrap.min.css and there's no need for you right now to have node_modules. But, again, of course you can have it like this if you'd like.
You can find a lot of useful comments about Node and JavaScript here.
The error happens because you are misplacing the elements. None of the answer above solved for me.
Wrong placement 1
<span class="project-sort-by">Sort by: <a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Recent</a></span>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<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>
Wrong placemement 2
<span class="project-sort-by">Sort by:
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Recent</a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<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>
</span>
Right placement
<span class="dropdown project-sort-by">Sort by:
<a class="dropdown-toggle" href="#" role="button" id="dropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Recent</a>
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
<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>
</span>
Removing data-toggle="dropdown" did not work for me as Bootstrap 4.x requires that for dropdown menus.
However in a similar issue, I figured that the third party plugin I used had a removed function called removeAttr. When I changed it with prop I worked. No more error.
Keep the semanticUI link below the bootstrap one
<link rel="stylesheet" href="../../node_modules/font-awesome/css/font-awesome.min.css">
<link rel="stylesheet" href="../../node_modules/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="../../node_modules/semantic-ui/dist/semantic.min.css">
<link rel="stylesheet" href="../../node_modules/fullcalendar/dist/fullcalendar.min.css">

Clicking caret icon inside bootstrap link does not work

Using Bootstrap v3.3.7 and jQuery v1.12.4, I am creating a component which activates a HTML popover.
Please see the code below.
Clicking the button activates the popover. However clicking the caret icon within the button does not do anything. Any idea why and how to resolve this?
Click here for the jsfiddle.
<a role="button" class="btn btn-default po" data-poc="#html1">Test 1 <span class="caret"></span></a>
<a role="button" class="btn btn-default po" data-poc="#html2">Test 2 <span class="caret"></span></a>
<div id="html1" class="hide">
<strong>This</strong> is a test!
</div>
<div id="html2" class="hide">
<strong>This</strong> is another test!
</div>
Use this
<a id="po1" class="btn btn-default" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Test <span class="caret"></span></a>
click here

Categories