append items to ul element using JavaScript permanently - javascript

I've got a few divs, and it's a dashboard kinda website so I need to update it everyday.
I can manually edit the HTML and all but that's you know...inefficient.
Each div has a ul element in it, and everyday I need to add a few li elements.
I've tried a JavaScript function that appends li elements and I'll add it in the code snippet too. But still, it's kinda temporary because if I delete that line of code in my js file the added li element will also disappear. So I'm looking for a way to append li elements to an unordered list permanently, and it would be nice to have a way to delete them too when they get really old.
function append(ul, data) {
try {
ul.appendChild(document.createElement("li")).innerHTML = data;
} catch (e) {
console.error(e);
console.log("error boi");
}
}
append(document.getElementById("ul-1"), "door")
div {
background-color: cyan;
height: 300px;
width: 500px;
}
<div id="1">
div 1
<br />
<ul id="ul-1">
<li>reeeeeeeee</li>
<li>ramen ramen ramen ramen</li>
<li>..........................</li>
<!-- have to append few li items every day-->
</ul>
</div>
<br>
<div id="2">
div 2
<br />
<ul id="ul-2">
<li>ok</li>
<li>ravioli ravioli ravioli ravioli</li>
<li>..........................</li>
</ul>
</div>

Note ↓:
This piece of code just shows an example of how you can add or remove items easily from and to the lists!
As #Chris G and #L.K. Kabilan mentioned, to store data you either need a Database or in the Local Storage. However, by storing data in the Local Storage you're taking a risk of losing the data because it's stored only in the browser.
// Get the elements
var input = document.getElementById('input');
var btn = document.getElementById('btn');
var select = document.getElementById('select');
var selected = select.options[select.selectedIndex].value;
// Delete the item of the clicked 'X' icon
function delLi(){
var del = document.querySelectorAll('li span');
for (var i = 0; i < del.length; i++){
del[i].addEventListener('click', (e) => {
e.target.parentElement.remove();
});
}
}
// Get the selected option
select.addEventListener('change', () => {
selected = select.options[select.selectedIndex].value;
});
// Wrap the input value in an item and append it to the selected list
btn.addEventListener('click', (e) => {
var val = input.value;
if(val == '' || val.length <= 0){
e.preventDefault();
} else {
var li = `<li><span>×</span><p>${val}</p></li>`;
document.getElementById(selected).innerHTML += li;
delLi();
}
});
delLi();
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.wrapper {
background-color: aqua;
width: 500px;
margin: 50px auto;
border-radius: 5px;
padding: 10px;
}
ul {
list-style-type: none;
line-height: 1.5;
}
ul::before {
content: attr(aria-label);
font-weight: bold;
font-size: 20px;
}
li {
display: flex;
align-items: center;
}
li span {
font-size: 18px;
font-weight: bold;
margin-right: 10px;
cursor: pointer;
}
form {
margin: 0 auto;
width: 500px;
background-color: rgb(233, 208, 17);
padding: 10px;
}
#input {
height: 30px;
width: 100%;
border-radius: 5px;
border: none;
padding: 0 10px;
display: block;
margin-bottom: 10px;
}
#btn {
width: 100px;
height: 34px;
background-color: green;
color: white;
border: none;
border-radius: 5px;
display: inline-block;
cursor: pointer;
}
<main>
<div class="wrapper" id="wrapper-1">
<ul id="ul-1" aria-label="List 1">
<li><span>×</span><p>Item 1</p></li>
<li><span>×</span><p>Item 2</p></li>
<li><span>×</span><p>Item 3</p></li>
<li><span>×</span><p>Item 4</p></li>
</ul>
</div>
<div class="wrapper" id="wrapper-2">
<ul id="ul-2" aria-label="List 2">
<li><span>×</span><p>Item 1</p></li>
<li><span>×</span><p>Item 2</p></li>
</ul>
</div>
<form action="">
<input id="input" type="text">
<select name="" id="select">
<option value="ul-1">List 1</option>
<option value="ul-2">List 2</option>
</select>
<input id="btn" type="button" value="Submit">
</form>
</main>

I guess u can use a JSON file to store and retrieve data, or u can go for PHP to get & retrieve data, yet u will be needing a Database, if I'm not wrong, using JSON would be more efficient.(If I'm wrong correct me)
check this link below https://www.w3schools.com/whatis/whatis_json.asp#:~:text=JSON%20stands%20for%20JavaScript%20Object,describing%22%20and%20easy%20to%20understand
Hope this answer helped u.

