Issue with show / hide icons collapsing all divs - javascript

I have the following code which contains some nested DIVs.
The DIVs have Plus and Minus Font Awesome icons to expand and collapse them.
You can use the buttons at the top of the page to toggle visibility of the DIVs.
The blue button and / or plus/minus icons can toggle visibility of the parents (Activities and Animals & Nature).
The green button toggles visiblity of the "child" divs which contain sub-headings such as award-medal, event etc.
The problem I have is that when it comes to toggling visibility of the child divs with the green plus/minus icons, if you e.g. click on the green minus for the award-medal heading, it also collapses the div for event.
I wondered if there is any way to split out the collapse functionality there, so that the green toggle button still works as it does now, but so that the individual gree plus/minus icons control the visibility of each div the icon is related to.
I can sort of see why the code works as it does now, but cannot get my head around how I would have to change the JS code to be able to achieve what I'm trying to do.
$(document).ready(function() {
$('.toggleparent').addClass('toggle-open');
$('.heading > a').on('click', function(event){
event.preventDefault();
if ( $(this).find('i').hasClass('fa-minus') ) {
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
$(this).parent().parent().find('.submenu').css("display", "none");
$(this).parent().parent().find('.submenu').addClass('closed');
if ( $('.submenu.closed').length == $('.menu').length ) {
$('.toggleparent').removeClass('toggle-open');
}
}
else if ( $(this).find('i').hasClass('fa-plus') ) {
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
$(this).parent().parent().find('.submenu').css("display", "block");
$(this).parent().parent().find('.submenu').removeClass('closed');
$('.toggleparent').addClass('toggle-open');
}
});
$('.toggleparent').on('click', function(){
if ( $(this).hasClass('toggle-open') ) {
$('.heading').each(function() {
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
$(this).parent().find('.submenu').css("display", "none");
$(this).parent().parent().find('.submenu').addClass('closed');
});
$('.toggleparent').removeClass('toggle-open');
}
else{
$('.heading').each(function() {
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
$(this).parent().find('.submenu').css("display", "block");
$(this).parent().parent().find('.submenu').removeClass('closed');
});
$('.toggleparent').addClass('toggle-open');
}
});
});
$(document).ready(function() {
$('.togglechild').addClass('toggle-open');
$('.subheading > a').on('click', function(event){
event.preventDefault();
if ( $(this).find('i').hasClass('fa-minus') ) {
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
$(this).parent().parent().find('.indent').css("display", "none");
$(this).parent().parent().find('.indent').addClass('closed');
if ( $('.indent.closed').length == $('.menu').length ) {
$('.togglechild').removeClass('toggle-open');
}
}
else if ( $(this).find('i').hasClass('fa-plus') ) {
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
$(this).parent().parent().find('.indent').css("display", "block");
$(this).parent().parent().find('.indent').removeClass('closed');
$('.togglechild').addClass('toggle-open');
}
});
$('.togglechild').on('click', function(){
if ( $(this).hasClass('toggle-open') ) {
$('.subheading').each(function() {
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
$(this).parent().find('.indent').css("display", "none");
$(this).parent().parent().find('.indent').addClass('closed');
});
$('.togglechild').removeClass('toggle-open');
}
else{
$('.subheading').each(function() {
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
$(this).parent().find('.indent').css("display", "block");
$(this).parent().parent().find('.indent').removeClass('closed');
});
$('.togglechild').addClass('toggle-open');
}
});
});
body{
background: #fff;
margin-top:20px;
}
h1.heading {
font: 'Oswald';
text-transform: uppercase;
}
td { background: #f1f1f1; border-bottom:1px solid #ccc; border-right:1px solid #ccc; padding:20px; margin:5px; border-top:1px solid #fff; border-left:1px solid #fff; }
.wrappingmapping {
margin:20px 0 0 20px;
border-radius:85px;
overflow:hidden;
border:10px solid #fff;
box-shadow:0 0 10px #999;
}
.menu {
margin-bottom: 50px;
}
.submenu {
padding: 20px;
background: repeating-linear-gradient(
-45deg,
#999,
#999 10px,
#888 10px,
#888 20px
);
border-radius: 2px;
}
.green {
color:#28a745;
}
.heading {
color: #000;
background: #ccc;
border-bottom: 1px solid #ccc;
padding: 5px;
}
.subheading {
background: #fff;
padding-left: 10px;
background: #f1f1f1;
border-top: 1px solid #fff;
font-size: 30px;
}
.indent {
background: #fff;
padding: 0px 20px 20px 20px;
}
.icon {
width: 64px;
height: 64px;
}
.gallery {
width: 100%;
*width: 99.94877049180327%;
margin: 0;
padding: 0;
}
.gallery.grid li {
margin: 2px 5px;
}
.gallery.grid li {
margin: 2px 5px;
display: block;
}
.gallery.grid li:hover {
background: #ccc;
}
.gallery.grid li {
display: inline-block;
border-top: 1px solid #eee;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
border-left: 1px solid #eee;
padding: 6px;
position: relative;
-moz-box-sizing: border-box;
border-radius: 3px 3px 3px 3px;
background: #fff;
}
.gallery a {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<div class="container-fluid">
<div>
<span class="toggleparent btn btn-primary btn-lg" data-selector="parent_">Toggle Parents</span>
<span class="togglechild btn btn-success btn-lg" data-selector="child_">Toggle Children</span>
</div>
<hr />
<!-- parent start -->
<div id="activities" class="menu">
<h1 class="heading">
<i class="fa fa-minus" aria-hidden="true"></i> Activities <span style="color:#ccc;"> [57] </span>
</h1>
<div id="parent_activities" class="submenu">
<!-- child start -->
<h4 class="subheading">
<i class="fa fa-minus green" aria-hidden="true"></i> award-medal <span style="color:#ccc;"> [6] </span>
</h4>
<div id="child_award-medal" class="indent">
<ul class="gallery grid">
<li>
<img title="military medal - 🎖️" src="https://cdn.jsdelivr.net/emojione/assets/svg/1f396.svg" class="icon" role="presentation">
</li>
</ul>
</div> <!-- /indent -->
<!-- child start -->
<h4 class="subheading">
<i class="fa fa-minus green" aria-hidden="true"></i> event <span style="color:#ccc;"> [19] </span>
</h4>
<div id="child_event" class="indent">
<ul class="gallery grid">
<li>
<img title="jack-o-lantern - 🎃" src="https://cdn.jsdelivr.net/emojione/assets/svg/1f383.svg" class="icon" role="presentation">
</li>
</ul>
</div> <!-- /indent -->
</div> <!-- /submenu -->
</div> <!-- /menu -->
<!-- parent end -->
<!-- parent start -->
<div id="animals-nature" class="menu">
<h1 class="heading">
<i class="fa fa-minus" aria-hidden="true"></i> Animals & Nature <span style="color:#ccc;"> [106] </span>
</h1>
<div id="parent_animals-nature" class="submenu">
<!-- child start -->
<h4 class="subheading">
<i class="fa fa-minus green" aria-hidden="true"></i> animal-amphibian <span style="color:#ccc;"> [1] </span>
</h4>
<div id="child_animal-amphibian" class="indent">
<ul class="gallery grid">
<li>
<img title="frog face - 🐸" src="https://cdn.jsdelivr.net/emojione/assets/svg/1f438.svg" class="icon" role="presentation">
</li>
</ul>
</div> <!-- /indent -->
<!-- child start -->
<h4 class="subheading">
<i class="fa fa-minus green" aria-hidden="true"></i> animal-bird <span style="color:#ccc;"> [12] </span>
</h4>
<div id="child_animal-bird" class="indent">
<ul class="gallery grid">
<li>
<img title="turkey - 🦃" src="https://cdn.jsdelivr.net/emojione/assets/svg/1f983.svg" class="icon" role="presentation">
</li>
</ul>
</div> <!-- /indent -->
</div> <!-- /submenu -->
</div> <!-- /menu -->
<!-- parent end -->
</div>

Because by .parent().find('.indent') it find all .indent, but what you need to find .next element with .indent class not all, so you should use .parent().next('.indent').
$(document).ready(function() {
$('.toggleparent').addClass('toggle-open');
$('.heading > a').on('click', function(event) {
event.preventDefault();
if ($(this).find('i').hasClass('fa-minus')) {
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
$(this).parent().parent().find('.submenu').css("display", "none");
$(this).parent().parent().find('.submenu').addClass('closed');
if ($('.submenu.closed').length == $('.menu').length) {
$('.toggleparent').removeClass('toggle-open');
}
} else if ($(this).find('i').hasClass('fa-plus')) {
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
$(this).parent().parent().find('.submenu').css("display", "block");
$(this).parent().parent().find('.submenu').removeClass('closed');
$('.toggleparent').addClass('toggle-open');
}
});
$('.toggleparent').on('click', function() {
if ($(this).hasClass('toggle-open')) {
$('.heading').each(function() {
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
$(this).parent().find('.submenu').css("display", "none");
$(this).parent().parent().find('.submenu').addClass('closed');
});
$('.toggleparent').removeClass('toggle-open');
} else {
$('.heading').each(function() {
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
$(this).parent().find('.submenu').css("display", "block");
$(this).parent().parent().find('.submenu').removeClass('closed');
});
$('.toggleparent').addClass('toggle-open');
}
});
});
$(document).ready(function() {
$('.togglechild').addClass('toggle-open');
$('.subheading > a').on('click', function(event) {
event.preventDefault();
if ($(this).find('i').hasClass('fa-minus')) {
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
$(this).parent().next('.indent').css("display", "none");
$(this).parent().next('.indent').addClass('closed');
if ($('.indent.closed').length == $('.menu').length) {
$('.togglechild').removeClass('toggle-open');
}
} else if ($(this).find('i').hasClass('fa-plus')) {
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
$(this).parent().next('.indent').css("display", "block");
$(this).parent().next('.indent').removeClass('closed');
$('.togglechild').addClass('toggle-open');
}
});
$('.togglechild').on('click', function() {
if ($(this).hasClass('toggle-open')) {
$('.subheading').each(function() {
$(this).find('i').removeClass('fa-minus').addClass('fa-plus');
$(this).next('.indent').css("display", "none");
$(this).next('.indent').addClass('closed');
});
$('.togglechild').removeClass('toggle-open');
} else {
$('.subheading').each(function() {
$(this).find('i').removeClass('fa-plus').addClass('fa-minus');
$(this).next('.indent').css("display", "block");
$(this).next('.indent').removeClass('closed');
});
$('.togglechild').addClass('toggle-open');
}
});
});
body {
background: #fff;
margin-top: 20px;
}
h1.heading {
font: 'Oswald';
text-transform: uppercase;
}
td {
background: #f1f1f1;
border-bottom: 1px solid #ccc;
border-right: 1px solid #ccc;
padding: 20px;
margin: 5px;
border-top: 1px solid #fff;
border-left: 1px solid #fff;
}
.wrappingmapping {
margin: 20px 0 0 20px;
border-radius: 85px;
overflow: hidden;
border: 10px solid #fff;
box-shadow: 0 0 10px #999;
}
.menu {
margin-bottom: 50px;
}
.submenu {
padding: 20px;
background: repeating-linear-gradient( -45deg, #999, #999 10px, #888 10px, #888 20px);
border-radius: 2px;
}
.green {
color: #28a745;
}
.heading {
color: #000;
background: #ccc;
border-bottom: 1px solid #ccc;
padding: 5px;
}
.subheading {
background: #fff;
padding-left: 10px;
background: #f1f1f1;
border-top: 1px solid #fff;
font-size: 30px;
}
.indent {
background: #fff;
padding: 0px 20px 20px 20px;
}
.icon {
width: 64px;
height: 64px;
}
.gallery {
width: 100%;
*width: 99.94877049180327%;
margin: 0;
padding: 0;
}
.gallery.grid li {
margin: 2px 5px;
}
.gallery.grid li {
margin: 2px 5px;
display: block;
}
.gallery.grid li:hover {
background: #ccc;
}
.gallery.grid li {
display: inline-block;
border-top: 1px solid #eee;
border-right: 1px solid #ccc;
border-bottom: 1px solid #ccc;
border-left: 1px solid #eee;
padding: 6px;
position: relative;
-moz-box-sizing: border-box;
border-radius: 3px 3px 3px 3px;
background: #fff;
}
.gallery a {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<div class="container-fluid">
<div>
<span class="toggleparent btn btn-primary btn-lg" data-selector="parent_">Toggle Parents</span>
<span class="togglechild btn btn-success btn-lg" data-selector="child_">Toggle Children</span>
</div>
<hr />
<!-- parent start -->
<div id="activities" class="menu">
<h1 class="heading">
<i class="fa fa-minus" aria-hidden="true"></i> Activities <span style="color:#ccc;"> [57] </span>
</h1>
<div id="parent_activities" class="submenu">
<!-- child start -->
<h4 class="subheading">
<i class="fa fa-minus green" aria-hidden="true"></i> award-medal <span style="color:#ccc;"> [6] </span>
</h4>
<div id="child_award-medal" class="indent">
<ul class="gallery grid">
<li>
<img title="military medal - 🎖️" src="https://cdn.jsdelivr.net/emojione/assets/svg/1f396.svg" class="icon" role="presentation">
</li>
</ul>
</div>
<!-- /indent -->
<!-- child start -->
<h4 class="subheading">
<i class="fa fa-minus green" aria-hidden="true"></i> event <span style="color:#ccc;"> [19] </span>
</h4>
<div id="child_event" class="indent">
<ul class="gallery grid">
<li>
<img title="jack-o-lantern - 🎃" src="https://cdn.jsdelivr.net/emojione/assets/svg/1f383.svg" class="icon" role="presentation">
</li>
</ul>
</div>
<!-- /indent -->
</div>
<!-- /submenu -->
</div>
<!-- /menu -->
<!-- parent end -->
<!-- parent start -->
<div id="animals-nature" class="menu">
<h1 class="heading">
<i class="fa fa-minus" aria-hidden="true"></i> Animals & Nature <span style="color:#ccc;"> [106] </span>
</h1>
<div id="parent_animals-nature" class="submenu">
<!-- child start -->
<h4 class="subheading">
<i class="fa fa-minus green" aria-hidden="true"></i> animal-amphibian <span style="color:#ccc;"> [1] </span>
</h4>
<div id="child_animal-amphibian" class="indent">
<ul class="gallery grid">
<li>
<img title="frog face - 🐸" src="https://cdn.jsdelivr.net/emojione/assets/svg/1f438.svg" class="icon" role="presentation">
</li>
</ul>
</div>
<!-- /indent -->
<!-- child start -->
<h4 class="subheading">
<i class="fa fa-minus green" aria-hidden="true"></i> animal-bird <span style="color:#ccc;"> [12] </span>
</h4>
<div id="child_animal-bird" class="indent">
<ul class="gallery grid">
<li>
<img title="turkey - 🦃" src="https://cdn.jsdelivr.net/emojione/assets/svg/1f983.svg" class="icon" role="presentation">
</li>
</ul>
</div>
<!-- /indent -->
</div>
<!-- /submenu -->
</div>
<!-- /menu -->
<!-- parent end -->
</div>

Related

Need Javascript help Dropdown Menu onclick issue

I need the help with Javascript onclick Dropdown Menu.
The menu opens when I click the button and closes when I click outside.
The problem is that when I open one menu and click on another, the previous menu stays open.
I want the solution that when I open one menu when I open another menu the previous menu closes.
<!DOCTYPE HTML>
<html>
<head>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.navbar {
width: 100%;
padding: 0 10% 0 10%;
overflow: hidden;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}
.dropbtn {
font-size: 16px;
border: none;
outline: none;
padding: 21.5px 20px;
background-color: inherit;
margin: 0;
cursor: pointer;
font-weight: bolder;
color: #2d3436;
}
.dropdown {
float: left;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #fff;
min-width: 460px;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
height: 450px;
}
.show {
display: block
}
</style>
</head>
<body>
<div class="navbar">
<div class="dropdown">
<button onclick="my1Function()" class="dropbtn dropbtn1">Dropdown <i class="fas fa-caret-down"></i></button>
<div id="myDropdown1" class="dropdown-content dropdown-content1">
</div>
</div>
<div class="dropdown">
<button onclick="my2Function()" class="dropbtn dropbtn2">Dropdown <i class="fas fa-caret-down"></i></button>
<div id="myDropdown2" class="dropdown-content dropdown-content2">
</div>
</div>
<div class="dropdown">
<button onclick="my3Function()" class="dropbtn dropbtn3">Dropdown <i class="fas fa-caret-down"></i></button>
<div id="myDropdown3" class="dropdown-content dropdown-content2">
</div>
</div>
</div>
<script>
function my1Function() {
document.getElementById("myDropdown1").classList.toggle("show");
}
function my2Function() {
document.getElementById("myDropdown2").classList.toggle("show");
}
function my3Function() {
document.getElementById("myDropdown3").classList.toggle("show");
}
window.onclick = function(event) {
if (!event.target.matches('.dropbtn')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show')) {
openDropdown.classList.remove('show');
}
}
}
}
</script>
</body>
</html>
You may not need specific onclick event like my1Function for each dropdown button, instead use a generic event listener.
Hide any open dropdown content. (This takes care of hiding the dropdown content when clicked outside)
Show the dropdown content specific to the clicked button.
<!DOCTYPE HTML>
<html>
<head>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
}
.navbar {
width: 100%;
padding: 0 10% 0 10%;
overflow: hidden;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
}
.dropbtn {
font-size: 16px;
border: none;
outline: none;
padding: 21.5px 20px;
background-color: inherit;
margin: 0;
cursor: pointer;
font-weight: bolder;
color: #2d3436;
}
.dropdown {
float: left;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #fff;
min-width: 460px;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
height: 450px;
}
.show {
display: block
}
</style>
</head>
<body>
<div class="navbar">
<div class="dropdown">
<button class="dropbtn dropbtn1">Dropdown 1<i class="fas fa-caret-down"></i></button>
<div id="myDropdown1" class="dropdown-content dropdown-content1">
</div>
</div>
<div class="dropdown">
<button class="dropbtn dropbtn2">Dropdown 2<i class="fas fa-caret-down"></i></button>
<div id="myDropdown2" class="dropdown-content dropdown-content2">
</div>
</div>
<div class="dropdown">
<button class="dropbtn dropbtn3">Dropdown 3<i class="fas fa-caret-down"></i></button>
<div id="myDropdown3" class="dropdown-content dropdown-content2">
</div>
</div>
</div>
<script>
window.addEventListener('click', function(event) {
// Hide any open dropdown content
const dropdownContents = document.querySelectorAll('.dropdown-content')
dropdownContents.forEach(content => {
content.classList.remove('show');
});
// Show the dropdown content respective to the clicked button
if (event.target.matches('.dropbtn')) {
event.target.nextElementSibling.classList.add('show');
}
})
</script>
</body>
</html>
I would do the dropdown as a details tag like this:
<nav>
<ul class="my-nav">
<li>
<details class="dropdown">
<summary>This has dropdown items</summary>
<ul>
<li>Hi</li>
<li>Universe</li>
</ul>
</details>
</li>
<li>
<details class="dropdown">
<summary>Another dropdown</summary>
<ul>
<li>Goodbye</li>
<li>Universe</li>
</ul>
</details>
</li>
</ul>
</nav>
Granted you would have different summaries/links, and here is the corresponding js:
var nav = document.querySelector('.my-nav');
nav.addEventListener('toggle', function (event) {
// Only run if the dropdown is open
if (!event.target.open) return;
// Get all other open dropdowns and close them
var dropdowns = nav.querySelectorAll('.dropdown[open]');
Array.prototype.forEach.call(dropdowns, function (dropdown) {
if (dropdown === event.target) return;
dropdown.removeAttribute('open');
});
}, true);

jQuery: Can't select a new element after append

I created a structure to represent the UI Tree using jQuery. I added the ability to add a new element at any level (The "add new" button is activated when you select a level for adding).
But in my example, I can not add a new element to the newly created element. I tried different ways, but it does not work.
I'll be happy for the tips on how I can fix this problem
$(function() {
const newElement = $('#new-element');
let targetButton;
function indexOfChildren() {
$('li').prepend(function() {
let countOfChildren = $(this).children().find(">li").length;
let targetSpan = $(this).find('button>:first-child');
targetSpan.text(countOfChildren);
});
};
indexOfChildren();
$('li>button').on('focus', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
$('[name="new-button"]').on('click', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
newElement.click(function() {
let name = prompt("Please enter name of new element");
let parentTargetButton = targetButton.closest('li');
let indexTargetSpan = parseInt(targetButton.find(':first-child').text());
if (name != null) {
if (indexTargetSpan == 0) {
parentTargetButton.append('<ul><li><button class="btn mb-3 mt-1" name="new-button">' + name + '<span></span></button></li></ul>');
} else {
parentTargetButton.children('ul').append('<li><button class="btn mb-3 mt-1" name="new-button">' + name + ' <span></span></button></li>');
}
}
indexOfChildren();
targetButton.focus();
});
});
body {
background-color: #f5f6f8;
}
.main-content {
background: #fff;
box-shadow: 0 5px 20px 0 #c8d2dd6e;
-webkit-box-shadow: 0 5px 20px 0 #c8d2dd6e;
border-radius: 5px;
}
.top-level {
border-bottom: 1px solid #dadee7;
}
ul {
list-style-type: none;
}
ul>li>ul {
border-left: 1px solid #eee;
margin-left: 60px;
}
ul>li>ul>li:before {
border-left: 1px solid;
}
#new-element {
background-color: #33b5ff;
color: #fff;
border-radius: 40px;
}
.main-content .btn {
box-sizing: content-box;
width: 140px;
padding: 14px;
text-align: left;
background-color: #f5f6f8;
border-radius: 7px;
}
span {
float: right;
color: #fff;
line-height: 1.4;
border-radius: 0.8em;
-moz-border-radius: 0.8em;
-webkit-border-radius: 01em;
text-align: center;
font-size: 0.9em;
width: 1.4em;
background-color: #33b5ff;
}
.btn:focus,
.btn:hover,
#new-element {
-webkit-box-shadow: 0 5px 25px 0 #9dabbb69;
*/ box-shadow: 0 5px 25px 0 #9dabbb69;
}
.main-content .btn:focus {
color: #fff;
background-color: #0095ff!important;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container project-item my-3 pt-5">
<div class="row top-level pb-4">
<h3 class="col-sm-9 pl-0">New Project</h3>
<div class="col-sm-3 pr-0">
<button type="button" class="btn float-right" id="new-element" disabled>+ Add new element</button>
</div>
</div>
</div>
<div class="container main-content pt-5 mt-5 pb-5">
<ul>
<li>
<button class="btn mb-3 mt-1">Project <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">Web Design <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">CSS <span></span></button>
</li>
<li>
<button class="btn mb-3 mt-1">HTML <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">HTML <span></span></button>
</li>
<li>
<button class="btn mb-3 mt-1">XHTML <span></span></button>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>
You can bind the .on event to the already existing parent element.
$('li').on('focus', 'button', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
$(function() {
const newElement = $('#new-element');
let targetButton;
function indexOfChildren() {
$('li').prepend(function() {
let countOfChildren = $(this).children().find(">li").length;
let targetSpan = $(this).find('button>:first-child');
targetSpan.text(countOfChildren);
});
};
indexOfChildren();
$('li').on('focus', 'button', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
$('[name="new-button"]').on('click', function(e) {
targetButton = $(this);
newElement.prop("disabled", false);
});
newElement.click(function() {
let name = prompt("Please enter name of new element");
let parentTargetButton = targetButton.closest('li');
let indexTargetSpan = parseInt(targetButton.find(':first-child').text());
if (name != null) {
if (indexTargetSpan == 0) {
parentTargetButton.append('<ul><li><button class="btn mb-3 mt-1" name="new-button">' + name + '<span></span></button></li></ul>');
} else {
parentTargetButton.children('ul').append('<li><button class="btn mb-3 mt-1" name="new-button">' + name + ' <span></span></button></li>');
}
}
indexOfChildren();
targetButton.focus();
});
});
body {
background-color: #f5f6f8;
}
.main-content {
background: #fff;
box-shadow: 0 5px 20px 0 #c8d2dd6e;
-webkit-box-shadow: 0 5px 20px 0 #c8d2dd6e;
border-radius: 5px;
}
.top-level {
border-bottom: 1px solid #dadee7;
}
ul {
list-style-type: none;
}
ul>li>ul {
border-left: 1px solid #eee;
margin-left: 60px;
}
ul>li>ul>li:before {
border-left: 1px solid;
}
#new-element {
background-color: #33b5ff;
color: #fff;
border-radius: 40px;
}
.main-content .btn {
box-sizing: content-box;
width: 140px;
padding: 14px;
text-align: left;
background-color: #f5f6f8;
border-radius: 7px;
}
span {
float: right;
color: #fff;
line-height: 1.4;
border-radius: 0.8em;
-moz-border-radius: 0.8em;
-webkit-border-radius: 01em;
text-align: center;
font-size: 0.9em;
width: 1.4em;
background-color: #33b5ff;
}
.btn:focus,
.btn:hover,
#new-element {
-webkit-box-shadow: 0 5px 25px 0 #9dabbb69;
*/ box-shadow: 0 5px 25px 0 #9dabbb69;
}
.main-content .btn:focus {
color: #fff;
background-color: #0095ff!important;
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div class="container project-item my-3 pt-5">
<div class="row top-level pb-4">
<h3 class="col-sm-9 pl-0">New Project</h3>
<div class="col-sm-3 pr-0">
<button type="button" class="btn float-right" id="new-element" disabled>+ Add new element</button>
</div>
</div>
</div>
<div class="container main-content pt-5 mt-5 pb-5">
<ul>
<li>
<button class="btn mb-3 mt-1">Project <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">Web Design <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">CSS <span></span></button>
</li>
<li>
<button class="btn mb-3 mt-1">HTML <span></span></button>
<ul>
<li>
<button class="btn mb-3 mt-1">HTML <span></span></button>
</li>
<li>
<button class="btn mb-3 mt-1">XHTML <span></span></button>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
</body>

Smooth Scroll On Button Click

I am using this code for scroll on an anchor link. It works one time and if click on anchor again it is not working.
$("#erly").on("click", function() {
$(".table-responsive").scrollLeft(0);
});
$("#late").on("click", function() {
$(".table-responsive").scrollLeft(50);
});
You may try unbinding the previous event handlers, like this.
$("#erly").unbind().on("click", function() {
$(".table-responsive").scrollLeft(0);
});
$("#late").unbind().on("click", function() {
$(".table-responsive").scrollLeft(50);
});
div.table-responsive {
background: #ccc none repeat scroll 0 0;
border: 3px solid #666;
margin: 5px;
padding: 5px;
position: relative;
width: 200px;
height: 100px;
overflow: auto;
}
p {
margin: 10px;
padding: 5px;
border: 2px solid #666;
width: 1000px;
height: 1000px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<body>
<a id="erly" href="#1">Early</a>
<br />
<a id="late" href="#2">Late</a>
<div class="table-responsive">
<h1>lalala</h1>
<p>Hello 1</p>
</div>
<div class="table-responsive">
<h1>lalala</h1>
<p>Hello 2</p>
</div>
</body>
<div class="col-xs-12 early_late">
<ul class="list-inline">
<li class="pull-left">
<a id="erly" class="erlier" onclick="scrollWin2()">
<span class="glyphicon glyphicon-menu-left span_left"></span> Earlier</a>
</li>
<li class="pull-right" onclick="scrollWin()">
<a id="late">Late <span class="glyphicon glyphicon-menu-right span_right"></span></a>
</li>
</ul>
function scrollWin() {
document.getElementById('scroll').scrollBy(100 , 0);
}
function scrollWin2() {
document.getElementById('scroll').scrollBy(-100 , 0);
}

Creating an onclick event for a button with a dropdown menu

I've been learning HTML and CSS for some weeks now and I start feeling comfortable with those. However I'm trying to learn JavaScript too.
I've been working on a button in HTML and CSS, you can view the demo of the button here.
I want to make the dropdown menu visible when you click the button and also if you click the button again the dropdown menu disappears.
Is there any simple or understandable way for creating a function which does this in JavaScript?
Here is the code I have:
HTML:
<div id="language-wrapper">
<a class="language-icon fr" href="#" alt="choose-your-language">Language</a>
<div id="language-dropdown">
<h3>Choose your language</h3>
<a class="language-links" href="#">Chinese</a>
<a class="language-links" href="#">Danish</a>
<a class="language-links" href="#">Deutsch</a>
<a class="language-links" href="#">English</a>
<a class="language-links" href="#">Espanol</a>
<a class="language-links" href="#">Filipino</a>
<a class="language-links" href="#">Hindu</a>
<a class="language-links" href="#">Italiano</a>
<a class="language-links" href="#">Norsk</a>
<a class="language-links" href="#">Nederlands</a>
<a class="language-links" href="#">Polski</a>
<a class="language-links" href="#">Portugues</a>
<a class="language-links" href="#">Svenska</a>
<a class="language-links" href="#">Suomi</a>
<a class="language-links" href="#">Turkce</a>
<a class="language-links" href="#">Urdu</a>
<p>Do you speak multiple languages or can't find your language? <font color="#d13030">Help us translate!</font><p>
</div> <!-- end of language-dropdown class -->
</div> <!-- end of language-wrapper -->
CSS:
#language-wrapper { display: inline-block; }
#language-wrapper:hover #language-dropdown { opacity: 1; display: block; }
.language-icon {
color: #fff;
font-weight:700;
padding-right:20px;
padding-left:30px;
display:inline-block;
font-size:11px;
text-align:right;
text-decoration:none;
position:relative;
left: 0; top: 0;
}
.fr { background: url("images/language-sprite.png") no-repeat 0 0; }
.fr:hover { background: url("images/language-sprite.png") no-repeat 0 -20px; color: #d13030; }
.language-icon:before {
content:'\25BE';
width:0px;
height:0;
position:absolute;
right:16px;
top: 0;
}
.language-icon:hover:before {
color: #d13030;
content: '\25B4';
top: -1px;
}
/* ------------------ LANGUAGE DROPDOWN ------------------ */
#language-dropdown {
opacity: 0;
width: 1023px;
display: none;
margin-top: 3px;
left: 0;
position: absolute;
border: 1px solid #ddd;
background: #fff;
box-shadow: 0px 3px 3px #b3b3b3;
}
#language-dropdown h3 {
color: #d13030;
font-size: 14px;
font-weight: normal;
padding: 5px 15px 0px 15px;
}
#language-dropdown p {
font-size: 12px;
padding: 0px 0px 10px 15px;
}
#language-dropdown a {
padding: 0px 0px 0px 15px;
}
.language-links {
font-size: 12px;
text-decoration: none;
color: #2793e6;
}
.language-links:hover {
text-decoration: underline;
}
it can be a basic toggle display function on onclik event:
function toggle(el) {
var tag=document.getElementById(el);
tag.style.display = tag.style.display === 'block' ? 'none' : 'block';
// set as defaut oposite defaut active value in document
// here defaut is set to block cause it is none in CSS
}
<a class="language-icon fr" href="#" alt="choose-your-language" onclick="toggle('language-dropdown');">Language</a>
test here : http://codepen.io/anon/pen/cHIrd/
note:
opacity:0; removed from your initial CSS
Better practice is to toggle class not style values :)
and maybe to set onclick event via javScript.
return false can be added to avoid link to href .
<a class="language-icon fr" href="#" alt="choose-your-language" onclick="toggle('language-dropdown');return false;">Language</a>
The Html
<button id="clickme">Clickme</button>
<h1 id="Another">Menu</h1>
The JavaScript:
document.getElementById("clickme").onclick=function(){
var el = document.getElementById('Another');
if (el.style.display == '') {
el.style.display = 'none';
alert("hide");
}else{
el.style.display = '';
alert("show");
}
};
Here is a sample

