How to look up data from an ul li? - javascript

My error that I present in adding a data search engine from a tags in specifies (ul -> li) is:
when I add a text in the search engine, the search input disappears
jQuery.fn.filterByText = function(textbox) {
return this.each(function() {
var select = this;
var options = [];
$(select).find('li').each(function() {
options.push({
value: $(this).val(),
text: $(this).text()
});
});
$(select).data('options', options);
$(textbox).bind('change keyup', function() {
var options = $(select).empty().data('options');
var search = $.trim($(this).val());
var regex = new RegExp(search, "gi");
$.each(options, function(i) {
var option = options[i];
if (option.text.match(regex) !== null) {
$(select).append(
$('<li>').text(option.text).val(option.value)
);
}
});
});
});
};
/*$(function() {
$('.options').filterByText($('input'));
});*/
.container {
display: flex;
flex-wrap: wrap;
width: 25%;
}
.selected {
border: thin solid darkgray;
border-radius: 5px;
background: lightgray;
display: flex;
align-items: center;
cursor: pointer;
height: 1.5em;
margin-bottom: .2em;
padding-left: .5em;
min-width: 150px;
position: relative;
}
.selected:after {
font-family: FontAwesome;
content: "\f0d7";
margin-left: 1em;
position: absolute;
right: .5em;
}
/*
.options {
display: none;
margin: 0;
padding: 0;
}
.options.open {
display: inline-block;
}
*/
li {
display: flex;
justify-content: flex-start;
align-items: center;
cursor: pointer;
}
li.search {
padding: 0.5rem 0;
}
li>img {
margin-right: 1em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<form>
<input type="hidden" id="sel">
<div class="container">
<div class="selected">Select an option</div>
<ul class="options">
<li class="search"><input type="text" id="search"></li>
<li class="option"><span>Option 1</span></li>
<li class="option"><span>Option 2</span></li>
<li class="option"><span>Option 3</span></li>
<li class="option"><span>Option 4</span></li>
<li class="option"><span>Option 5</span></li>
<li class="option"><span>Option 6</span></li>
<li class="option"><span>Option 7</span></li>
<li class="option"><span>Option 8</span></li>
<li class="option"><span>Option 9</span></li>
<li class="option"><span>Option 10</span></li>
<li class="option"><span>Option 11</span></li>
<li class="option"><span>Option 12</span></li>
<li class="option"><span>Option 13</span></li>
<li class="option"><span>Option 14</span></li>
<li class="option"><span>Option 15</span></li>
<li class="option"><span>Option 16</span></li>
<li class="option"><span>Option 17</span></li>
<li class="option"><span>Option 18</span></li>
<li class="option"><span>Option 19</span></li>
<li class="option"><span>Option 20</span></li>
<li class="option"><span>Option 21</span></li>
<li class="option"><span>Option 22</span></li>
<li class="option"><span>Option 23</span></li>
<li class="option"><span>Option 24</span></li>
<li class="option"><span>Option 25</span></li>
<li class="option"><span>Option 26</span></li>
<li class="option"><span>Option 27</span></li>
<li class="option"><span>Option 28</span></li>
<li class="option"><span>Option 29</span></li>
<li class="option"><span>Option 30</span></li>
<li class="option"><span>Option 31</span></li>
<li class="option"><span>Option 32</span></li>
<li class="option"><span>A</span></li>
<li class="option"><span>B</span></li>
<li class="option"><span>C</span></li>
<li class="option"><span>D</span></li>
<li class="option"><span>E</span></li>
<li class="option"><span>H</span></li>
<li class="option"><span>E</span></li>
<li class="option"><span>E</span></li>
<li class="option"><span>A</span></li>
<li class="option"><span>Other</span></li>
</ul>
</div>
</form>
My idea is to show only the data that is coinciding in the search engine if I search for an existing specific word that shows me only that record and that the others do not show
I was looking for some other example code and only found this code on the web
<script>
function myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById("myInput");
filter = input.value.toUpperCase();
table = document.getElementById("myTable");
tr = table.getElementsByTagName("tr");
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[1];
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = "";
} else {
tr[i].style.display = "none";
}
}
}
}
</script>
Can you explain to me, please, what I'm doing wrong in the code.

