JavaScript, Pressing the enter key - javascript

My JavaScript assignment is a ''to-do list', the user needs to be able to press the enter key, I tried this code but it's not working. If anyone has suggestions please let me know! Thanks
EDIT: Here is my JavaScript, HTML and CSS file
EDIT II: Here are the directions in full
1. After inserting a new item, clear the input field
2. If the user presses the enter key, perform the same action as clicking the plus button.
3. Check to make sure that the user entered something into the input field adding it to the list
4. When the user clicks on the heading, so a prompt to allow them to change the title. Make sure they entered something before changing it.
window.addEventListener('load', function(){
var todos = document.getElementsByClassName('todo-item');
var removes = document.getElementsByClassName('remove');
document.getElementById('add-item').addEventListener('click', addItem, false);
document.querySelector('.todo-list').addEventListener('click', toggleCompleted, false);
document.querySelector('.todo-list').addEventListener('click', removeItem, false);
function toggleCompleted(e) {
console.log('=' + e.target.className);
if(e.target.className.indexOf('todo-item') < 0) {
return;
}
console.log(e.target.className.indexOf('completed'));
if(e.target.className.indexOf('completed') > -1) {
console.log(' ' + e.target.className);
e.target.className = e.target.className.replace(' completed', '');
} else {
console.log('-' + e.target.className);
e.target.className += ' completed';
}
}
function addItem() {
var list = document.querySelector('ul.todo-list');
var newItem = document.getElementById('new-item-text').value;
var newListItem = document.createElement('li');
newListItem.className = 'todo-item';
newListItem.innerHTML = newItem + '<span class="remove"></span>';
list.insertBefore(newListItem, document.querySelector('.todo-new'));
}
function valueField(input,val){
if(input.value == "")
input.value=val;
}
function clearField(input,val){
if(input.value == val)
input.value="";
}
function removeItem(e) {
if(e.target.className.indexOf('remove') < 0) {
return;
}
function handle(e){
var keycode
if(e.keyCode === ""){
}
return false;
}
var el = e.target.parentNode;
el.parentNode.removeChild(el);
}
});
body {
background-color: #BCDBF2;
font-family: Helvetica, Arial, sans-serif;
}
body > div {
width: 300px;
margin:50px auto;
}
h1 {
text-align: center;
}
.todo-list {
list-style: none;
padding: 0px;
}
.todo-item {
border: 2px solid #444;
margin-top: -2px;
padding: 10px;
cursor: pointer;
display: block;
background-color: #ffffff;
}
.todo-new {
display: block;
margin-top: 10px;
}
.todo-new input[type='text'] {
width: 260px;
height: 22px;
border: 2px solid #444;
}
.todo-new a {
font-size: 1.5em;
color: black;
text-decoration: none;
background-color: #ffffff;
border: 2px solid #444;
display: block;
width: 24px;
float: right;
text-align: center;
}
.todo-new a:hover {
background-color: #0EB0dd;
}
.remove {
float: right;
font-family: Helvetica, Arial, sans-serif;
font-size: 0.8em;
color: #dd0000;
}
.remove:before {
content: 'X';
}
.remove:hover {
color: #ffffff;
}
.todo-item::after:hover{
background-color: #dd0000;
color: white;
}
.todo-item:hover {
background-color: #0EB0FF;
color: white;
}
.completed {
text-decoration: line-through;
opacity: 0.5;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Lab 18 - Event Delegation</title>
<link rel='stylesheet' href='main.css'/>
</head>
<body>
<div>
<h1>To-Do List</h1>
<ul class='todo-list'>
<li class='todo-item'>4L 2% Milk
<span class='remove'></span></li>
<li class='todo-item'>Butter, Unsalted
<span class='remove'></span></li>
<li class='todo-item'>Dozen Eggs
<span class='remove'></span></li>
<li class='todo-item'>Walk the dog
<span class='remove'></span></li>
<li class='todo-item'>Cut the lawn
<span class='remove'></span></li>
<li class='todo-item'>Laundry
<span class='remove'></span></li>
<li class='todo-new'>
<input id='new-item-text' type='text'/>
<a id='add-item' href='#'>+</a>
</li>
</ul>
</div>
<script src='main.js'></script>
</body>
</html>

Look up the key code that will correspond to enter. One place to find this is on MDN KeyboardEvent:keyCode. Using that, you can write:
var ENTER = 13;
function handle(e){
if(e.keyCode === ENTER){
// insert a new line or whatever you want
}
return false;
}

You need to register the onkeypress event on a HTML element, for example on the input text, like this:
<input id='new-item-text' type='text' onkeypress="return handle(event)" />
Also, you can register the event on <body>or other HTML elements. And you can register the event using HTML or using Javascript.
In HTML:
<element onkeypress="myScript">
In JavaScript:
object.onkeypress=function(){myScript};
If you want to learn more about this event you can read this docs.
To know where is the handle function needs to be global (declared outside the load event).
The last thing to do, is to filter the enter button with e.keyCode === 13. Important: is a Number, not a String.
I put below all the code testable that you can see and run (I applied the example when press enter on the input text).
I hope to help you.
All the code
window.addEventListener('load', function() {
var todos = document.getElementsByClassName('todo-item');
var removes = document.getElementsByClassName('remove');
document.getElementById('add-item').addEventListener('click', addItem, false);
document.querySelector('.todo-list').addEventListener('click', toggleCompleted, false);
document.querySelector('.todo-list').addEventListener('click', removeItem, false);
function toggleCompleted(e) {
console.log('=' + e.target.className);
if (e.target.className.indexOf('todo-item') < 0) {
return;
}
console.log(e.target.className.indexOf('completed'));
if (e.target.className.indexOf('completed') > -1) {
console.log(' ' + e.target.className);
e.target.className = e.target.className.replace(' completed', '');
} else {
console.log('-' + e.target.className);
e.target.className += ' completed';
}
}
function addItem() {
var list = document.querySelector('ul.todo-list');
var newItem = document.getElementById('new-item-text').value;
var newListItem = document.createElement('li');
newListItem.className = 'todo-item';
newListItem.innerHTML = newItem + '<span class="remove"></span>';
list.insertBefore(newListItem, document.querySelector('.todo-new'));
}
function valueField(input, val) {
if (input.value == "")
input.value = val;
}
function clearField(input, val) {
if (input.value == val)
input.value = "";
}
function removeItem(e) {
if (e.target.className.indexOf('remove') < 0) {
return;
}
var el = e.target.parentNode;
el.parentNode.removeChild(el);
}
});
function handle(e) {
if (e.keyCode === 13) {
console.log("Doing something");
}
return true;
}
body {
background-color: #BCDBF2;
font-family: Helvetica, Arial, sans-serif;
}
body > div {
width: 300px;
margin: 50px auto;
}
h1 {
text-align: center;
}
.todo-list {
list-style: none;
padding: 0px;
}
.todo-item {
border: 2px solid #444;
margin-top: -2px;
padding: 10px;
cursor: pointer;
display: block;
background-color: #ffffff;
}
.todo-new {
display: block;
margin-top: 10px;
}
.todo-new input[type='text'] {
width: 260px;
height: 22px;
border: 2px solid #444;
}
.todo-new a {
font-size: 1.5em;
color: black;
text-decoration: none;
background-color: #ffffff;
border: 2px solid #444;
display: block;
width: 24px;
float: right;
text-align: center;
}
.todo-new a:hover {
background-color: #0EB0dd;
}
.remove {
float: right;
font-family: Helvetica, Arial, sans-serif;
font-size: 0.8em;
color: #dd0000;
}
.remove:before {
content: 'X';
}
.remove:hover {
color: #ffffff;
}
.todo-item::after:hover {
background-color: #dd0000;
color: white;
}
.todo-item:hover {
background-color: #0EB0FF;
color: white;
}
.completed {
text-decoration: line-through;
opacity: 0.5;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Lab 18 - Event Delegation</title>
<link rel='stylesheet' href='main.css' />
</head>
<body>
<div>
<h1>To-Do List</h1>
<ul class='todo-list'>
<li class='todo-item'>4L 2% Milk
<span class='remove'></span>
</li>
<li class='todo-item'>Butter, Unsalted
<span class='remove'></span>
</li>
<li class='todo-item'>Dozen Eggs
<span class='remove'></span>
</li>
<li class='todo-item'>Walk the dog
<span class='remove'></span>
</li>
<li class='todo-item'>Cut the lawn
<span class='remove'></span>
</li>
<li class='todo-item'>Laundry
<span class='remove'></span>
</li>
<li class='todo-new'>
<input id='new-item-text' type='text' onkeypress="return handle(event)" />
<a id='add-item' href='#'>+</a>
</li>
</ul>
</div>
<script src='main.js'></script>
</body>
</html>

I believe that the key code for enter is 13. See below.
function handle(e){
if(e.keyCode === 13){
}
return false;
}

Related

How to change active tab back to not active after validation failure in JavaScript

I have a Details tab with a dropdown that swaps forms in and out and a Result tab that displays the result in a graph. When the user selects "Result" I want to validate the data entry before going to the result tab.
What happens is that when the Result tab is clicked it becomes active and changes color. I then goes into script.js displayResultContent() which validates the data entry. If the data is not valid I don't want to proceed to the result tab so I only show the result if the data is okay.
The issue I have is that if the data is invalid, error messages are displayed on the form, but the Result tab remains displayed with the active color instead of changing to the non active color. Once the user clicks the mouse on the screen the tab changes color.
Is there any way to make this tab change to the non active color without having to click on the screen? I haven't yet put the media queries in so this looks best on a wide screen, otherwise the tabs are displayed below each other instead of beside. It still works though.
const DATE_TYPE_PAST = 0;
const DATE_TYPE_FUTURE = 1;
const SUCCESS = 0;
const ERROR = 1;
$(function() {
$('#details-tab').click(displayDetails);
$('#result-tab').click(displayResultContent);
$("#your-details-tab").click(displayYourDetailsTab);
$("#your-superannuation-tab").click(displayYourSuperannuationTab);
});
function displayYourDetailsTab() {
removeAllForms();
var form = $("#your-details-form");
form.show();
$('#details-tab').html("Your Details");
}
function displayYourSuperannuationTab() {
removeAllForms();
var form = document.getElementById("your-superannuation-form");
form.style.display = 'block';
$('#details-tab').html("Your Superannuation");
}
function removeAllForms() {
var forms = document.getElementsByTagName('form');
for (var i = 0; i < forms.length; i++) {
forms[i].style.display = "none";
}
}
function displayDetails() {
$('#details').show();
$('#result').hide();
$('#result-tab').removeClass('active');
$('#details-tab').addClass('active');
}
function displayResultContent() {
// FIRST CHECK DATA ENTRY
const dateResult = checkDate(document.getElementById("date-of-birth"), DATE_TYPE_PAST);
const rentResult = checkMandatoryWholeNumber(document.getElementById("fortnightly-rent"), "Fortnightly rent ", 0, 999);
if (dateResult === SUCCESS && rentResult === SUCCESS) {
$('#result').show();
$('#details').hide();
$('#result-tab').addClass('active');
$('#details-tab').removeClass('active');
}else {
$('#result-tab').removeClass('active');
}
}
const showError = (input, message) => {
// get the form-field element
let formField = input.closest(".form-field");
// add the error class
formField.classList.remove('success');
formField.classList.add('error');
// show the error message
const error = formField.querySelector('small');
error.textContent = message;
};
const showSuccess = (input) => {
// get the form-field element
let formField = input.closest(".form-field");
// remove the error class
formField.classList.remove('error');
formField.classList.add('success');
// hide the error message
const error = formField.querySelector('small');
error.textContent = '';
};
const yourDetailsForm = document.getElementById("your-details-form");
if (yourDetailsForm != null) {
yourDetailsForm.addEventListener('input', function(e) {
switch (e.target.id) {
case 'date-of-birth':
checkDate(document.getElementById(e.target.id), DATE_TYPE_PAST);
break;
case 'fortnightly-rent':
checkMandatoryWholeNumber(document.getElementById(e.target.id), "Fortnightly rent ", 0, 999);
break;
}
});
}
const isRequired = value => value !== '';
const isValidDate = function(date) {
return (date !== "Invalid Date") && date !== ("Nan");
}
function checkDate(dateElement, dateType) {
const val = dateElement.value;
const newDate = new Date(val);
if (isValidDate(newDate)) {
const today = new Date();
today.setHours(0,0,0,0);
if (dateType === DATE_TYPE_PAST) {
if (newDate < today) {
// okay
showSuccess(dateElement);
return SUCCESS;
}else {
// error
showError(dateElement, "date must be in the past");
return ERROR;
}
} if (dateType === DATE_TYPE_FUTURE) {
if (newDate >= today) {
// okay
showSuccess(dateElement);
return SUCCESS;
}else {
// error
showError(dateElement, "date must be in the future");
return ERROR;
}
}
}else {
showError(dateElement, "date is mandatory");
return ERROR;
}
}
$(document).on("keydown", ".whole-number", function (e) {
const invalidChars = [
"-",
"+",
"e",
".",
];
if (invalidChars.includes(e.key)) {
e.preventDefault();
}
});
function checkMandatoryWholeNumber(element, prefix, min, max) {
if (!isRequired(element.value)) {
showError(element, prefix + " is mandatory");
return ERROR;
}
const val = parseInt(element.value);
if (val < min || val > max) {
showError(element, prefix + " must be between " + min + " and " + max);
return ERROR;
}
showSuccess(element);
return SUCCESS;
}
html, body {
height: 100%;
margin: 0;
overflow:hidden;
}
.content {
height:100%;
margin-left: 15%;
margin-right: 15%;
display:flex;
flex-flow: column;
}
.content .result-content {
background-color: #FFF;
flex: 1 1 auto;
margin-left:1%;
margin-right:1%;
display: none;
}
#tabs {
width: 70%;
margin: 0 auto;
padding: 0;
border-bottom: 7px solid #FE6D73;
margin-top: 50px;
}
.form-container {
width: 70%;
height: 98%;
background-color: #FFF;
margin: 0 auto;
overflow-y: auto;
overflow-x: hidden;
padding-bottom: 7px;
box-sizing: border-box;
padding-top: 0px;
}
li {
list-style: none;
}
/*******************************************************************/
/* NAV TABS */
/******************************************************************/
.nav-link {
border-radius: 15px 15px 0px 0px !important;
text-decoration: none;
height: 40px;
font-size: 80%;
background-color: #eeeeee !important;
color: #aaaaaa;
}
.nav-link.active,
.nav-link:active,
.nav-link:hover,
.nav-link:focus {
border-radius: 15px 15px 0px 0px !important;
background-color: #FE6D73 !important;
color: #FEF9EF !important;
}
.nav-link-left {
width: 255px;
}
.nav-link-right {
width: 100px;
}
.nav-tabs>li>ul>li>a {
width: 200px;
}
.dropdown-menu {
z-index: 999999;
}
.nav-tabs>li>ul {
background-color: #FE6D73 !important;
}
/* Remove border from tabs */
.nav-tabs .nav-link {
border: 0px solid transparent;
}
/* This is the dropdown link */
.dropdown-item {
background-color: #FE6D73 !important;
color: #FEF9EF !important;
}
/* Border at bottom of each item in the drop down list */
.dropdown-menu>li {
border-bottom: 1px solid #FEF9EF !important;
}
.nav-tabs>li>ul>li.active>a, .nav-tabs>li>ul>li.active>a:focus, .nav-tabs>li>ul>li>a:hover {
background-color: #FEF9EF !important;
color: #FE6D73 !important;
}
.dropdown-menu {
border-top: 1px solid #FEF9EF;
}
/*******************************************************************/
/* FORMS */
/******************************************************************/
input[type="number"] {
/*80px*/
width: 5em;
font-size: 80%;
}
input[type="date"] {
border: 1px solid #cccccc;
}
input {
border: 1px solid #cccccc;
}
#your-superannuation-form {
display: none;
}
form {
margin-top: 20px;
background-color: beige;
}
.form-group {
margin-top: 20px;
}
.disabled-link {
cursor: not-allowed;
opacity: 0.5;
}
.disabled-text {
opacity: 0.5;
}
.enabled-text {
opacity: 1.0;
}
.enabled-link {
cursor: pointer;
opacity: 1.0;
}
.pointer-not-allowed{
cursor: not-allowed;
}
.pointer-allowed {
cursor: pointer;
}
form label {
font-family: 'opensansreg', 'Verdana', 'Arial';
}
.form-text {
font-family: Georgia;
align-self: start;
}
.button-text {
font-family: Georgia;
font-size:80%;
}
.input-text {
font-family: Consolas, Lucida Console, monospace;
}
:root {
--error-color: #dc3545;
--success-color: #cccccc;
--warning-color: #ffc107;
}
.form-field input:focus {
outline: none;
}
.form-field.error input {
/* border-color: var(--error-color); */
border: 1px solid #dc3545;
}
.form-field.success input {
/* border-color: var(--success-color); */
border: 1px solid #cccccc;
}
.form-field small {
color: var(--error-color);
font-size: 70%;
display: block;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="style.css"/>
</head>
<body>
<div id="tabs">
<ul class="nav nav-tabs">
<li class="dropdown nav-item">
<a class="nav-link nav-link-left dropdown-toggle active" id="details-tab" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Details</a>
<ul class="dropdown-menu">
<li><a class="dropdown-item" id="your-details-tab" href="#">Your Details</a></li>
<li><a class="dropdown-item" id="your-superannuation-tab" href="#">Your Superannuation</a></li>
</ul>
</li>
<li class="nav-item">
<a class="nav-link nav-link-right" id="result-tab" href="#" tabindex="-1">Result</a>
</li>
</ul>
</div>
<div class="content">
<div class="form-container" id="details">
<form id="your-details-form">
<div class="form-group">
<label for="date-of-birth" class="form-text">Date of Birth</label>
<div class="form-field">
<input type="date" class="form-text" id="date-of-birth" name="date-of-birth">
<small></small>
</div>
</div>
<div class="form-group">
<label for="fortnightly-rent" class="form-text">Fortnightly Rent</label>
<div class="form-field">
<input type="text" class="input-text" size="4" id="fortnightly-rent" name="fortnightly-rent"
onKeyDown="if (this.value.length == 4) this.value = this.value.slice(0, -1);"/>
<small></small>
</div>
</div>
</form>
<form id="your-superannuation-form">
THIS IS YOUR SUPERANNUATION FORM
</form>
</div> <!-- end form-container-->
<div class="result-content" id="result">
THIS IS THE RESULT
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js#3.8.0/dist/chart.min.js"></script>
<script type="text/javascript" src="script.js"></script>
</body>
</html>
Please remove the .nav-link:focus selector from this declaration
.nav-link.active,
.nav-link:active,
.nav-link:hover{
border-radius: 15px 15px 0px 0px !important;
background-color: #FE6D73 !important;
color: #FEF9EF !important;
}
Currently when you click on a tab the focus remains and it goes only after clicking away
.nav-link.active,
.nav-link:active,
.nav-link:hover,
.nav-link:focus <---- It works properly after removing this
{
border-radius: 15px 15px 0px 0px !important;
background-color: #FE6D73 !important;
color: #FEF9EF !important;
}

Create an element with a click and remove it by a second click

Still learning so bear with me.
I am building a test project where I have a simple input that I show it on the same page as a list. (grocery or to do list project)
So when a user hits the ok button I create a new li inside a ul element. That goes ok.
I want to implement the following though: When the user clicks on the new element (li) I want to change the text decoration to line-though and show a trash icon where it will remove this li element by clicking on it.
I have managed to do that. The problem is that when the user clicks again on the new element (li) I get a second trash image.
I want help to succeed in this: when a user clicks on the element while it has text-decoration = line-through to hide or remove the trash icon and make text-decoration none again.
Here is a code pen for this project to check out. Just insert a new item on the list and then click twice on it: https://codepen.io/dourvas-ioannis/pen/MWVBjNZ
This is the function I am using when the user hits the add button to add a list item:
function addToList(){
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
newListItem.addEventListener('click', function(){
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i class="material-icons">delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem(){
this.parentNode.remove();
}
//select from DOM
let allItems = document.querySelector('#allItems');
let button = document.querySelector('#add-button');
let userInput = document.querySelector('#item');
let list = document.querySelector('#list');
let clear = document.querySelector('#clear-button');
//add event listener
button.addEventListener('click', addToList);
clear.addEventListener('click', clearAll);
//functions
function addToList() {
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
newListItem.addEventListener('click', function() {
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i class="material-icons">delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem() {
this.parentNode.remove();
}
function clearAll() {
list.innerHTML = "";
}
body {
font-size: 10px;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
background-color: antiquewhite;
}
#container {
width: 80%;
margin: auto;
padding-top: 10px;
background-color: rgb(200, 225, 225);
color: rgb(52, 48, 48);
border-radius: 10px;
}
p {
font-size: 20px;
text-align: center;
padding: 30px, 0px, 5px, 0px;
}
#formdiv {
text-align: center;
}
#item {
size: 100px;
}
#clear {
margin-top: 60px;
text-align: center;
}
li {
list-style-type: none;
font-size: 3.2em;
padding: 0.5em;
margin: 1em;
background-color: lightyellow;
border-radius: 5px;
border: 1px solid grey;
}
.trash-image {
float: right;
margin: -2px 3px 3px 3px;
vertical-align: middle;
height: 4px;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<body>
<br> <br> <br>
<div id='container'>
<p>My list</p>
<br>
<div id="formdiv">
<label for="item">add this.. </label><br>
<input type="text" name="item" id="item">
<button id="add-button"> add </button>
</div>
<div id="allItems">
<ul id="list">
</ul>
</div>
<div id="clear">
<button id="clear-button"> Clear List </button><br> <br> <br>
</div>
</div>
Here's a quick example implementation of the approach I mentioned in the comments. I've just hacked it together quickly, so there's a small difference for the bin.
I've used an img (without a src) instead of a 'character' from the
font. I've styled the img to be 16x16 for the same reason. It also
makes it visible instead of being 0x0 pixels. I also set the cursor.
"use strict";
window.addEventListener('load', onLoad, false);
function onLoad(evt) {
document.querySelector('button').addEventListener('click', onAddBtnClicked, false);
}
function onAddBtnClicked(evt) {
let userText = document.querySelector('input').value;
let newLi = document.createElement('li');
newLi.textContent = userText;
newLi.addEventListener('click', onIncompleteItemClicked, false);
document.querySelector('ul').appendChild(newLi);
}
function onIncompleteItemClicked(evt) {
let clickedLi = this;
clickedLi.classList.toggle('itemComplete');
let binImg = document.createElement('img');
binImg.addEventListener('click', onBinIconClicked, false);
clickedLi.appendChild(binImg);
clickedLi.removeEventListener('click', onIncompleteItemClicked, false);
clickedLi.addEventListener('click', onCompletedItemClicked, false);
}
function onCompletedItemClicked(evt) {
let clickedLi = this;
clickedLi.classList.toggle('itemComplete');
let binImg = clickedLi.querySelector('img');
clickedLi.removeChild(binImg);
clickedLi.removeEventListener('click', onCompletedItemClicked, false);
clickedLi.addEventListener('click', onIncompleteItemClicked, false);
}
function onBinIconClicked(evt) {
let clickedBin = this;
let containingLi = clickedBin.parentNode;
containingLi.remove();
}
.itemComplete {
text-decoration: line-through;
}
li>img {
cursor: pointer;
width: 16px;
height: 16px;
}
<input value='blah-blah'></input><button>Add</button>
<ul></ul>
Add a variable indicating that the icon has been already added.
Check if icon is added on click
If yes - skip
If not - set icon
//select from DOM
let allItems = document.querySelector('#allItems');
let button = document.querySelector('#add-button');
let userInput = document.querySelector('#item');
let list = document.querySelector('#list');
let clear = document.querySelector('#clear-button');
//add event listener
button.addEventListener('click', addToList);
clear.addEventListener('click', clearAll);
//functions
function addToList() {
let newListItem = document.createElement('li');
newListItem.textContent = userInput.value;
list.appendChild(newListItem);
userInput.value = "";
// declare boolean variable
let hasTrashIcon = false
newListItem.addEventListener('click', function() {
// if has thrash icon skip
if (hasTrashIcon) return
// set has trash icon
hasTrashIcon = true
this.style.textDecoration = 'line-through';
let itemButton = document.createElement('a');
itemButton.setAttribute('href', '#');
itemButton.classList.add('trash-image');
itemButton.innerHTML = '<i class="material-icons">delete</i><a/>';
itemButton.addEventListener("click", deleteOneItem);
this.appendChild(itemButton);
});
}
function deleteOneItem() {
this.parentNode.remove();
}
function clearAll() {
list.innerHTML = "";
}
body {
font-size: 10px;
font-family: Arial, Helvetica, sans-serif;
margin: 0;
background-color: antiquewhite;
}
#container {
width: 80%;
margin: auto;
padding-top: 10px;
background-color: rgb(200, 225, 225);
color: rgb(52, 48, 48);
border-radius: 10px;
}
p {
font-size: 20px;
text-align: center;
padding: 30px, 0px, 5px, 0px;
}
#formdiv {
text-align: center;
}
#item {
size: 100px;
}
#clear {
margin-top: 60px;
text-align: center;
}
li {
list-style-type: none;
font-size: 3.2em;
padding: 0.5em;
margin: 1em;
background-color: lightyellow;
border-radius: 5px;
border: 1px solid grey;
}
.trash-image {
float: right;
margin: -2px 3px 3px 3px;
vertical-align: middle;
height: 4px;
}
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<body>
<br> <br> <br>
<div id='container'>
<p>My list</p>
<br>
<div id="formdiv">
<label for="item">add this.. </label><br>
<input type="text" name="item" id="item">
<button id="add-button"> add </button>
</div>
<div id="allItems">
<ul id="list">
</ul>
</div>
<div id="clear">
<button id="clear-button"> Clear List </button><br> <br> <br>
</div>
</div>

