jquery on handler not working for inserted element - javascript

I've got a simple to-do list app. To-do items are inserted by jQuery as <li> items. When they're checked off, they're removed from #todolist and prepended to #donelist. I want to let the user replace to-do items they've accidentally checked off, hence the .on handler for #donelist .checkbox elements, but it's not working. I've been puzzling over this for an embarrassingly long amount of time. How can I get the click handler working for #donelist .checkboxes?
HTML:
<div id="topform">
<input type="text" id="task" placeholder=" New task...">
</div>
<ul id="todolist">
</ul>
<ul id="donelist">
</ul>
JS:
$('#todolist').on('click', '.checkbox', checkTask);
$('#donelist').on('click', '.checkbox', replaceTask);
$('input').keypress(function (e) {
if (e.which == 13) {
addTask(e);
}
});
function addTask(e) {
taskToAdd = $('#task').val();
var listItem = "<li><span class='todotask'>" + taskToAdd + "</span><div class='checkbox'></div></li>";
$('#todolist').prepend(listItem);
}
function checkTask() {
var listItem = $(this).parent();
listItem.remove();
$('#donelist').prepend(listItem);
}
function replaceTask() {
alert('hey buddy');
}
Full CSS:
html,
body {
margin: 0;
padding: 0;
background-color: #313131;
font-family: 'Helvetica', sans-serif;
}
#task {
width: 98%;
margin: 5px auto 7px auto;
padding: 0;
display: block;
height: 45px;
border: none;
border-radius: 2px;
font-size: 25px;
background-color: #F7F7F7;
}
ul {
margin: 0 auto 0 auto;
padding: 0;
width: 98%;
}
li {
list-style-type: none;
padding: 0;
margin: 5px auto 0 auto;
width: 100%;
height: 45px;
line-height: 45px;
position: relative;
font-size: 25px;
border-radius: 2px;
background-color: #F7F7F7;
}
#donelist li {
opacity: .5;
text-decoration: line-through;
}
.todotask {
margin-left: 7px;
}
.checkbox {
height: 31px;
width: 31px;
border-radius: 2px;
background-color: #C1C1C1;
position: absolute;
right: 7px;
top: 7px;
}
checkTask() works just fine, which is what really confuses me. checkTask() is called when the user clicks on a dynamically inserted element (a div in a li that's inserted by addTask(). Why doesn't replaceTask() fire as well?

Having the corresponding HTML in the OP would have helped, so I've had to guess a bit about how the structure, but here's a working example of what I think you're looking for:
HTML
<h1>ADD</h1>
<input id="task"></input>
<button id="add">Add</button>
<h1>TODO</h1>
<ul id="todolist">
<li><span class='todotask'>" Take out the garbage "</span><div class='checkbox'></div></li>
<li><span class='todotask'>" Do the dishes "</span><div class='checkbox'></div></li>
</ul>
<h1>DONE</h1>
<ul id="donelist">
</ul>
CSS
.checkbox{
width: 15px;
height: 15px;
background-color: black;
display: inline-block;
cursor: pointer;
}
JavaScript inside document.ready()
$('#todolist').on('click', '.checkbox', checkTask);
$('#donelist').on('click', '.checkbox', replaceTask);
$("#add").click(addTask);
function addTask(e) {
taskToAdd = $('#task').val();
var listItem = "<li><span class='todotask'>" + taskToAdd + "</span><div class='checkbox'></div></li>";
$('#todolist').prepend(listItem);
}
function checkTask() {
var listItem = $(this).parent();
listItem.remove();
$('#donelist').prepend(listItem);
}
function replaceTask() {
var listItem = $(this).parent();
listItem.remove();
$('#todolist').prepend(listItem)
}

Related

Changing a span field to an input field for updating information

I am creating a way to edit dynamic content. I found a question on here that got me started in terms of changing text (spans in my case) into input fields.
Currently, I can't figure out the following issue. When you click "Edit" (on the right side) the input fields replace the span (this is what I want), but when when you click outside of the input the input fields add new span fields instead of replacing the input fields.
I am wanting the styling and the fields to constantly stay in their original place.
Does anyone see what I am doing wrong?
var projID = '';
//Obtaining ID and Editing the projects
$(document.body).on('click', '.recEdit', '[data-editable]', function() {
projID = $(this).parent().data('recid');
console.log('Project ID is..... ' + projID);
var $el = $(this).parent().children().find('span');
var $input = $('<input/>').val( $el.text() );
$el.replaceWith( $input );
var save = function(){
var $p = $('<span data-editable class="recBaseFormat" />').text( $input.val() );
$input.replaceWith( $p );
};
/**
We're defining the callback with `one`, because we know that
the element will be gone just after that, and we don't want
any callbacks leftovers take memory.
Next time `p` turns into `input` this single callback
will be applied again.
*/
$input.one('blur', save).focus();
});
.recentProjectCont {
width: 98%;
height: 85px;
border-bottom: 1px solid #ccc;
padding: 10px 0;
margin: 0 10px;
display: block;
position: relative;
}
.recentProjectImg {
width: 100px;
height: 85px;
display: inline-block;
vertical-align: top;
}
.recentProjectImg img {
width: 100%;
height: 100%;
object-fit: cover;
}
.recProjInfoCont {
display: inline-block;
vertical-align: top;
width: 80%;
height: 100%;
margin-left: 20px;
}
.recInfoCont1, .recInfoCont2 {
height: 100%;
display: inline-block;
vertical-align: top;
}
.recInfoCont1 {
width: 40%;
}
.recInfoCont2 {
width: 52%;
text-align: right;
}
.recBaseFormat, .projectViews {
letter-spacing: .1rem;
line-height: 1.4em;
color: #2f2f2f;
display: block;
margin-bottom: 5px;
}
.recProjName {
font-size: 1.1rem;
font-family: 'Muli', sans-serif;
}
.recInfoStat, .projectViews {
font-size: .7rem;
font-family: 'Nunito', sans-serif;
}
.recEdit {
position: absolute;
top: 20%;
left: 97%;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="recentProjectCont">
<div class="recProjInfoCont">
<div class="recInfoCont1">
<span class="recProjName recBaseFormat" data-editable>Name</span>
<span class="recInfoStat recBaseFormat recAlt" data-editable>Alt</span>
<span class="recInfoStat recBaseFormat recCat" data-editable>Category</span>
</div>
<div class="recInfoCont2">
<span class="recInfoStat recBaseFormat" data-editable>Status</span>
<span class="recInfoStat recBaseFormat" data-editable>Creator</span>
</div>
</div>
<div class="recEdit">Edit</div>
</div>
This code could definitely be optimized, but it should get you going in the right direction. There were a few issues with your code. The issue I mentioned above, which is that your selector was only targeting the last span element within the parent element. We can solve that by using the each method to loop over every span within the parent. Another issue is that you were losing the classes for your spans when you were replacing them with inputs. I've solved that by saving a list of classes for each span before replacing them with an input so that they can be reapplied when they are converted back to spans. Finally, you were firing the save function for all inputs on blur of any input, meaning that the user would only be able to edit one span and then when they clicked out, all inputs would have been converted back. Instead, now it will only convert back when you unfocus each specific input.
var projID = '';
//Obtaining ID and Editing the projects
$(document.body).on('click', '.recEdit', '[data-editable]', function() {
projID = $(this).parent().data('recid');
console.log('Project ID is..... ' + projID);
$(this).parent().children().find('span').each(function() {
var classList = $(this).attr('class');
$input = $('<input/>').val($(this).text());
$(this).replaceWith($input);
$input.on('blur',function() {
$(this).replaceWith('<span data-editable class="' + classList + '">' + $(this).val() + '</span>');
});
});
});
.recentProjectCont {
width: 98%;
height: 85px;
border-bottom: 1px solid #ccc;
padding: 10px 0;
margin: 0 10px;
display: block;
position: relative;
}
.recentProjectImg {
width: 100px;
height: 85px;
display: inline-block;
vertical-align: top;
}
.recentProjectImg img {
width: 100%;
height: 100%;
object-fit: cover;
}
.recProjInfoCont {
display: inline-block;
vertical-align: top;
width: 80%;
height: 100%;
margin-left: 20px;
}
.recInfoCont1, .recInfoCont2 {
height: 100%;
display: inline-block;
vertical-align: top;
}
.recInfoCont1 {
width: 40%;
}
.recInfoCont2 {
width: 52%;
text-align: right;
}
.recBaseFormat, .projectViews {
letter-spacing: .1rem;
line-height: 1.4em;
color: #2f2f2f;
display: block;
margin-bottom: 5px;
}
.recProjName {
font-size: 1.1rem;
font-family: 'Muli', sans-serif;
}
.recInfoStat, .projectViews {
font-size: .7rem;
font-family: 'Nunito', sans-serif;
}
.recEdit {
position: absolute;
top: 20%;
left: 97%;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="recentProjectCont">
<div class="recProjInfoCont">
<div class="recInfoCont1">
<span class="recProjName recBaseFormat" data-editable>Name</span>
<span class="recInfoStat recBaseFormat recAlt" data-editable>Alt</span>
<span class="recInfoStat recBaseFormat recCat" data-editable>Category</span>
</div>
<div class="recInfoCont2">
<span class="recInfoStat recBaseFormat" data-editable>Status</span>
<span class="recInfoStat recBaseFormat" data-editable>Creator</span>
</div>
</div>
<div class="recEdit">Edit</div>
</div>
Finally, as others have mentioned, another option would be to use the contenteditable attribute on your spans. This is an HTML solution for editing HTML elements that are not editable by default. It essentially does the same thing you're trying to do with Javascript, but it's much cleaner. It also has very good browser support. One drawback to this solution would be that it will not be immediately clear to the user that the element is editable like it would be with an actual button that says "Edit." But there are some solutions for that as well.
<span contenteditable="true">You can edit me</span>
You could use juste the contenteditable attribute toggle each click !

Assign a value to input field

let slider = document.getElementById("slider");
let rightBtn = document.getElementById("rightbutton");
let leftBtn = document.getElementById("leftbutton");
let element = document.getElementById("elementtype").innerHTML;
let celciusBoiling = document.getElementById("celciusboiling").value;
let chlorine = ["Chlorine", 100, 200];
function moveSliderRight() {
if (rightBtn.onclick) {
slider.value++;
}
}
function moveSliderLeft() {
if (leftBtn.onclick) {
slider.value--;
}
}
function main() {
moveSliderRight();
moveSliderLeft();
if (slider.value == parseInt(2)) {
element = chlorine[0];
celciusBoiling = chlorine[1];
}
}
main();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
background-color: peachpuff;
}
header {
width: 90%;
margin: 10px auto 0px;
}
header h1 {
text-align: center;
border: 1px solid black;
padding: 15px 0px;
}
.navbar {
width: 75%;
margin: 50px auto 50px;
padding: 10px 0px;
display: flex;
justify-content: space-around;
border: 1px solid black;
}
.navlinks {
border-right: 1px solid black;
width: 50%;
text-align: center;
display: block;
}
#nav3 {
border: none;
}
#intro {
margin: 0px auto 50px;
width: 40%;
text-align: center;
}
#slider {
-webkit-appearance: none;
background-color: grey;
width: 90%;
display: block;
margin: auto;
}
#slider::-webkit-slider-thumb {
cursor: pointer;
}
#slider::-moz-range-thumb {
cursor: pointer;
}
#valuetag {
text-align: center;
margin-top:25px;
}
h2 {
text-align: center;
font-size: 45px;
text-decoration: underline;
}
#display {
width: 90%;
margin-left: 50px;
margin-bottom: 50px;
font-size: 40px;
}
#display div {
display: inline-block;
width: 45%;
text-align: center;
}
span {
font-size: 15px;
}
.boiling {
margin-left: 6%;
}
.boilingpointslider {
text-align: center;
}
button {
margin: 20px 20px 20px 0px;
width: 75px;
}
<header>
<h1>Periodic Table Gases - Interative Slider</h1>
<nav>
<div class="navbar">
<div class="navlinks">Boiling Point</div>
<div class="navlinks" id="nav3">Melting Point</div>
</div>
</nav>
</header>
<div id="intro">
<p>Interact with the slider buttons to view the displayed properties held by gases, within the periodic table of elements.</p>
</div>
<h2 id="elementtype">Hydrogen</h2>
<div id="display">
<div class="boiling">
<h2>Boiling Point</h2>
<input id="celciusboiling" type="number" value="0"><span>℃</span>
<input id="fahrenboiling" type="number"><span>℉</span>
<input id="kelvinboiling" type="number"><span>K</span>
</div>
<div class="melting">
<h2>Melting Point</h2>
<input id="celciusmelting" type="number"><span>℃</span>
<input id="fahrenmelting" type="number"><span>℉</span>
<input id="kelvinmelting" type="number"><span>K</span>
</div>
</div>
<input type="range" min="0" max="9" value="0" id="slider">
<div class="boilingpointslider">
<button id="leftbutton" onclick="moveSliderLeft()">Left</button>
<button id="rightbutton" onclick="moveSliderRight()">Right</button>
</div>
I am having issues transferring a value to an input field.
Within the snippet linked their is a heading with the value hydrogen and to the bottom left their is a boiling point heading with a input field for celcius.
I'm trying to achieve a scenario whereby you move the slider along using the buttons and at each value the heading changes to a different element and the input value for just the celcius boiling point changes.
I can't get this to work though. The buttons are working to make the slider move left and right, but for whatever reason i cant get the value to appear within the input field or change the heading. I've displayed the code i have already to get the buttons to move the slider and a snippet of what i thought would allow the changes i want to take place when the slider value changes to 2. I cant get it to to work though
Thanks.
You don't show your HTML, but I presume that slider is an input (text or hidden).
The value attribute is a string, even if you assign it a number, so you need to first convert it to a integer if you want to increment or decrement it, like so:
slider.value = parseInt(slider.value)++ // or --
Note that also you are trying to parseInt(2) down in your main(), which makes no sense as 2 is already an integer.