Links in the dropdown menu are not working

Having an issue getting any kind of interaction from these links in the dropdown. I tried various link types and none are responding to clicks.
<li class="headerContact">
Contact Us<i class="fa fa-envelope"></i>
</li>
<li class="menuLink">
Features<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Science<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Videos<i class="fa fa-caret-right right"></i>
</li>
The test page is at bruxzir.jgallardo.me/header.aspx.
This is the full code for that page that I am using during development. (I am not doing this in production)
<!doctype html>
<html class="no-js" lang="en">
<head>
<!--#include file="/pages/_includes/head-default.html" -->
<style>
.active .dropdown { display:block; }
.dropdown { display:none; }
.header {
background-color: #333;
color: #fff;
height: 36px;
width: 100%;
line-height: 36px;
}
/* should be replaced with image */
.headerLogo {
display:inline;
font-size: 24px;
line-height: 36px;
padding-left: 6px;
}
.headerMenu{
float:right;
font-size: 36px;
margin-right: 6px;
}
.headerLogo a, .headerMenu a { color:#fff; text-decoration:none; }
.headerNav {
background-color: #292c2d;
overflow:hidden;
width:100%;
}
.headerNav a { color: #f3f3f3; text-decoration: none; }
.headerNav ul {
list-style-type: none;
margin:0;
padding-left: 0;
text-align:left;
}
.headerNav ul li {
border-bottom: 1px dotted #34393b;
display:inline-block;
width: 100%;
}
.menuLink a {
display:block;
line-height: 48px;
padding: 0 12px;
}
.headerNav ul li a i {
line-height: 48px;
}
.right { float:right; }
.findLabLink {
background-color: #48e0a4;
margin: 0 auto;
text-align: center;
width: 84%;
}
.findLabLink a {
color: rgb(40,43,45);
display:block;
line-height: 48px;
}
.headerContact {
line-height: 60px;
text-align: center;
}
.headerContact a {
background-color: #464241;
border-radius: 2px;
letter-spacing: 3px;
padding: 8px 18px;
}
.headerContact i {
margin-left: 30px;
}
</style>
</head>
<body>
<div class="container">
<div id="mainContent" class="block push">
<div class="row">
<div class="large-12 columns">
<h1>BruxZir Home Page</h1>
<div id="dd" class="wrapper-dropdown-3 dd" tabindex="1">
<div class="header">
<div class="headerLogo">
<!-- change # to / -->
BruxZir
</div>
<div class="headerMenu">
≡
</div>
</div> <!--/ end of .header -->
<div class="headerNav">
<ul class="dropdown">
<li class="findLabLink">
Find An Authorized Lab
</li>
<li class="headerContact">
Contact Us<i class="fa fa-envelope"></i>
</li>
<li class="menuLink">
Features<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Science<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Videos<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Cases<i class="fa fa-caret-right right"></i>
</li>
<li class="menuLink">
Testimonials<i class="fa fa-caret-right right"></i>
</li>
</ul>
</div> <!-- headerNav -->
</div>
</div>
</div>
</div> <!-- end of #mainContent -->
</div>
<!-- JavaScript Declarations
======================== -->
<!--#include file="/pages/_includes/js-default.html" -->
<script>
// all of this is for the menu
function WTF() {
window.location.href = "";
}
function DropDown(el) {
this.dd = el;
this.placeholder = this.dd.children('span');
this.opts = this.dd.find('ul.dropdown > li');
this.val = '';
this.index = -1;
this.initEvents();
}
DropDown.prototype = {
initEvents: function () {
var obj = this;
obj.dd.on('click', function (event) {
event.stopPropagation();
if (event.target.className === 'dd') {
$(this).toggleClass('active');
}
return false;
});
}
}
$(function () {
var dd = new DropDown($('#dd'));
$(document).click(function () {
// all dropdowns
$('.wrapper-dropdown-3').removeClass('active');
});
});
</script>
</body>
</html>
You're returning false and stopping event bubbling for all clicks withing the $('#dd') element right now. I think you only want to do that for your initial menu toggling click on the $('.dd') element.
if (event.target.className === 'dd') {
$(this).toggleClass('active');
event.stopPropagation(); // not sure why you need this
return false;
}
Look at the jsFiddle. I removed a lot of javascript and used one jQuery. I am not sure what you need, let me know if there something I missed.
$(function () {
$('.dd').on('click', function(event){
event.stopPropagation();
$('.wrapper-dropdown-3').toggleClass('active');
});
$(document).click(function () {
// all dropdowns
$('.wrapper-dropdown-3').removeClass('active');
});
});

Categories

Resources