How to operate checkbox with keydown property?

I want to tick the checkbox when enter pressed and output should be display in line tag similarly after pressing backspace checkbox should be unticked and element must remove from line.
but how can i do that? without using jquery.
for (i = 301; i < 359; i++) {
document.write("<input type='checkbox' value='" + i + "' onkeydown='absent(this)'>" + i + "<br>");
}
function absent(e) {
if (event.key == "Enter") {
e.checked = true;
document.getElementById("dis").innerHTML += " " + e.value;
}
if (e.key == "Backspace") {
e.checked = false;
var x = document.getElementById("dis").innerHTML;
var m = x.replace(e.value, "")
document.getElementById("dis").innerHTML = m;
}
}
li {
max-width: 800px;
word-wrap: break-word;
font-size: 27px;
margin-left: 200px;
color: blue;
margin-top: 100px;
}
h1 {
color: crimson;
font-weight: 1000px;
font-size: 60px;
margin-left: 500px;
;
}
<!DOCTYPE html>
<html>
<head>
<title>Checkbox Attandance</title>
</head>
<body style="background-color: blanchedalmond;">
<h1>Attendance</h1>
<li id="dis">Present Students<br></li><br>
</body>
</html>
Add || event.key == "Delete" inside your if brackets, and it will work
<!DOCTYPE html>
<html>
<head>
<title>Checkbox Attandance</title>
<style>
li {
max-width: 800px;
word-wrap: break-word;
font-size: 27px;
margin-left: 200px;
color: blue;
margin-top: 100px;
}
h1{
color: crimson;
font-weight: 1000px;
font-size: 60px;
margin-left: 500px;;
}
</style>
</head>
<body style="background-color: blanchedalmond;" >
<h1>Attendance</h1>
<li id="dis">Present Students<br></li><br>
<script>
for(i=301;i<359;i++){
document.write("<input type='checkbox' value='"+i+"' onkeydown='absent(this)'>"+i+"<br>");
}
function absent(e){
if(event.key=="Enter"){
e.checked=true;
document.getElementById("dis").innerHTML+=" "+e.value;
}
if(event.key === "Backspace" || event.key === "Delete"){
e.checked=false;
var x=document.getElementById("dis").innerHTML;
var m=x.replace(e.value,"")
document.getElementById("dis").innerHTML=m;
}
}
</script>
</body>
</html>
Here's a demo where you can navigate (using tab key) with focus over the available checkboxes created at initialization. Each one on hover will show the corresponding id with a tooltip.
When you press Enter it will tick the currently active checkbox and will add a new list item in the list, corresponding to the checkbox id selected. If you press del, it will untick the checkbox and remove the corresponding list item.
Since the action gets performed on the checkbox having focus, the remove feature will work only on the last one added. If requested it could be easily get more powerful but the order of selected options won't be guaranteed anymore.
The keyboard will control focus making you rotate through the checkboxes.
const target = document.getElementById('target');
for(i=301;i<359;i++){
const o = document.createElement('input');
o.setAttribute('type','checkbox');
o.setAttribute('title',`id:${i}`);
o.value = i;
o.addEventListener('keydown', absent);
o.addEventListener('click', (event)=>{event.preventDefault();});
target.append(o);
}
document.querySelector('#target input:first-child').focus();
function absent(e){
if(!e.target.checked && e.key=="Enter"){
const list = document.querySelector("#students ol.list");
const item = document.createElement('li');
item.innerText = e.target.value;
list.append(item);
e.target.checked = true;
}
if(e.target.checked && e.key=="Backspace"){
const lastItem = document.querySelector("#students ol.list li:last-child");
if(lastItem.innerText != e.target.value)
return;
lastItem.remove();
e.target.checked = false;
}
if(e.key=="Tab" && e.target.nextSibling == null)
document.querySelector('#target input:first-child').focus();
}
body {
background-color: blanchedalmond;
}
h1{
color: crimson;
font-weight: 700;
font-size: 60px;
text-align: center;
}
h2 {
color: blue;
}
#students{
margin: 0 2rem 1rem 2rem;
padding: 0 20px;
border: dashed 2px gray;
}
.list{
}
#target{
margin: 0 2rem;
padding: 20px;
border: dashed 2px gray;
}
input[type=checkbox]{
cursor: pointer;
}
<body>
<h1>Attendance</h1>
<div id="students" tabindex="-1">
<h2>Present Students</h2>
<ol class="list">
</ol>
</div>
<div id="target">
</div>
</body>