Javascript Dropdown Staying open

In my site I made a simple dropdown menu, but my problem is that it won't close if mouseleave happens on the <span> that triggers the dropdown.
Here is my code:
//Find the dropdown span
var header = document.getElementById('drop');
//Find the ul with the links
var ul = document.getElementById('nav-dropdown');
//Get the width and apply it to the dropdown items
var width = drop.getBoundingClientRect().width;
ul.style.minWidth = width + "px";
//Round the corners on the last link
var links = document.getElementsByClassName('dropdown-link');
links[links.length - 1].style.borderRadius = "0 0 7px 7px";
var open = 0;
//Onhover, display the dropdown;
header.addEventListener("mouseover", function() {
ul.style.display = "block";
header.style.borderRadius = "7px 7px 0 0";
if (links[0].getBoundingClientRect().width > width) {
links[0].style.borderRadius = "0 7px 0 0";
}
open = 1;
});
//When the mouse leaves the menu, close it.
ul.addEventListener("mouseleave", function() {
ul.style.display = "none";
header.style.borderRadius = "7px";
open = 0;
});
//What I've tried to fix it:
/*
header.addEventListener("mouseleave", function() {
ul.style.display = "none";
header.style.borderRadius = "7px";
});
*/
/*Stylesheet for this stuff*/
* {
font-family: arial;
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 20px;
text-decoration: none;
list-style: none;
}
a:visited {
color: white;
}
a,
#drop {
color: white;
}
a:hover {
color: coral;
}
.header-links-container {
position: relative;
top: 0;
background: rgb(63, 83, 95);
width: 100%;
height: 80px;
opacity: .8;
z-index: 999;
}
.title {
font-weight: bold;
font-size: 30px;
padding: 20px 50px;
position: relative;
float: left;
color: white;
}
.header-links {
position: relative;
float: right;
vertical-align: middle;
}
.nav-links {
margin: auto;
padding-top: 20px;
padding-right: 30px;
}
.nav-link {
position: relative;
float: right;
padding: 0 20px;
font-size: 23px;
padding: 5px 10px;
margin: 5px;
background: #4471ba;
border-radius: 7px;
}
.nav-link:hover {
background: #4480ba;
color: #d1d1d1;
}
#nav-dropdown {
display: none;
margin-top: 42px;
margin-left: 5px;
position: absolute;
}
.dropdown-link {
color: black;
background-color: #ccc;
padding: 5px 10px;
}
.dropdown-link:hover {
color: #000;
background-color: #a7a7a7;
}
.dropdown-link:active {
color: white;
background-color: #3b8cfa;
}
<div class="header-links-container">
<h2 class="title">Title</h2>
<div class="header-links">
<ul class="nav-links">
<li class="nav-link">Photo Gallery</li>
<li class="nav-link">SLAP</li>
<li id="drop" class="nav-link"><span>Dropdown</span></li>
<ul id="nav-dropdown" class="jim">
<a href="#">
<li class="dropdown-link">Link 1</li>
</a>
<a href="#">
<li class="dropdown-link">Link 2</li>
</a>
<a href="#">
<li class="dropdown-link">Longer Link</li>
</a>
<a href="#">
<li class="dropdown-link">Vacuum</li>
</a>
</ul>
</ul>
</div>
</div>
<p>
Relavent JS lines start at Line 16
</p>
And here is the fiddle that might make more sense: https://jsfiddle.net/dLw1hu5n/6/
I've tried closing the dropdown like in the last code block, but then it won't stay open when you go to hover over the links. I've also tried making the menu close when the mouse hovers over the navbar div, but no luck there either.
Can I fix this or do I need to start from square 1?
I would prefere to solve this via css. However, in your case you can try the following:
function displayDropdown() {
ul.style.display = "block";
header.style.borderRadius = "7px 7px 0 0";
if (links[0].getBoundingClientRect().width > width) {
links[0].style.borderRadius = "0 7px 0 0";
}
open = 1;
}
function hideDropdown() {
ul.style.display = "none";
header.style.borderRadius = "7px";
open = 0;
}
//Onhover, display the dropdown;
header.addEventListener("mouseover", function() {
displayDropdown();
});
ul.addEventListener("mouseover", function() {
displayDropdown();
});
//When the mouse leaves the menu, close it.
ul.addEventListener("mouseleave", function() {
hideDropdown();
});
header.addEventListener("mouseleave", function() {
hideDropdown();
});
Your JS is fine but your event listener for mouseleave needs to be on the enclosing div. This way your element stays open until you hover outside of the header
t.addEventListener("mouseleave", function() {
ul.style.display = "none";
header.style.borderRadius = "7px";
open = 0;
});
What is t?
var t = document.getElementById(t);
What element has id T?
Try this fiddle to find out https://jsfiddle.net/dLw1hu5n/12/