Related

When to Call JavaScript Toggle Function?

I have a drop down menu I need to make appear and disappear using pure JavaScript (no libraries/jQuery). Thus I am developing a toggle function. However despite trying several approaches, nothing seems to work. My current idea is to create a variable to hold the state of the menu (open or closed). Once the display of the menu changes from "none" to "block", the variable should change from "closed" to "open". Then an event listener would be added to the body element so when anything is clicked, the menu closes (i.e. the display property is changed back to "none").
Unfortunately the above doesn't seem work. When I put the If/else block outside of an event listener it fires when the page loads, but not when the menuToggle variable changes. If I put it or a function inside the menuPlaceholder event listener the menu won't open, probably due to the open and close code being called basically at the same time.
Clearly I am missing something, probably related to program control or function calling. Does anyone have any insights?
The code I am working with is below. Note the alert functions peppered throughout the code are for testing purposes only.
//Puts IDs for search preference selection box into variables
var menuPlaceholder = document.getElementById('searchSelection');
var menuDisplay = document.getElementById('searchOptions');
var boxLabel = document.getElementById('searchLabel');
//Puts IDs for text input box and submission into variables
var searchBoxPlaceholder = document.getElementById('searchInput');
var searchInput = document.getElementById('searchBox');
var submitButton = document.getElementById('submit');
//Adds class to each search option and puts ID of hidde field into variable
var searchPrefSubmission = document.getElementsByClassName('buttonSearch');
var hiddenInput = document.getElementById('searchChoice');
//Global variable to indicate whether searchOptions menu is opened or closed
var menuToggle = "closed";
//Closes element when one clicks outside of it.
function hideOnClickOutside(element) {
const outsideClickListener = event => {
if (!element.contains(event.target) && isVisible(element)) { // or use: event.target.closest(selector) === null
element.style.display = 'none'
removeClickListener()
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length )
//When the placeholder box is clicked, the option menu appears
menuPlaceholder.addEventListener('click', function (event){
menuDisplay.style.display = "block";
menuToggle = "open";
//Add click event to searchPref buttons
for (i = 0; i < searchPrefSubmission.length; i++) {
//Assigns value of the button to both the hidden input field and the placeholder box
searchPrefSubmission[i].addEventListener('click', function(event) {
hiddenInput.value=this.value;
boxLabel.innerHTML = this.value;
menuDisplay.style.display = "none";
menuPlaceholder.style.display = "inline-block";
});
}
});
//This code causes the text input box of the search form to appear when the background box is clicked
searchBoxPlaceholder.addEventListener('click', function(event){
searchInput.style.display = "inline";
submitButton.style.display = "inline";
//hideOnClickOutside(menuDisplay);
});
if (menuToggle == "open"){
document.body.addEventListener('click', function(event){
alert('Foo!');
})
}else{
alert('Boo!');
}
/*function toggleMenu () {
//menuDisplay.style.display = "none";
alert('Boo!');
menuToggle = "closed";
}*/
body {
font-family:Montserrat, sans-serif;
}
#searchOptionPlaceholder {
display: inline-block;
}
#searchSelection {
padding: 10px 20px;
margin-right: 10px;
background-color: #F0F3F5;
display: inline-block;
color: #000000;
width: 140px;
max-width: 200px;
max-height: 35px;
border: 2px solid black;
vertical-align: middle;
}
#searchSelection img {
float: right;
}
#searchLabel {
display: inline-block;
padding-top: 10px;
vertical-align: top;
}
#searchOptions {
display: none;
background-color: #F0F3F5;
position: absolute;
z-index: 2;
}
#searchOptions ul {
background-color: #F0F3F5;
padding: 5px;
}
#searchOptions li {
list-style-type: none;
border-bottom: 2px solid black;
}
#searchOptions li:hover {
background-color: #706868;
color: #ffffff;
}
.buttonSearch {
background-color: transparent;
border: none;
padding: 10px;
font-size: 14px;
}
.searchSubHeading {
font-size: 12px;
}
#searchInput {
display: inline-block;
background-color: #F0F3F5;
padding: 10px 100px;
position: relative;
top: 0px;
max-width: 350px;
border: 2px solid black;
vertical-align: middle;
}
#searchInput img {
position: relative;
left: 80px;
}
#searchBox {
display: none;
width: 80%;
background-color: #F0F3F5;
border: none;
font-size: 1.5em;
position: relative;
right: 50px;
vertical-align: middle;
}
#submit {
border: none;
background-image: url('https://library.domains.skidmore.edu/search/magnifyingGlass.png');
background-repeat: no-repeat;
background-size: contain;
width: 50px;
height: 30px;
position: relative;
right: -80px;
vertical-align: middle;
}
#otherLinks {
margin-top: 10px;
}
#otherLinks a{
color: #000000;
}
#otherLinks a:hover{
color: #006a52;
}
<h1>Library Search</h1>
<form method="post" action="https://library.domains.skidmore.edu/search/searchBox.php" id="librarySearch">
<div id="searchSelection"><span id="searchLabel">Catalog</span><img src="down.png" height="30px" width="30px" /></div>
<div id="searchOptions">
<ul>
<li><button type="button" name="searchPref" value="Catalog" class="buttonSearch">Catalog<br /><br /><span class="searchSubHeading">Search books and DVDs</span></button></li>
<li><button type="button" name="searchPref" value="SearchMore" class="buttonSearch">SearchMore<br /><br /><span class="searchSubHeading">Search everything</span></button></li>
<li><button type="button" name="searchPref" value="Journals" class="buttonSearch">Journals<br /><br /><span class="searchSubHeading">Search journals</span></button></li>
</ul>
</div>
<div id="searchInput">
<input type="hidden" id="searchChoice" name="searchPref" value="catalog" />
<input type="search" id="searchBox" size="60" name="searchText" placeholder="Search our holdings"/><button type="submit" id="submit"></button></div>
<div id="otherLinks">Advanced Catalog Search | WorldCat | eBooks</div>
</form>
Some issues:
Adding event listeners within an event listener is in most cases a code smell: this will add those inner listeners each time the outer event is triggered. Those listeners remain attached, and so they accumulate. So, attach all event handlers in the top-level script, i.e. on page load, and then never again.
The if ... else at the end will execute on page load, and then never again. So the value of menuToggle is guaranteed to be "closed". You need to put that if...else switch inside the handler, so that it executes every time the event triggers, at which time the menuToggle variable will possibly have a modified value.
The body element does not stretch (by default) over the whole window. If you want to detect a click anywhere on the page, you should attach the listener on the document element itself, not on document.body.
When the click on the menu placeholder is handled, you should avoid that this event "bubbles" up the DOM tree up to the document, because there you have the other handler that wants to hide the menu again. You can do this with event.stopPropagation().
The global variable is not absolutely necessary, but if you use it, then I would call it menuVisible and give it a boolean value: false at first, and possibly true later.
For actually toggling the menu, I would create a function, which takes the desired visibility (false or true) as argument, and then performs the toggle.
Do not use undeclared variables, like the for loop variable i. Define it with let.
Here is your code with those changes implemented. Of course, there is still a lot that could be improved, but I believe that goes beyond the scope of this question:
var menuPlaceholder = document.getElementById('searchSelection');
var menuDisplay = document.getElementById('searchOptions');
var boxLabel = document.getElementById('searchLabel');
var searchBoxPlaceholder = document.getElementById('searchInput');
var searchInput = document.getElementById('searchBox');
var submitButton = document.getElementById('submit');
var searchPrefSubmission = document.getElementsByClassName('buttonSearch');
var hiddenInput = document.getElementById('searchChoice');
// Changed name and type of global variable:
var menuVisible = false;
// Removed some functions ...
menuPlaceholder.addEventListener('click', function (event){
// Use new function for actually setting the visibility
toggleMenu(!menuVisible);
// Avoid that click event bubbles up to the document level
event.stopPropagation();
});
// Add these event handlers on page load, not within another handler
// Define loop variable with let
for (let i = 0; i < searchPrefSubmission.length; i++) {
//Assigns value of the button to both the hidden input field and the placeholder box
searchPrefSubmission[i].addEventListener('click', function(event) {
hiddenInput.value = this.value;
boxLabel.innerHTML = this.value;
// Use the new function for setting the visibility
toggleMenu(false);
menuPlaceholder.style.display = "inline-block";
});
}
searchBoxPlaceholder.addEventListener('click', function(event){
searchInput.style.display = "inline";
submitButton.style.display = "inline";
});
// Bind handler on document itself, and call new function
document.addEventListener('click', function(event) {
toggleMenu(false);
});
// new function to perform the toggle
function toggleMenu(show) {
menuDisplay.style.display = show ? "block" : "none";
menuVisible = show;
}
body {
font-family:Montserrat, sans-serif;
}
#searchOptionPlaceholder {
display: inline-block;
}
#searchSelection {
padding: 10px 20px;
margin-right: 10px;
background-color: #F0F3F5;
display: inline-block;
color: #000000;
width: 140px;
max-width: 200px;
max-height: 35px;
border: 2px solid black;
vertical-align: middle;
}
#searchSelection img {
float: right;
}
#searchLabel {
display: inline-block;
padding-top: 10px;
vertical-align: top;
}
#searchOptions {
display: none;
background-color: #F0F3F5;
position: absolute;
z-index: 2;
}
#searchOptions ul {
background-color: #F0F3F5;
padding: 5px;
}
#searchOptions li {
list-style-type: none;
border-bottom: 2px solid black;
}
#searchOptions li:hover {
background-color: #706868;
color: #ffffff;
}
.buttonSearch {
background-color: transparent;
border: none;
padding: 10px;
font-size: 14px;
}
.searchSubHeading {
font-size: 12px;
}
#searchInput {
display: inline-block;
background-color: #F0F3F5;
padding: 10px 100px;
position: relative;
top: 0px;
max-width: 350px;
border: 2px solid black;
vertical-align: middle;
}
#searchInput img {
position: relative;
left: 80px;
}
#searchBox {
display: none;
width: 80%;
background-color: #F0F3F5;
border: none;
font-size: 1.5em;
position: relative;
right: 50px;
vertical-align: middle;
}
#submit {
border: none;
background-image: url('https://library.domains.skidmore.edu/search/magnifyingGlass.png');
background-repeat: no-repeat;
background-size: contain;
width: 50px;
height: 30px;
position: relative;
right: -80px;
vertical-align: middle;
}
#otherLinks {
margin-top: 10px;
}
#otherLinks a{
color: #000000;
}
#otherLinks a:hover{
color: #006a52;
}
<h1>Library Search</h1>
<form method="post" action="https://library.domains.skidmore.edu/search/searchBox.php" id="librarySearch">
<div id="searchSelection">
<span id="searchLabel">Catalog</span>
<img src="down.png" height="30px" width="30px" />
</div>
<div id="searchOptions">
<ul>
<li>
<button type="button" name="searchPref" value="Catalog" class="buttonSearch">
Catalog<br /><br /><span class="searchSubHeading">Search books and DVDs</span>
</button>
</li>
<li>
<button type="button" name="searchPref" value="SearchMore" class="buttonSearch">
SearchMore<br /><br /><span class="searchSubHeading">Search everything</span>
</button>
</li>
<li>
<button type="button" name="searchPref" value="Journals" class="buttonSearch">
Journals<br /><br /><span class="searchSubHeading">Search journals</span>
</button>
</li>
</ul>
</div>
<div id="searchInput">
<input type="hidden" id="searchChoice" name="searchPref" value="catalog" />
<input type="search" id="searchBox" size="60" name="searchText" placeholder="Search our holdings"/>
<button type="submit" id="submit"></button>
</div>
<div id="otherLinks">
Advanced Catalog Search |
WorldCat |
eBooks
</div>
</form>