Javascript Blur background when div is block?

I'm having a problem with bluring the background when my menu is open. I tried writing something on my own but it's not working.
function backgroundBlur() {
var menuBox = document.getElementById("mobile-menu");
var blur = document.getElementById("body");
if (menuBox.style.dsiplay = "block") {
blur.style.filter = "blur(3px)";
}
}
I think the problem can be caused by three reasons:
Typo noted by #RyanWalls
The backgroundBlur() method is not called
The display property of the menuBox is not block
I made a run to simulate this event:
let button = document.getElementById('setBlur');
let control = false;
function backgroundBlur(control) {
var menuBox = document.getElementById("mobile-menu");
var blur = document.getElementById("body");
if (menuBox.style.display === "block")
{
if(!control)
{
blur.style.filter = "blur(3px)";
button.innerHTML = 'Remove Blur';
}
else
{
blur.style.filter = "blur(0px)";
button.innerHTML = 'Add Blur';
}
}
}
button.addEventListener('click', function() {
backgroundBlur(control);
control = !control;
});
*{
margin: 0;
}
#body{
background-color: black;
}
button{
margin-top: 25px;
background-color: #4CAF50;
border: none;
color: white;
padding: 15px 32px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 16px;
width: 100%;
}
.vertical-menu {
width: 200px;
}
.vertical-menu a {
background-color: #eee;
color: black;
display: block;
padding: 12px;
text-decoration: none;
}
.vertical-menu a:hover {
background-color: #ccc;
}
.vertical-menu a.active {
background-color: #04AA6D;
color: white;
}
<div id="body">
<div id="mobile-menu" style="display: block;">
<div class="vertical-menu">
Home
Link 1
</div>
</div>
</div>
<button id="setBlur">Add Blur</button>