ul - li to 2 drop targets

I am trying to put together this project.
In my list I have fruit & veg.I want to be able to drag the right item into the correct box. Once it is in the correct box ( dropped) it should be invisible.
Hope someone can help.
HTML
<header>
<h1>THIS IS A TEST PAGE</h1>
</header>
<nav>
</nav>
<section>
<h1>Choose a Box</h1>
<ul id="fruit">Fruit
</ul>
<ul id="veg">Veg
</ul>
</section>
<article>
<ul id="dragsource">
<li id="item1" draggable="true">Apple</li>
<li id="item2" draggable="true">Banana</li>
<li id="item3" draggable="true">Orange</li>
<li id="item4" draggable="true">Potato</li>
<li id="item5" draggable="true">Carrot</li>
<li id="item6" draggable="true">Pea</li>
</ul>
</article>
JS
window.onload = function() {
var target1 = document.getElementById("fruit");
var target2 = document.getElementById("veg");
var list = document.querySelectorAll("#dragsource li");
for (i = 0; i < list.length; i++) {
list[i].draggable = true;
list[i].ondragstart = function(event) {
var event = event || window.event;
var dt = event.dataTransfer;
dt.setData("text", event.target.id);
dt.effectAllowed = "move";
};
}
target1.ondragover = function(event) {
var event = event || window.event;
event.preventDefault();
};
target2.ondragover = function(event) {
var event = event || window.event;
event.preventDefault();
};
target2.ondrop = function(event) {
var event = event || window.event;
var dt = event.dataTransfer;
event.preventDefault();
var data = dt.getData("text");
target2.appendChild(document.getElementById("data"));
};
target1.ondrop = function(event) {
var event = event || window.event;
var dt = event.dataTransfer;
event.preventDefault();
var data = dt.getData("text");
target1.appendChild(document.getElementById(data));
};
};
CSS
header {
background-color: black;
color: yellow;
text-align: center;
padding: 5px;
}
nav {
line-height: 30px;
background-color: yellow;
height: 400px;
width: 100px;
float: left;
padding: 5px;
}
body,
html {
background-color: silver;
font-family: sans-serif;
color: black;
text-align: center;
}
section {
width: 482px;
height: 220px;
float: left;
text-align: center;
padding: 5px;
}
#fruit {
width: 90px;
height: 120px;
left: 150px;
top: 150px;
padding: 10px;
border: 2px solid green;
position: absolute;
}
#veg {
width: 200px;
height: 120px;
left: 340px;
top: 150px;
padding: 10px;
border: 2px solid green;
position: absolute;
}
article {
background-color: aqua;
height: 170px;
width: 482px;
float: right;
padding: 5px;
}
ul {
margin: left;
column-count: 3;
width: 50%;
text-align: left;
list-style: none;
}
li {
list-style-type: none;
padding: 5px;
margin: 2px;
background-color: #CCCCFF;
border: 2px double #CCCCCC;
}
footer {
background-color: black;
color: white;
clear: both;
text-align: center;
padding: 5px;
}
See fiddle: https://jsfiddle.net/cq2aw1dy/3/
Before starting - it should be noted in your target2.onDrop function, the last line you say document.getElementById("data") there shouldn't be any quotes there. That will give you some issues.
Since all of your fruits have ID's I think it would serve you better to make use of classes The way to do that would be to add a class to the dropped element that tells it to become invisible.
CSS
#fruit > .hiddenDrop, #veg > .hiddenDrop {
display: none;
}
Javascript - Place this inside of your .onDrop() functions
var element = document.getElementById(data);
element.setAttribute('class', 'hiddenDrop');
target.appendChild(element);
What this does is after the element is dropped, it adds the class hiddenDrop to that element which will then change it's display property to none
EDIT
You can do it with the css like this #fruit > *{display: none;}
It is saying if you drag into the fruit div, display is set to none.
See fiddle:
https://jsfiddle.net/cq2aw1dy/4/