How to add images in the options of a <select> tag using vanilla js?

I am working with Sass and Vanilla Js. I want to know how I can make images appear before the text in a select tag:
Something like this: Select with images
This is an example of what I found (but uses JQuery): https://codepen.io/antonandoff/pen/PmQvBz
var langArray = [];
$('.vodiapicker option').each(function(){
var img = $(this).attr("data-thumbnail");
var text = this.innerText;
var value = $(this).val();
var item = '<li><img src="'+ img +'" alt="" value="'+value+'"/><span>'+ text +'</span></li>';
langArray.push(item);
})
$('#a').html(langArray);
$('.btn-select').html(langArray[0]);
$('.btn-select').attr('value', 'en');
$('#a li').click(function(){
var img = $(this).find('img').attr("src");
var value = $(this).find('img').attr('value');
var text = this.innerText;
var item = '<li><img src="'+ img +'" alt="" /><span>'+ text +'</span></li>';
$('.btn-select').html(item);
$('.btn-select').attr('value', value);
$(".b").toggle();
});
$(".btn-select").click(function(){
$(".b").toggle();
});
var sessionLang = localStorage.getItem('lang');
if (sessionLang){
var langIndex = langArray.indexOf(sessionLang);
$('.btn-select').html(langArray[langIndex]);
$('.btn-select').attr('value', sessionLang);
} else {
var langIndex = langArray.indexOf('ch');
console.log(langIndex);
$('.btn-select').html(langArray[langIndex]);
}
.vodiapicker{
display: none;
}
#a{
padding-left: 0px;
}
#a img, .btn-select img{
width: 12px;
}
#a li{
list-style: none;
padding-top: 5px;
padding-bottom: 5px;
}
#a li:hover{
background-color: #F4F3F3;
}
#a li img{
margin: 5px;
}
#a li span, .btn-select li span{
margin-left: 30px;
}
/* item list */
.b{
display: none;
width: 100%;
max-width: 350px;
box-shadow: 0 6px 12px rgba(0,0,0,.175);
border: 1px solid rgba(0,0,0,.15);
border-radius: 5px;
}
.open{
display: show !important;
}
.btn-select{
margin-top: 10px;
width: 100%;
max-width: 350px;
height: 34px;
border-radius: 5px;
background-color: #fff;
border: 1px solid #ccc;
}
.btn-select li{
list-style: none;
float: left;
padding-bottom: 0px;
}
.btn-select:hover li{
margin-left: 0px;
}
.btn-select:hover{
background-color: #F4F3F3;
border: 1px solid transparent;
box-shadow: inset 0 0px 0px 1px #ccc;
}
.btn-select:focus{
outline:none;
}
.lang-select{
margin-left: 50px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<select class="vodiapicker">
<option value="en" class="test" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/LetterA.svg/2000px-LetterA.svg.png">English</option>
<option value="au" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/NYCS-bull-trans-B.svg/480px-NYCS-bull-trans-B.svg.png">Engllish (AU)</option>
<option value="uk" data-thumbnail="https://glot.io/static/img/c.svg?etag=ZaoLBh_p">Chinese (Simplified)</option>
<option value="cn" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/NYCS-bull-trans-D.svg/2000px-NYCS-bull-trans-D.svg.png">German</option>
<option value="de" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/0/04/MO-supp-E.svg/600px-MO-supp-E.svg.png">Danish</option>
<option value="dk" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/F_icon.svg/267px-F_icon.svg.png">French</option>
<option value="fr" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/2000px-Google_%22G%22_Logo.svg.png">Greek</option>
<option value="gr" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/4H_Emblem.svg/1000px-4H_Emblem.svg.png">Italian</option>
</select>
<div class="lang-select">
<button class="btn-select" value=""></button>
<div class="b">
<ul id="a"></ul>
</div>
</div>
I know that using JQuery is much easier and that there are many examples, but I want to know if it is possible to do this using pure Js (Vanilla Js)
You should use a list instead of <select> / <option>, then you can set your image source in the data attributes. Then you can simply query all <li> elements inside your list class (or, better yet, add a class to each list item), and set the innerHTMl value to be what you want.
To simulate the behaviour of select/option, you will need to implement your own onclick events, which will set the value of the select button and replace the selected content.
See working example below.
const list = document.getElementById('vodiapicker');
const listElements = list.querySelectorAll('li');
const selectButton = document.getElementById("btn-select");
// build list
listElements.forEach((element) => {
// set image
element.innerHTML = `<img src="${element.getAttribute('data-thumbnail')}"/> <span>${element.innerText}</span>`;
// change current selection on click on item
element.onclick = () => {
// hide selection list
list.style.display = 'none';
// set selected
selectButton.setAttribute('value', element.getAttribute('value'));
selectButton.innerHTML = element.outerHTML;
};
});
// set the button to first element initially
selectButton.innerHTML = listElements[0].outerHTML;
selectButton.setAttribute('value', listElements[0].getAttribute('value'));
// toggle list visibility on button click
selectButton.onclick = () => {
list.style.display = list.style.display === 'block' ? 'none' : 'block';
};
#vodiapicker {
/* hide initially */
display: none;
}
#vodiapicker li {
cursor: pointer;
/* don't display the bullet for this list */
list-style: none;
}
#vodiapicker li img {
width: 12px;
}
#btn-select {
cursor: pointer;
list-style: none;
}
#btn-select img {
width: 12px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<!-- select button -->
<button id="btn-select" value=""></button>
<!-- option list -->
<ul id="vodiapicker">
<li value="en" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/3/3e/LetterA.svg/2000px-LetterA.svg.png">English</li>
<li value="au" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/f/fb/NYCS-bull-trans-B.svg/480px-NYCS-bull-trans-B.svg.png">Engllish (AU)</li>
<li value="uk" data-thumbnail="https://glot.io/static/img/c.svg?etag=ZaoLBh_p">Chinese (Simplified)</li>
<li value="cn" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/3/39/NYCS-bull-trans-D.svg/2000px-NYCS-bull-trans-D.svg.png">German</li>
<li value="de" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/0/04/MO-supp-E.svg/600px-MO-supp-E.svg.png">Danish</li>
<li value="dk" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/c/c2/F_icon.svg/267px-F_icon.svg.png">French</li>
<li value="fr" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/2000px-Google_%22G%22_Logo.svg.png">Greek</li>
<li value="gr" data-thumbnail="https://upload.wikimedia.org/wikipedia/commons/thumb/5/5e/4H_Emblem.svg/1000px-4H_Emblem.svg.png">Italian</li>
</ul>
</body>
</html>
You can use javascript dropdown with images, for example: https://selectron23.pluginus.net/ - fully configurable, no jQuery (pure js)