Best way to toggle between the state of show() and hide() in jQuery

I have the following code which switches between the states of hide() and show() of show prices button.I am aware about .toggle() in jQuery.But I couldn't find a workaround of it in this instance.
When I click the button the <p></p> element is appended to .msg class in the div and when I click it once again it hides it state by removing the <p></p> element from the DOM (which is in the else block).
I have managed to come up with a solution which works well using If..else, yet it doesn't feel right or the best way to do it. I find this solution naive and want to know what I can do to further optimize this code.
Following is the code:
(function() {
//$('.not-interested').hide();
$('.msg').hide();
var showPrice = function(e) {
e.stopPropagation();
var vacation = $(this).closest('.vacation');
var button = vacation.find('button');
if ((!vacation.hasClass('present'))) {
var price = +vacation.data('price');
var vacation_place = vacation.find('h3').text();
var msg = $("<p style='text-align:center;line-height:24px;font-size:13px;'>Price for " + vacation_place + " is: " + (3 * price) + " </p>");
vacation.find('.msg').prepend(msg).show();
vacation.addClass('present');
} else if ((e.type == 'click' && e.toElement.localName == 'button') || e.type == 'showAll') {
//console.log(e.toElement.localName);
//vacation.on('click','button')){
//console.log(e.toElement);
//console.log(vacation.on('click','button').context);
//console.log(button);
vacation.removeClass('present');
vacation.find('.msg').hide().find('p').remove();
}
};
var removePrice = function(e) {
e.stopPropagation();
var vacation = $(this).closest('.vacation');
vacation.find('div.msg').hide();
//vacation.on('click.price','button',showPrice);
};
$('.vacation').on('click.show', 'button', showPrice);
$('.vacation').on('showAll.price', showPrice); // creating a custom event
$('.show-all-price').on('click', function(e) {
e.preventDefault();
$('.vacation').trigger('showAll.price'); // firing a custom event on click of an anchor
});
})();
body,
ul {
font-size: 100%;
margin: 0;
padding: 0;
font-family: "sans-serif";
color: #fff;
}
.show-all {
width: 100px;
background: #597C80;
margin-top: 25px;
margin-left: 25px;
border: 1px solid #2A3F41;
}
.show-all a {
display: block;
text-decoration: none;
color: #333;
text-align: center;
padding: 10px;
font-size: 13px;
}
ul {
list-style: none;
margin-top: 20px;
margin-left: 20px;
float: left;
}
li {
float: left;
display: block;
padding: 10px;
background: #2A3F41;
margin-right: 10px;
padding-bottom: 25px;
}
li h3 {
text-align: center;
}
li > div {
width: 80%;
margin: 0 auto;
}
li button {
width: 100%;
background: #377C37;
color: #333;
border: none;
outline: 0;
cursor: pointer;
padding: 5px 9px;
}
button:active {
position: relative;
top: 2px;
/* padding: 8px 13px 6px;*/
}
li a {
display: block;
margin-top: 10px;
text-align: center;
text-decoration: none;
color: #597C80;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<body>
<div class="show-all">
Show all
</div>
<ul id="vacation-list">
<li class="vacation" data-price="395">
<h3>Hawaiian Vacation</h3>
<div>
<button>Show all prices</button>
<div class="msg">
Not Interested
</div>
</div>
</li>
<li class="vacation" data-price="315">
<h3>American Vacation</h3>
<div>
<button>Show all prices</button>
<div class="msg">
Not Interested
</div>
</div>
</li>
<li class="vacation" data-price="420">
<h3>French Vacation</h3>
<div>
<button>Show all prices</button>
<div class="msg">
Not Interested
</div>
</div>
</li>
</ul>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script src="js/app.js"></script>
</body>
I've also tried using .on() and .off() with name spacing but couldn't figured how to do it appropriately.
Here's the code with .on() and .off() switching:
(function(){
//$('.not-interested').hide();
$('.msg').hide();
var showPrice = function(e){
e.stopPropagation();
var vacation = $(this).closest('.vacation');
var button = vacation.find('button');
var price = +vacation.data('price');
var vacation_place = vacation.find('h3').text();
var msg = $("<p style='text-align:center;line-height:24px;font-size:13px;'>Price for " + vacation_place + " is: " + (3 * price) + " </p>");
vacation.find('.msg').prepend(msg).show();
vacation.on('click.remove','button',removePrice);
};
var removePrice = function(e){
e.stopPropagation();
var vacation = $(this).closest('.vacation');
vacation.find('div.msg').hide().find('p').remove();
vacation.on('click.price','button',showPrice);
};
$('.vacation').on('click.price','button',showPrice);
$('.vacation').on('showAll.price',showPrice); // creating a custom event
$('.show-all-price').on('click',function(e){
e.preventDefault();
$('.vacation').trigger('showAll.price'); // firing a custom event on click of an anchor
});
})();
Note:,e.toElement.localName == 'button' doesn't work in IE.

Categories