Disappearing drop down menu

I am trying to create a disappearing drop down menu that disappears into the top of the page, and you can only see the word 'open'. This opens the the menu, the word open changes to the word close which when clicked makes the menu disappear again. Help would be much appricated.
<html>
<head>
<title>dropdown</title>
<link rel="stylesheet" type="text/css" href="dropdown_css.css">
<script type = "text/javascript">
function navagate(menu) {
var panel = document.getElementById(menu),maxh = "-362px", navg = document.getElementById('navag');
if (panel.style.marginTop == maxh){
panel.style.marginTop = "0px";
navag.innerHTML = "Close";
}
else {
panel.style.marginTop = maxh;
navag.innerHTML = "Open";
}
}
window.onload = function(){panel.style.marginTop = "-362px";}
</script>
<body>
<div id = "panel">
<ul>
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
<div id ="sections_button">
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
</html>
#panel {
width : 160px;
height: 130px;
background-color: gray;
margin-left: 30px;
margin-top:20px;
}
#panel li {
list-style-type: none;
}
Here, I've made a JS fiddle that may help you out: http://jsfiddle.net/942z0nhh/ I did not play around with the styling at all.
A few things I noticed:
You're making some mistakes that I think you wouldn't make if you indented properly. Take a look here, where you closed your body twice:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
Second, you have some spelling mistakes:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
vs
function navagate(menu) {
You can see there that your function would never be called because of it.
Lastly, your 'open' and 'close' a here:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
Was within the div your function was overwriting. The function would change it to 'close'- but then it wouldn't be visible to the user anyway! I moved it above, which I hope makes sense.
Please let me know if you have any other questions, or if I misunderstood.
You could also do it only with CSS. It's the "css checkbox hack". I'm having it not like you want it but it is pretty close. Changing the text from open to close should be also possible.
At the moment, I don't know how to move the open/close label below the ul list.
*, html {
padding: 0px;
font-family: sans-serif;
}
/* Checkbox Hack */
input[type=checkbox] {
position: absolute;
display: none;
}
label {
display: block;
cursor: pointer;
content: "close";
}
/* Default State */
#wrapper {
display: block;
background: gray;
color: white;
text-align: center;
}
/* Toggled State */
input[type=checkbox]:checked ~ #menu {
display: block;
background: lightgray;
color: black;
top:0px;
}
.menuToggle ul{
display: none;
width: 100%;
}
#menu {
padding-top: 5px;
margin: 0px;
list-style: none;
}
<div id="wrapper">
<div class="menuToggle">
<label for="toggle-1">open</label>
<input type="checkbox" id="toggle-1"/>
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
</div>
</div>
With jQuery you could do it like the example below.
I think it is now almost like you wanted it. Maybe some styling improvements are required.
With the css hack I couldn't manage the text change. With js you have more possibilities. You could also improve/modify the animations.
$(function() {
var $menuButton = $('#openButton');
var $menu = $('#menu');
var btnToggleAnim = function() {
$menuButton.animate({opacity: 'toggle'}, "fast");
};
var menuToggleAnim = function() {
$('#menu').animate({
height:'toggle',
//opacity: 'toggle'
}, { duration: "slow" });
};
$('#closeButton,#openButton').on('click', function() {
menuToggleAnim();
btnToggleAnim();
});
});
*, html {
padding: 0px;
font-family: sans-serif;
}
a {
text-decoration:none;
}
#openButton {
display:block;
background: gray;
color: #fff;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
#closeButton{
display: block;
background: gray;
color: #fff;
text-align: center;
border: 2px solid lightgray;
border-bottom-left-radius: 13px;
border-bottom-right-radius: 13px;
}
#wrapper {
display: block;
text-align: center;
}
#menu {
display: none;
background: lightgray;
color: black;
padding-top: 5px;
margin: 0px;
list-style: none;
}
#menu {
color: #000;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
open
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
<li>close</li>
</ul>
</div>

Categories

Resources