I want append an HTML element into a DIV, but this one do not get the proper CSS like the original ones.
I have a dropdown menu, and want append on it new <li> rows.
My HTML code:
<br/><br/>
Append it
<div class="container">
<div class="row">
<div class="col-sm-3">
<h5>Normal Dropdown Button</h5>
<div class="panel panel-default">
<div class="panel-body">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span data-bind="label">Select One</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<div id="append">
</div>
<li>Item 1</li>
<li>Another item</li>
<li>This is a longer item that will not fit properly</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<br/><br/>
My Javascript code:
$( document.body ).on( 'click', '.append', function( event ) {
$("#append").append("<li>Item 1</li>");
return false;
});
Here a live example: http://jsfiddle.net/dJDHd/2136/
EDITED WITH MY MAIN PROBLEM:
https://jsfiddle.net/Lr7gn020/1/
Click on APPEND IT, and then check the appended element by clicking on Select One button (Dropdown menu), and you will see that it do not get the proper CSS like the others (Item Test).
You've nested a div in the ul and the styles target .dropdown-menu>li>a so the div is breaking that. A div can't be a direct child of a ul and li can't be a direct child of a div. Instead of nesting a div in the ul, then appending li's to the div, you can $.prepend() li's directly to the menu, if you want them to appear at the beginning of the menu when you add them. If you don't care where they appear, you can $.append() them to the bottom instead.
$(document.body).on('click', '.append', function(event) {
$(".dropdown-menu").prepend("<li>Item Test</li>");
return false;
});
.btn-input {
display: block;
}
.btn-input .btn.form-control {
text-align: left;
}
.btn-input .btn.form-control span:first-child {
left: 10px;
overflow: hidden;
position: absolute;
right: 25px;
}
.btn-input .btn.form-control .caret {
margin-top: -1px;
position: absolute;
right: 10px;
top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br/><br/>
Append it
<div class="container">
<div class="row">
<div class="col-sm-3">
<h5>Normal Dropdown Button</h5>
<div class="panel panel-default">
<div class="panel-body">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span data-bind="label">Select One</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Item 1</li>
<li>Another item</li>
<li>This is a longer item that will not fit properly</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<br/><br/>
The reason behind the appended option having different css is due to the fact that you are appending it inside a div element.
The current CSS of the li elements comes from the bootstrap css with this selector.
dropdown-menu>li>a
Since you have a div node inside ul (which is wrong and make html invalid) and you are appending a new li inside this div with JS, the above selector will not reach this node and CSS will not be applied.
You should add the li node directly under the ul node.
Fiddle : http://jsfiddle.net/9med3Lou/
Change your jquery part.
$( document.body ).on( 'click', '.append', function( event ) {
$(".dropdown-menu").append("<li>Item 1</li>"); //append with ul, not div
return false;
});
Related
I have a dropdown menu and I am trying to toggle the display:block class on the ul child of the button, once that dropdown button is clicked. Currently the ul is set to display:none until the main button parent is clicked. So only the parent is shown on the screen currently.
I am having a hard time setting up these loops properly. I can set it up so when one button is clicked all the ul's for every project are shown but I only want the one under the corresponding button.
HTML:
<div class="dropdown">
<div class="project">
<button>website 1<i class="fas fa-caret-down"></i></button>
<ul class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
<div class="project">
<button>Website 2<i class="fas fa-caret-down"></i></button>
<ul class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
</div>
JAVASCRIPT:
const projects = document.querySelectorAll('.project')
const dropdown_lists = document.querySelectorAll('.drop-list')
projects.forEach(button => button.addEventListener('click', function(){
// Feel like I need a forEach loop here to loop through the dropdown_lists or a reg for loop
// for(i=0;i<dropdown_lists.length;i++) - maybe something like this
// then I need to classList.toggle('active') on this ul
// I'm getting stuck on how to make this in sync with the corresponding project button
}))
CSS:
.drop-list {
display: none;
}
.active {
display: block;
}
What I need is when projects[0] is clicked that toggles the class of 'active' to dropdown_lists[0] from the list.
When projects[1] is clicked that toggles the class of 'active' to dropdown_lists[1] from the list.
Again, I can set up the code so when I click one button all the ul dropdown-lists toggle the class 'active' but I only want the first button to go with the first ul and second button with the second ul.
I'm just not sure how to go about this, either make a boolean if dropdown lists === 2 and project === 2 than toggle the class. I just cant think of the best practice to do this easily.
Appreciate the help.
Thanks
I applied the toggle() method, together with the method of forEach(). In which you need to declare the variable of the current button - projects_current.
Next, .active class is assigned to <ul class="drop-list">...</ul> according to the index:
dropdown_lists[index]
const projects = document.querySelectorAll('.project')
const dropdown_lists = document.querySelectorAll('.drop-list')
projects.forEach(function (projects_current, index) {
projects_current.addEventListener('click', function () {
dropdown_lists[index].classList.toggle('active');
});
});
.drop-list {
display: none;
}
.active {
display: block;
}
<div class="dropdown">
<div class="project">
<button>website 1<i class="fas fa-caret-down"></i></button>
<ul class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
<div class="project">
<button>Website 2<i class="fas fa-caret-down"></i></button>
<ul class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
</div>
You could use "event delegation" to achieve the result without multiple event listeners. The basic idea is to use a click event listener on a common parent (div.dropdown) to check if a button was clicked, and if so, toggle the active class of the next sibling element.
A minimal event listener would then read like what you want to achieve:
document.querySelector(".dropdown").addEventListener( "click", event => {
if( event.target.tagName == "BUTTON") {
event.target.nextElementSibling.classList.toggle("active");
}
});
You can put an id in the dropdown to use it in the onclick of the buttons
const toggleDropdow = (dropdown) =>
document.getElementById(dropdown).classList.toggle("active");
.drop-list {
display: none;
}
.active {
display: block;
}
<div class="dropdown">
<div class="project">
<button onclick="toggleDropdow('dropdown1')">Website 1</button>
<ul id="dropdown1" class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
<div class="project">
<button onclick="toggleDropdow('dropdown2')">Website 2</button>
<ul id="dropdown2" class="drop-list">
<li>Live Website</li>
<li>Resources</li>
</ul>
</div>
</div>
I have some test code.
<div class="someclass" id="someid">
<div class="form-someclass1 class2 ">
<div class="button action right addbutton" id="btnId"><i class="add"></i> Add</div>
</div>
<ul class="ui-sortable">
<!-- dynamically li gets added. -->
</ul>
</div>
As soon as we click on "btnId" li gets added in ul and div has been changed. Similarly, if we remove li ul gets changed and div has been changed. Is there any way to get information that div > ul has been changed and on which event should we trigger the code in order to know change?
I tried for DOMSubTreeNodeChanged mutator events but as per google, it has compatibility issues and not to use.
How about this:
$("#btnId").on('click', function(e){
//alert(1112);
var target = $(this).closest(".someclass").find(".ui-sortable");
target.append('<li><span class="tab">Message Center</span></li>');
});
$(document).on('DOMNodeInserted', function(e) {
//check if li inserted to ul
if(e.target.localName == "li"){
//do somethings!
console.log("Inserted a li for ul!");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="someclass" id="someid">
<div class="form-someclass1 class2 ">
<div class="button action right addbutton" id="btnId"><i class="add"></i> Add</div>
</div>
<ul class="ui-sortable">
<!-- dynamically li gets added. -->
</ul>
</div>
So i managed to get my buttons to show the list items in the unordered list. But now every time i click a button all the list items nested in unordered list appears and disappears when the button is clicked again.
This is my updated HTML:
<div class="container-fluid text-center bg-black" id="services">
<div class="services">
<h2>SERVICES</h2>
<br>
<div class="row">
<div class="col-sm-3 iconpad-even">
<img src="img/icons/icon_data_edit.png" alt="data"/>
<button class="icon-btn" data-button="btnData">DATA</button>
<ul class="showData">
<li>Design</li>
<li>Cable Installation</li>
<li>Testing</li>
<li>CAT5e, CAT6, CAT6A</li>
</ul>
</div>
<div class="col-sm-3 iconpad-odd">
<img src="img/icons/fiber-icon-edit.png" alt="fiber-icon" />
<button class="icon-btn" data-button="btnFiber">FIBER</button>
<ul class="showData">
<li>Consultancy</li>
<li>Building to Building</li>
<li>Network Backbone</li>
<li>Testing</li>
</ul>
</div>
Basically i have 6 div's that are structured the exact same way, only difference is the content on the list items.
I've removed the display:none on the services ul li and added it to the css .showData class as suggested by #Mohammed-Yusef
Here's the current jQuery:
$(function() {
$('.icon-btn').on('click', function() {
$('.showData').toggle();
});
});
The jquery syntax of the click function should be as given below and also in your css you are hiding all the li elements. So you have to toggle them back with the selector $('.showData li') instead of $('.showData'). Also use .icon-btn instead of .icon-button as you don't have such a class mentioned in your html.
$('.icon-btn').on('click', function() {
$('.showData li').toggle();
});
Working snippet,
$(function() {
$('.icon-btn').on('click', function() {
//$('.showData li').toggle();
$(this).next('.showData').find('li').toggle();
});
});
.services ul li {
display: none;
margin-left: -1.8em;
/*color: #fff;*/
list-style: none;
margin-bottom: 1em;
font-size: 20px;
font-weight: bold;
font-family: 'Oswald', 'open-sans';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid text-center bg-black" id="services">
<div class="services">
<h2>SERVICES</h2>
<br>
<div class="row">
<div class="col-sm-3 iconpad-even">
<img src="img/icons/icon_data_edit.png" alt="data"/>
<button class="icon-btn" data-button="btnData">DATA</button>
<ul class="showData">
<li>Design</li>
<li>Cable Installation</li>
<li>Testing</li>
<li>CAT5e, CAT6, CAT6A</li>
</ul>
</div>
<div class="col-sm-3 iconpad-odd">
<img src="img/icons/fiber-icon-edit.png" alt="fiber-icon" />
<button class="icon-btn" data-button="btnFiber">FIBER</button>
<ul class="showData">
<li>Consultancy</li>
<li>Building to Building</li>
<li>Network Backbone</li>
<li>Testing</li>
</ul>
</div>
Please try it
$( "body" ).on( "click", ".icon-button", function(){
$('.showData').toggle();
});
The problem is that you don't have an element with a class icon-button your button has a class icon-btn so use $('.icon-btn') instead of $('.icon-button')
and you can use
$(function() {
$('.icon-btn').on('click', function() {
$('.showData').toggle();
});
});
and in css use
.showData{
display: none;
}
and remove display:none from .services ul li
Note: be sure to include jquery
I got as following:
<div parent-with-overflow-hidden>
<div absolute-position></div>
</div>
The real context is using the drop down menu bootstrap
<div overflow-hidden>
<div class="dropdown">
<button>Click to show menu</button>
<ul class="dropdown-menu">Menu</ul>
</div>
</div>
that I cannot show entire the menu.
How can I display the child div without move it outside the parent?
using position:absolute won't get it out of the parent with overflow-hidden . so you need to overwrite that with position:fixed . it will get the .dropdown-menu out of any parent/grandparent it has.
then you need to set the top position depending on the height of the parent, which is the overflow-hidden div.
after that, you need to dynamically re-calculate the top position while scrolling the page so that the dropdown stays in the same position
let me know if it works ;)
see snippet below or fiddle > jsfiddle
var oHeight = $('.ohidden ').height()
$('.dropdown-menu').css('top',oHeight)
//dropdown remain `glued` to the button on scroll
$(window).on("scroll",function(){
var wScroll = $(this).scrollTop()
$('.dropdown-menu').css('top',oHeight-wScroll)
})
.ohidden { overflow:hidden}
.dropdown-menu { position:fixed!important;}
body { height:2000px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="ohidden">
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
Click to show Menu
</button>
<ul class="dropdown-menu">
<li>ITEM 1</li>
<li>ITEM 2</li>
<li>ITEM 3</li>
</ul>
</div>
</div>
Whenever I hover over the second button in the menu, a "submenu" appears. When it appears, it partially covers the images in a div "container".
The styling of the submenu is such that it is semi-transparent so the images inside the div "container" also appear in the background of the menu, which doesnt look that good.
I know that the simple solution would be to change the location of the div but then the images would not be centered so that is not an option. I was wondering if it is possible that whenever I hover over the buttons that have a submenu, the div "container" hide and appear again when I move my mouse away from the menu. The div "container" should not hide when hovering over first Home button since it does not have a submenu and images should remain hidden as long as the menu is open. Is it possible in javascript or jQuery or CSS3??
HTML Code:
<div id="menu">
<ul class="menu" id="tempMenu">
<li class="Home">Home</li>
<li class="HOme2"><a id="secondElement" href="www.google.com">Home2</a><div>
<ul class="submenu">
<li>
<a id="one" href="">One</a>
</li></br>
<li>
<a id="two" href="">two</a>
</li>
<li>
<a id="three" href="">three</a>
</li>
<li>
<a id="four" href="">four</a>
</li>
<li>
<a id="five" href="">five</a>
</li>
<li>
<a id="six" href="">six</a>
</li>
<li>
<a id="seven" href="">seven</a>
</li>
<li>
<a id="eight" href="">eight</a>
</li>
</ul>
</div>
</li>
</ul>
</div>
<div id="container">
<div id="box1" class="box">Image1<img src="images/image1.png"></div>
<div id="box2" class="box">Image2<img src="images/image2.png"></div>
</div>
CSS Code:
ul.menu .submenu{
display: none;
position: absolute;
}
ul.menu li:hover .submenu{
display: block;
}
$('.submenu').hover(function() {
$('#container').hide()
}, function() {
$('#container').show()
});
You basically want to detect on the hover event whenever the current menu item (one of the .menu > a elements) contains a submenu (.submenu).
What about :
$('.menu > a').hover(function(){
if ($(this).find('.submenu').length != 0) {
$('#container').hide();
}
}, function(){
$('#container').show();
});
Also, some of your html closing tags have issues, you should ensure that they are all closing in a correct order to prevent unexpected glitches.
firstly give that div 2 class names like-class1,class2
in Css :
.class1{
display: none;
position: absolute;
}
.class2{
display : block;
}
in jquery :
//this would track mouse pointer in/out events
$("#menu").hover( function(event){ $("#div").attr("class","class1"); },
function(event){ $("#div").attr("class","class1"); } );
You forgot to close this
<li class="HOme2"><a id="secondElement" href="www.google.com">Home2</a><div>
to
<li class="HOme2"><a id="secondElement" href="www.google.com">Home2</a></li><div>
for the Jquery i think this will help
$('.submenu').mouseenter(function() {
$('#container').hide()
}).mouseleave(function(){
$('#container').show()
});