I did a simple jsfiddle, works flawless with the second link I posted fiddle here
You have to remove the input out of the ul or it will be filtered, or you handle it differently
<input type="text" id="search"> <!-- not in ul > li -->

Related

How to show dropdown menu when clicked

js
const navItems = document.querySelectorAll('.navbar__items')
const dropDown = document.querySelectorAll('.dropdown')
dropDown.forEach(element => {
element.addEventListener('click',()=>{
{
navItems.forEach(nav =>{
nav.classList.toggle('drop')
})
}
})
})
HTML
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
</ul>
CSS
.navbar{
position: relative;
}
.navbar__items{
position: absolute;
display: none;
}
.drop{
display: block;
}
I have a navbar and each of these navbar items have dropdown items. I want to show these dropdown items when I click on the 'dropdown' class. But the problem is when I click on one of them all the dropdowns are visible. How do I show only the list I've clicked on?
Enter the below code
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.dropbtn {
background-color: #3498DB;
color: white;
padding: 16px;
font-size: 16px;
border: none;
cursor: pointer;
}
.dropbtn:hover, .dropbtn:focus {
background-color: #2980B9;
}
.dropdown {
position: relative;
display: inline-block;
}
.dropdown-content {
display: none;
position: absolute;
background-color: #f1f1f1;
min-width: 160px;
overflow: auto;
box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);
z-index: 1;
}
.dropdown-content a {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.dropdown a:hover {background-color: #ddd;}
.show {display: block;}
</style>
</head>
<body>
<div class="dropdown">
<button onclick="myFunction()" class="dropbtn">Click</button>
<div id="myDropdown" class="dropdown-content">
Clicked
Clicked
Clicked
</div>
</div>
<script>
function myFunction() {
document.getElementById("myDropdown").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>
As mentioned in comments it is better to use Event Delegation technique.
The algorithm is quite simple:
Add listener on the parent element
On click check if dropdown-opener was clicked
Get drop-down which I need to open
Close other dropdowns
Open dropdown from 3.
const allDropdowns = document.querySelectorAll('.navbar__items')
const DROP_CLASS = 'drop';
const navbar = document.querySelector('.navbar');
navbar.addEventListener('click', ({target}) => {
if (!target.classList.contains('dropdown')) return;
const parent = target.parentNode;
const navItems = parent
.querySelector('.navbar__items');
allDropdowns.forEach(el => el !== navItems && el.classList.remove(DROP_CLASS));
if (navItems) {
navItems.classList.toggle(DROP_CLASS);
}
});
.navbar{
position: relative;
}
.navbar__items{
position: absolute;
left: 80px;
display: none;
}
.drop{
display: block;
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
</ul>
Use the event target to get the parentNode, then use the parentNode to query the hidden element as all your elements are grouped in the same parent/child grouping. Also you can set an initial class for hidden, display: none; in each element and add it on click. A forEach loop sets each elements display to none using the hidden class on click.
const navItems = document.querySelectorAll('.navbar__items')
const dropDown = document.querySelectorAll('.dropdown')
// callback function that passes in the event => e from your listener
function showDropdown (e){
// set each navbar__items element display: none using hidden class
navItems.forEach(el => el.classList.add('hidden'))
// query the specific .navbar__items in the event.targets group
let dd = e.target.parentNode.querySelector('.navbar__items')
// remove the hidden class a nd show the dropdown for this event.target
dd.classList.remove('hidden')
}
// iterate over the dropdown element
dropDown.forEach(element => {
// function showDropdown on click
element.addEventListener('click', showDropdown)
})
.navbar {
position: relative;
}
.navbar__items {
position: absolute;
left: 75px;
}
.hidden {
display: none;
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li>clicked 1</li>
<li>clicked 1</li>
<li>clicked 1</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li>clicked 2</li>
<li>clicked 2</li>
<li>clicked 2</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown">click</div>
<ul class="navbar__items hidden">
<li>clicked 3</li>
<li>clicked 3</li>
<li>clicked 3</li>
</ul>
</li>
</ul>
Rather than using addEventlistener you should add onclick method in html to every drop-down with same method name but change the ul class name with for each drop-down and then pass class name in method and then toggle the drop-down with parameter class name.
For example,
function onClick(item) {
if (document.getElementsByClassName(item).classList.contains('hidden')) {
document.getElementsByClassName('dropdown').classList.remove('hidden');
}
if (!document.getElementsByClassName(item)[0].classList.contains('hidden')) {
document.getElementsByClassName('dropdown').classList.add('hidden');
}
}
<ul class="navbar">
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items1')">click</div>
<ul class="navbar__items1 hidden">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items2')">click</div>
<ul class="navbar__items2 hidden">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
<li class="nav-menu">
<div class="dropdown" onclick="onClick('navbar_items3')">click</div>
<ul class="navbar__items3 hidden">
<li>clicked</li>
<li>clicked</li>
<li>clicked</li>
</ul>
</li>
</ul>

Remove Class From All Elements Except Active Element

I have a set of anchor tags that I am adding an active class to via a forEach method. How do I get it so when I add the active class to one anchor tag, it removes this active class from all other anchor tags items?
I must also have it so the 1st anchor tag starts with an active class on it (which I have done via CSS)
CodePen: https://codepen.io/emilychews/pen/gOaXdMr
var tabLink = document.querySelectorAll('.tab-link'),
tabPane = document.querySelectorAll('.tab-pane')
tabLink.forEach(function(item){
item.addEventListener('click', function(){
item.classList.add('active')
}, false)
})
.nav-tabs {
display: flex;
align-items: center;
padding: 1rem 2rem;
list-style: none;
background: lightblue;
}
.tab-link {
margin-left: 4rem;
padding: 1rem;
border-radius: 1px;
transition: .2s;
display: block;
}
.tab-link.active {
background: white;
}
<ul class="nav-tabs"role="tablist">
<li role="presentation"><a class="tab-link active" href="#html-tab" title="html tab" role="tab">HTML</a></li>
<li role="presentation"><a class="tab-link" href="#css-tab" title="css tab" role="tab">CSS</a></li>
<li role="presentation"><a class="tab-link" href="#result-tab" title="result tab" role="tab">Result</a></li>
</ul>
If you use jQuery, You can do this using few lines of code.
Vanilla JS
var tabLink = document.querySelectorAll('.tab-link');
tabLink.forEach(function(item){
item.addEventListener('click', function(){
document.querySelector('.active').classList.remove('active');
item.classList.add('active');
}, false)
})
jQuery
$(document).on('click', '.tab-link', function(){
$('.tab-link').removeClass('active'); // remove active for all first.
$(this).addClass('active'); // add active for clicked element
})
Inside the click event listener, you can simply remove all the active classes from all the children elements inside .tab-link before adding the last active class to the clicked element.
I only added three lines of code below to your original code to achieve what you wanted.
var tabLink = document.querySelectorAll('.tab-link'),
tabPane = document.querySelectorAll('.tab-pane')
tabLink.forEach(function(item){
item.addEventListener('click', function(){
tabLink.forEach(function(item) {
item.classList.remove('active')
})
item.classList.add('active')
}, false)
})
.nav-tabs {
display: flex;
align-items: center;
padding: 1rem 2rem;
list-style: none;
background: lightblue;
}
.tab-link {
margin-left: 4rem;
padding: 1rem;
border-radius: 1px;
transition: .2s;
display: block;
}
.tab-link.active {
background: white;
}
<ul class="nav-tabs"role="tablist">
<li role="presentation"><a class="tab-link active" href="#html-tab" title="html tab" role="tab">HTML</a></li>
<li role="presentation"><a class="tab-link" href="#css-tab" title="css tab" role="tab">CSS</a></li>
<li role="presentation"><a class="tab-link" href="#result-tab" title="result tab" role="tab">Result</a></li>
</ul>
so basically just give each on a different id then in the function just remove the class from each and than add the class.
var tabLink = document.querySelectorAll('.tab-link'),
tabPane = document.querySelectorAll('.tab-pane')
tabLink.forEach(function(item){
item.addEventListener('click', function(){
document.getElementById('a').classList.remove('active');
document.getElementById('b').classList.remove('active');
document.getElementById('c').classList.remove('active');
item.classList.add('active')
}, false)
})
.nav-tabs {
display: flex;
align-items: center;
padding: 1rem 2rem;
list-style: none;
background: lightblue;
}
.tab-link {
margin-left: 4rem;
padding: 1rem;
border-radius: 1px;
transition: .2s;
display: block;
}
.tab-link.active {
background: white;
}
<ul class="nav-tabs"role="tablist">
<li role="presentation"><a id='a' class="tab-link active" href="#html-tab" title="html tab" role="tab">HTML</a></li>
<li role="presentation"><a id='b' class="tab-link" href="#css-tab" title="css tab" role="tab">CSS</a></li>
<li role="presentation"><a id='c' class="tab-link" href="#result-tab" title="result tab" role="tab">Result</a></li>
</ul>
I created a second function that will be called in the click event. That function search for a item where has the class active and remove the class.
var tabLink = document.querySelectorAll('.tab-link'),
tabPane = document.querySelectorAll('.tab-pane')
function clearActiveItemMenu(){
tabLink.forEach(function(item){
if(item.classList.contains('active')){
item.classList.remove('active');
}
});
}
tabLink.forEach(function(item){
item.addEventListener('click', function(){
clearActiveItemMenu();
item.classList.add('active')
}, false)
})
.nav-tabs {
display: flex;
align-items: center;
padding: 1rem 2rem;
list-style: none;
background: lightblue;
}
.tab-link {
margin-left: 4rem;
padding: 1rem;
border-radius: 1px;
transition: .2s;
display: block;
}
.tab-link.active {
background: white;
}
<ul class="nav-tabs"role="tablist">
<li role="presentation"><a class="tab-link active" href="#html-tab" title="html tab" role="tab">HTML</a></li>
<li role="presentation"><a class="tab-link" href="#css-tab" title="css tab" role="tab">CSS</a></li>
<li role="presentation"><a class="tab-link" href="#result-tab" title="result tab" role="tab">Result</a></li>
</ul>

Kendo UI sortable within a sortable

I'm trying to get the following to work:
<div id="playlist">
<div id="playlist-title"><span>My Playlist</span></div>
<ul id="sortable-basic">
<div class="sortable-div">
<li>drag div</li>
<li class="sortable">Papercut <span>3:04</span></li>
<li class="sortable">One Step Closer <span>2:35</span></li>
</div>
<div class="sortable-div">
<li>drag div</li>
<li class="sortable">With You <span>3:23</span></li>
<li class="sortable">Points of Authority <span>3:20</span></li>
</div>
<div class="sortable-div">
<li>drag div</li>
<li class="sortable">Crawling <span>3:29</span></li>
<li class="sortable">Runaway <span>3:03</span></li>
</div>
<div class="sortable-div">
<li>drag div</li>
<li class="sortable">By Myself <span>3:09</span></li>
<li class="sortable">In the End <span>3:36</span></li>
</div>
<div class="sortable-div">
<li>drag div</li>
<li class="sortable">A Place for My Head <span>3:04</span></li>
<li class="sortable">Forgotten <span>3:14</span></li>
</div>
<div class="sortable-div">
<li>drag div</li>
<li class="sortable">Cure for the Itch <span>2:37</span></li>
<li class="sortable">Pushing Me Away <span>3:11</span></li>
</div>
</ul>
</div>
<script>
$(document).ready(function() {
$("#sortable-basic").kendoSortable({
hint:function(element) {
return element.clone().addClass("hint");
},
placeholder:function(element) {
return element.clone().addClass("placeholder").text("drop here");
},
cursorOffset: {
top: -10,
left: -230
},
items: ".sortable, .sortable-div"
});
});
</script>
So the plan is the following:
You need to be able to drag the div's up and down other div's. This works fine. But you also need to be able to drag a single item around, in and out the div. This is the part I cannot figure out. When I click an item it selects the div anyways.
For the life of me i cannot seem to figure this out.
please try below code.
For your more reference, I was modify given link code:
https://docs.telerik.com/kendo-ui/controls/interactivity/sortable/how-to/nested-sortables
$(document).ready(function() {
function placeholder(element) {
return $("<li style='color: red;' class='sortable' id='placeholder'>Drop Here!</li>");
}
$("#sortable-basic").kendoSortable({
connectWith: ".sortable-div",
filter: ".sortable", // Filter only list items that are direct child of the Sortable container.
// Use ".list-item" to allow parent items to use the nested Sortable.
placeholder: placeholder
});
$(".sortable-div").kendoSortable({
connectWith: "#sortable-basic",
filter: ".sortable",
placeholder: placeholder
});
});
#example {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
#playlist {
margin: 30px auto;
width: 300px;
background-color: #f3f5f7;
border-radius: 4px;
border: 1px solid rgba(0,0,0,.1);
}
#playlist-title span {
display: none;
}
#sortable-basic {
padding: 0;
margin: 0;
}
li.sortable {
list-style-type: none;
padding: 6px 8px;
margin: 0;
color: #666;
font-size: 1.2em;
cursor: move;
}
li.sortable:last-child {
border-bottom: 0;
border-radius: 0 0 4px 4px;
}
li.sortable span {
display: block;
float: right;
color: #666;
}
li.sortable:hover {
background-color: #dceffd;
}
li.hint {
display: block;
width: 200px;
background-color: #52aef7;
color: #fff;
}
li.hint:after {
content: "";
display: block;
width: 0;
height: 0;
border-top: 6px solid transparent;
border-bottom: 6px solid transparent;
border-left: 6px solid #52aef7;
position: absolute;
left: 216px;
top: 8px;
}
li.hint:last-child {
border-radius: 4px;
}
li.hint span {
color: #fff;
}
li.placeholder {
background-color: #dceffd;
color: #52aef7;
text-align: right;
}
<link href="https://kendo.cdn.telerik.com/2019.3.1023/styles/kendo.default-v2.min.css" rel="stylesheet"/>
<script src="https://kendo.cdn.telerik.com/2019.3.1023/js/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2019.3.1023/js/kendo.all.min.js"></script>
<div id="example">
<div id="playlist">
<div id="playlist-title"><span>My Playlist</span></div>
<ul id="sortable-basic">
<ul class="sortable sortable-div">
<li>drag div</li>
<li class="sortable">Papercut <span>3:04</span></li>
<li class="sortable">One Step Closer <span>2:35</span></li>
</ul>
<ul class="sortable sortable-div">
<li>drag div</li>
<li class="sortable">With You <span>3:23</span></li>
<li class="sortable">Points of Authority <span>3:20</span></li>
</ul>
<ul class="sortable sortable-div">
<li>drag div</li>
<li class="sortable">Crawling <span>3:29</span></li>
<li class="sortable">Runaway <span>3:03</span></li>
</ul>
<ul class="sortable sortable-div">
<li>drag div</li>
<li class="sortable">By Myself <span>3:09</span></li>
<li class="sortable">In the End <span>3:36</span></li>
</ul>
<ul class="sortable sortable-div">
<li>drag div</li>
<li class="sortable">A Place for My Head <span>3:04</span></li>
<li class="sortable">Forgotten <span>3:14</span></li>
</ul>
<ul class="sortable sortable-div">
<li>drag div</li>
<li class="sortable">Cure for the Itch <span>2:37</span></li>
<li class="sortable">Pushing Me Away <span>3:11</span></li>
</ul>
</ul>
</div>
</div>

Elements grid arranging CSS

I am trying to achieve a scenario: when you click on a box, it shows a "long box" (full width) in the next row. The problem is that I get a gap after the clicked object.
Is it possible show the "long box" in the next row without changing the structure of the small boxes using CSS?
Link to jsfiddle: jsfiddle.net/mhLv7zj1/
$(document).ready(function(){
$(".box").click(function(){
$(this).next('.open').toggleClass('toggled');
});
$(".open").click(function(){
$(this).toggleClass('toggled');
});
})
Here's one option. You can remove all the li class="open" from your HTML and instead have this algorithm on each click:
hide/remove any already open items
calculate the number of items in the flex row where the item that was clicked lives and its position
then you'll know where to make the insertion, so: at the end of this row, dynamically insert an open item (style it in advance so that it takes up an entire row (flex: 0 0 100%;)
Use flex and flex-basis properties.
$(document).ready(function() {
$(".box").click(function() {
$(this).next('.open').toggleClass('toggled');
});
$(".open").click(function() {
$(this).toggleClass('toggled');
});
})
ul {
display: flex;
list-style: none;
flex-direction: row;
flex-wrap: wrap;
}
.box {
background: blue;
height: 80px;
flex: 1 1 32%;
margin-right: 2px;
margin-bottom: 2px;
}
.open {
display: none;
background: red;
width: 100%;
height: 80px;
}
.toggled {
display: flex;
flex-basis: 66.5%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<ul>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
<li class="box"></li>
<li class="open"></li>
</ul>
The problem is that the red boxes are siblings of the blue boxes so when you make them display:block they push the other content around. You need to make the red boxes children of the blue boxes and use relative positioning to achieve your desired result.
let boxes = document.querySelectorAll('ul > li');
boxes.forEach(b => {
b.addEventListener('click', expand.bind(b));
});
function expand() {
this.querySelector('.open').classList.toggle('visible');
}
ul {
width: 100%;
display: flex;
flex-flow: row wrap;
list-style-type: none;
margin: 0;
padding: 0;
}
li {
position: relative;
flex-basis: 33%;
height: 150px;
background: blue;
border: 1px solid white;
}
div.open {
display: none;
position: relative;
top: calc(100% + 1px);
left: -1px;
width: calc(300% + 4px);
height: 150px;
border: 1px solid white;
background: red;
z-index: 1;
}
.visible {
display: block!important;
}
<ul>
<li> <div class="open"></div> </li>
<li> <div class="open"></div> </li>
<li> <div class="open"></div> </li>
<li> <div class="open"></div> </li>
<li> <div class="open"></div> </li>
<li> <div class="open"></div> </li>
<li> <div class="open"></div> </li>
<li> <div class="open"></div> </li>
</ul>
PS. This example isn't a perfect fixed replica of your code but it should get you on the right track.

Dropdown list not slide toggling

I cannot seem to understand why in the world my slide toggle is not working. could someone tell me what I'm missing? and then please explain to me what I was doing wrong? I have not done web dev in over 2 years, but this all looks solid to me, not sure what I'm missing.
$(document).ready(
function listItemsSmooth(){
$('.main-ul').children('.li').on('click', function() {
$(this).children('ul').slideToggle('slow');
});
$("#newFunction").click(listItemsSmooth);
});
.main-li-items{
display: inline-block;
text-align: center;
padding-left: 35px;
}
/*.main-li-items:hover .sub-li-items{
display:block;
}*/
.sub-li-items{
list-style-type: none;
text-align: left;
margin-left: -40.5px;
display: none
}
ul{
text-align: center;
position: absolute;
}
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"
type="text/javascript"></script>
<nav>
<nav class = "home-main-nav-menu">
<ul class = "main-ul" id ="newFunction">
<li class = "main-li-items">Home</li>
<li class = "main-li-items">About Me
<ul>
<li class = "sub-li-items">Education</li>
<li class = "sub-li-items">Lessons</li>
</ul>
</li>
<li class = "main-li-items">Blog</li>
<li class = "main-li-items">Contact
<ul>
<li class = "sub-li-items">Email</li>
<li class = "sub-li-items">Phone</li>
</ul>
</li>
<li class = "main-li-items">Portfolio
<ul>
<li class = "sub-li-items">Recent</li>
<li class = "sub-li-items">All</li>
</ul>
</li>
<li class = "main-li-items">Collaborate
<ul>
<li class = "sub-li-items"><a href = "#/">Now</li>
<li class = "sub-li-items"><a href = "#/">Later</li>
</ul>
</li>
</ul>
</nav>
</nav>
There are a couple of things contributing to this! The first is that your script is looking for a child element of class .li when it should be looking for the element li
Additionally, the CSS is hiding the <li> elements, not the <ul> which is the element being side-toggled.
$(document).ready(function(){
$('.main-ul').children('li').on('click', function() {
$(this).children('ul').slideToggle('slow');
});
});
.main-li-items{
display: inline-block;
text-align: center;
padding-left: 35px;
}
.main-li-items > ul {
display: none;
}
/*.main-li-items:hover .sub-li-items{
display:block;
}*/
.sub-li-items{
list-style-type: none;
text-align: left;
margin-left: -40.5px;
}
ul{
text-align: center;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<nav>
<nav class = "home-main-nav-menu">
<ul class = "main-ul" id = "newFunction">
<li class = "main-li-items">Home</li>
<li class = "main-li-items">About Me
<ul>
<li class = "sub-li-items">Education</li>
<li class = "sub-li-items">Lessons</li>
</ul>
</li>
<li class = "main-li-items">Blog</li>
<li class = "main-li-items">Contact
<ul>
<li class = "sub-li-items">Email</li>
<li class = "sub-li-items">Phone</li>
</ul>
</li>
<li class = "main-li-items">Portfolio
<ul>
<li class = "sub-li-items">Recent</li>
<li class = "sub-li-items">All</li>
</ul>
</li>
<li class = "main-li-items">Collaborate
<ul>
<li class = "sub-li-items">Now</li>
<li class = "sub-li-items">Later</li>
</ul>
</li>
</ul>
</nav>
</nav>
You need to correct so many things so just compare your code and my code :
Fiddle
$(document).ready(function(){
function listItemsSmooth(){
$(this).find('ul').slideToggle('slow');
}
$(".main-li-items").click(listItemsSmooth);
});
.main-li-items{
display: block;
text-align: center;
float: left;
padding-left: 21px;
}
.main-li-items > ul{
display: none;
}
.sub-li-items{
list-style-type: none;
text-align: left;
margin-left: -40.5px;
}
ul{
text-align: center;
position: absolute;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<nav>
<nav class = "home-main-nav-menu">
<ul class = "main-ul" id ="newFunction">
<li class = "main-li-items">Home</li>
<li class = "main-li-items">About Me
<ul>
<li class = "sub-li-items">Education</li>
<li class = "sub-li-items">Lessons</li>
</ul>
</li>
<li class = "main-li-items">Blog</li>
<li class = "main-li-items">Contact
<ul>
<li class = "sub-li-items">Email</li>
<li class = "sub-li-items">Phone</li>
</ul>
</li>
<li class = "main-li-items">Portfolio
<ul>
<li class = "sub-li-items">Recent</li>
<li class = "sub-li-items">All</li>
</ul>
</li>
<li class = "main-li-items">Collaborate
<ul>
<li class = "sub-li-items"><a href = "#"/>Now</li>
<li class = "sub-li-items"><a href = "#"/>Later</li>
</ul>
</li>
</ul>
</nav>
</nav>

Categories