Clicking the add button does absolutely nothing and I dont know why

Does anybody know why the button wont react to input when clicked? I want the click to bring up a prompt and then use the text from the prompt and append it into the hmtl as a list item with the same css as the other list items.
$(".btn").click(function() {
var text = prompt('What do you need to do?')
var txt1 = $("<li id="
listItem "><p></p></li>").text(text);
$("#itemList").append(txt1);
});
body {
background: #bff0ff;
}
li {
display: inline-block;
float: left;
padding: 5px;
}
#list {
list-style-type: none;
}
#itemList {
list-style-type: none;
}
#listItem {
width: 250px;
height: 75px;
border-radius: 5px;
background: #5ABCB9;
}
#listItem p {
font-family: curive, sans-serif;
text-align: center;
font-size: 20px;
color: #
}
.btn {
height: 50px;
width: 50px;
border-radius: 50%;
border: 1px;
font-size: 40px;
background: #63E2C6;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<input type="button" class="btn" value="+" />
<ul id="itemList">
<li id="listItem">
<p>
Study for exams.
</p>
</li>
</ul>
If you are trying to add more li elements to your existing ul, try the following ( since with your current implementation p element would be ignored when rendered ) :
$(".btn").click(function() {
var text = prompt('What do you need to do?')
var $li = $('<li/>',{ 'class' : 'listItem' })
var $p = $('<p/>', { 'text' : text })
$($li).append($p);
$("#itemList").append($li);
});
Example : https://jsfiddle.net/9av0c8z3/
There's a few things you need to do. First of those should be to clean up the errors in your JS, i.e. this isn't a proper string:
"<li id="listItem"><p></p></li>"
Once you hit the second double quote (") you're no longer working with a string and it thinks listItem is a variable.
I personally use single quotes for strings (').
'<li id="listItem"><p></p></li>'
Then you'll have to redo how you're using IDs in CSS. IDs should be unique and not re-used, that's what a class is for. So I've changed instances of id="listItem" to class="listItem" and updated the CSS from #listItem to .listItem.
Also, when you do this $( '<li id="listItem"><p></p></li>' ).text( text ); the text gets added to the li and the p is not created. So create the p first, add the text to it then append it to the li.
After that I think you're good to go.
var $itemList = $( '#itemList' );
$( '.btn' ).click( function( e ) {
var text = prompt( 'What do you need to do?' ),
p = $( '<p>', { text: text } ),
li = $( '<li>', { "class": 'listItem' } ).append( p );
$itemList.append( li );
} );
body {
background: #bff0ff;
}
#itemList,
#itemList li {
list-style: none;
}
li {
float: left;
padding: 5px;
}
.listItem {
width: 250px;
height: 75px;
border-radius: 5px;
background: #5ABCB9;
}
.listItem p {
font-family: curive, sans-serif;
text-align: center;
font-size: 20px;
}
.btn {
height: 50px;
width: 50px;
border-radius: 50%;
border: 1px;
font-size: 40px;
background: #63E2C6;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<input type="button" class="btn" value="+">
<ul id="itemList">
<li class="listItem">
<p>
Study for exams.
</p>
</li>
</ul>

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>

jquery on handler not working for inserted element

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)
}

Categories

Resources