I have this program that can make closables dynamically. When the user clicks on a created closable an input box and a button are displayed in the content of the closable. The user can then input text into the textbox and then press the button. Then the users text will be displayed in the selected closable content.
Everything works, fine, except for when I try to display the users input in the selected closables content.
Here's what's happening:
When the user inputs something in the text box it's append to the closables content:
The text is only displayed in the closable content after I close the selected closable:
Why isn't the users input being displayed in the selected closable after I click the add task button?
Here is my full code:
var currentClosable;
var currentContent;
function selectedColl(){
document.getElementById("inputTaskDiv").style.display = "block";
currentClosable = event.target;
currentContent = currentClosable.nextElementSibling;
var inputTaskDiv = document.getElementById("inputTaskDiv");
currentContent.append(inputTaskDiv);
}
var taskCounter = 0;
function addTask() {
var text = document.getElementById("taskInput").value;
// create a new div element and give it a unique id
var newTask = $("<input type='checkbox'><label>"+ text + "</label><br>");
newTask.id = 'temp' + taskCounter;
taskCounter++
// and give it some content
var newContent = document.createTextNode(text);
$(currentContent).append(newTask); //Why isn't it being displayed??
console.log("appended");
}
var elementCounter = 0;
var elementCounterContent = 0;
var text;
function addElement() {
text = document.getElementById("input").value;
// create a new div element and give it a unique id
var newDiv = $("<button class='collapsible' onclick='selectedColl()'></button>").text(text);
var newContentOfDiv = $("<div class='content'></div>");
newDiv.id = 'temp' + elementCounter;
newContentOfDiv.id = 'content' + elementCounterContent;
newDiv.classList = "div";
elementCounter++
elementCounterContent++
// and give it some content
var newContent = document.createTextNode(text);
// add the newly created element and its content into the DOM
document.getElementById("input").value = " ";
$("body").append(newDiv, newContentOfDiv);
newDiv.click(function() {
this.classList.toggle("active");
content = this.nextElementSibling;
if (content.style.maxHeight){
content.style.maxHeight = null;
} else {
content.style.maxHeight = content.scrollHeight + "px";
}
});
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.active, .collapsible:hover {
background-color: #555;
}
.collapsible:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "\2212";
}
.content {
padding: 0 18px;
max-height: 0;
overflow: hidden;
transition: max-height 0.2s ease-out;
background-color: #f1f1f1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<input id="input" type="text"><button onclick="addElement()">Add</button>
<div id="inputTaskDiv" style="display:none">
<input id="taskInput" type="text"><button onclick="addTask()">Add Task</button>
</div>
The changes made are in CSS and JS.
In CSS you can see which lines are commented on style ".content": max-height and overflow
The change in JS is:
I changed content.style.maxHeight with this content.style.display
this.classList.toggle("active");
content = this.nextElementSibling;
if (content.style.display === 'block') {
content.style.display = 'none';
} else {
content.style.display = 'block';
}
Example:
var currentClosable;
var currentContent;
function selectedColl() {
document.getElementById("inputTaskDiv").style.display = "block";
currentClosable = event.target;
currentContent = currentClosable.nextElementSibling;
var inputTaskDiv = document.getElementById("inputTaskDiv");
currentContent.append(inputTaskDiv);
}
var taskCounter = 0;
function addTask() {
var text = document.getElementById("taskInput").value;
// create a new div element and give it a unique id
var newTask = $("<input type='checkbox'><label>" + text + "</label><br>");
newTask.id = 'temp' + taskCounter;
taskCounter++
// and give it some content
var newContent = document.createTextNode(text);
$(currentContent).append(newTask); //Why isn't it being displayed??
console.log("appended");
}
var elementCounter = 0;
var elementCounterContent = 0;
var text;
function addElement() {
text = document.getElementById("input").value;
// create a new div element and give it a unique id
var newDiv = $("<button class='collapsible' onclick='selectedColl()'></button>").text(text);
var newContentOfDiv = $("<div class='content'></div>");
newDiv.id = 'temp' + elementCounter;
newContentOfDiv.id = 'content' + elementCounterContent;
newDiv.classList = "div";
elementCounter++
elementCounterContent++
// and give it some content
var newContent = document.createTextNode(text);
// add the newly created element and its content into the DOM
document.getElementById("input").value = " ";
$("body").append(newDiv, newContentOfDiv);
newDiv.click(function () {
this.classList.toggle("active");
content = this.nextElementSibling;
if (content.style.display === 'block') {
content.style.display = 'none';
} else {
content.style.display = 'block';
}
});
}
.collapsible {
background-color: #777;
color: white;
cursor: pointer;
padding: 18px;
width: 100%;
border: none;
text-align: left;
outline: none;
font-size: 15px;
}
.active,
.collapsible:hover {
background-color: #555;
}
.collapsible:after {
content: '\002B';
color: white;
font-weight: bold;
float: right;
margin-left: 5px;
}
.active:after {
content: "\2212";
}
.content {
padding: 0 18px;
/* max-height: 0; */
/* overflow: hidden; */
transition: max-height 0.2s ease-out;
background-color: #f1f1f1;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<input id="input" type="text"><button onclick="addElement()">Add</button>
<div id="inputTaskDiv" style="display:none">
<input id="taskInput" type="text"><button onclick="addTask()">Add Task</button>
</div>
Related
I'm creating a tab menu like this:
function clear_selected() //sets all columns color black
{
var parent = document.querySelector("#container")
var items = document.querySelectorAll(".item")
var n = items.length;
for (var i = 0; i < n; i++)
items[i].style.backgroundColor = "";
}
function plus(itself) //adds another column
{
var parent = itself.parentElement;
var n = parent.childElementCount;
clear_selected();
var n = parent.querySelectorAll(".item").length;
var page = document.createElement("button");
page.className = "item";
page.style.backgroundColor = "blue";
page.textContent = "column"
page.onclick = function() {
clear_selected();
this.style.backgroundColor = "blue";
};
var temp = document.createElement("span");
temp.className = "del"
temp.innerHTML = "×"
temp.onclick = function() { //it's suppose to remove a column and color default as blue
document.querySelector("#main_item").style.backgroundColor = "blue" //THIS LINE ISN'T WORKING
this.parentElement.remove();
};
page.appendChild(temp);
parent.insertBefore(page, parent.childNodes[n]);
}
function see(el) {
clear_selected();
el.style.backgroundColor = "blue";
}
#container {
display: flex;
width: 100%;
height: 50px;
text-align: center;
background-color: yellow;
}
.item {
background-color: black;
color: white;
border: none;
outline: none;
cursor: pointer;
margin: 0.1rem;
padding: 0.1rem;
max-width: 100%;
}
.del {
background-color: red;
display: inline-block;
cursor: pointer;
border-radius: 50%;
width: 0.7rem;
margin-left: 2rem;
}
<div id="container">
<button class="item" id="main_item" style="background-color:blue;" onclick="see(this)">default column </button>
<button class="item" onclick="plus(this)">+</button>
</div>
but when I press the 'x' to remove a column, I want the default column to color blue, but the line of code which is suppose to achieve that isn't working
document.querySelector("#main_item").style.backgroundColor = "blue"
Before pressing 'x':
After pressing 'x' on the last column:
What it SHOULD look like:
I've losing sleep over this, can someone PLEASE tell me why isn't it working?
When you click on the "X", both of your onclick handlers are getting called, including the one that runs clear_selected, which sets the background color to "".
You can fix this by using stopPropagation on the event passed into the onclick function for the "x". That will stop the click event from going up the chain to the parent element of the "x".
temp.onclick = function(e) {
document.querySelector("#main_item").style.backgroundColor = "blue"
this.parentElement.remove();
e.stopPropagation();
};
I am creating a list of inputs and storing the values in an array when the add button is clicked.
All works well, but I have introduced the possibility to remove items in the list effectively by hiding the 'deleted' elements from the DOM.
Now I need to remove the hidden elements from the array.
To keep things simple, I thought to store in the array only the visible elements (instead of removing the hidden element from the array).
To do so I am looking at adapting the 'how to count visible elements' code in: (https://stackoverflow.com/questions/37634146/javascript-count-visible-elements but it doesn't work and a list of '[object HTMLLIElement]' is displayed when displaying the array on an alert.
This is my code:
// Create a "close" button and append it to each list item
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
myNodelist[i].appendChild(span);
}
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function () {
var div = this.parentElement;
div.style.display = "none";
};
}
// Create a new list item when clicking on the "Add" button
function addNumber() {
var li = document.createElement("li");
var inputValue = document.getElementById("number").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === "") {
alert("Add at least one phone number!");
} else {
document.getElementById("myUL").appendChild(li);
}
// remove elements from form after added to list
document.getElementById("number").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
// without this, the element is not deleted
for (i = 0; i < close.length; i++) {
close[i].onclick = function () {
var div = this.parentElement;
div.style.display = "none";
};
}
}
// store values after submit
function submitRecords() {
divs = document.getElementsByTagName("li");
var divsArray = [].slice.call(divs);
var displayShow = divsArray.filter(function (el) {
return getComputedStyle(el).display !== "none";
});
alert(displayShow);
}
#myUL {
/* text-align: center; */
width: 40%;
float: left;
}
/* Style the list items */
ul li {
position: relative;
padding: 12px 8px 12px 40px;
list-style-type: none;
background: #eee;
border-top: lightgrey 1px solid;
border-bottom: lightgrey 1px solid;
font-size: 20px;
transition: 0.2s;
/* this allows for the borders of 2 adiacent items to overlap */
margin-top: -1px;
}
/* Style the close button */
.close {
cursor: pointer;
position: absolute;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.close:hover {
background-color: red;
color: white;
}
.addBtn {
background: #eee;
border: black 1px solid;
padding: 4px;
color: black;
cursor: pointer;
}
.addBtn:hover {
background-color: #ddd;
}
<div class="inputForm">
<form>
<input
type="text"
id="number"
placeholder="Enter number"
onkeypress="return isNumberKey(event)"
/>
<span onclick="addNumber()" class="addBtn">Add</span>
<br /><br />
<input
onclick="submitRecords()"
id="send"
type="submit"
value="SEND"
/>
</form>
</div>
<!-- this is needed to generate the list of numbers -->
<ul id="myUL"></ul>
What am I doing wrong?
There is a .value in function addNumber which seems to be spurious, on this line:
divs = document.getElementsByTagName("li").value;
when this is removed the console.log shows li elements.
The code for adding onclick functionality to the span elements looks as though it is trying to step through a (non-existent?) array, and it is doing this each time a number is added. Removing this code and instead setting up the onclick as a span element is created seems to work.
Here is the altered code:
<!-- Added HTML for testing -->
<input id="number" value=999 onchange="addNumber();"/>
<button onclick="submitRecords();">submit records</button>
<ul id="myUL"></ul>
<script>
function submitRecords() {
var divs = (document.getElementsByTagName("li"));// REMOVED .value
var divsArray = [].slice.call(divs);
var displayShow = divsArray.filter(function (el) {
return getComputedStyle(el).display !== "none";
});
var numbers=[];
var keys = [];
for (var i=0;i<displayShow.length;i++) {
numbers[i]=displayShow[i].childNodes[0].textContent;
console.log(numbers[i]);
}
}
function addNumber() {
var li = document.createElement("li");
var inputValue = document.getElementById("number").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === "") {
alert("Add at least one phone number!");
} else {
document.getElementById("myUL").appendChild(li);
}
// close button
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.onclick = function () { //ADDED so that an li element's span child gets this onclick function as soon as it is created
var div = this.parentElement;
div.style.display = "none";
};
span.appendChild(txt);
li.appendChild(span);
/* REMOVED // hide element
for (i = 0; i < close.length; i++) {
close[i].onclick = function () {
var div = this.parentElement;
div.style.display = "none";
};
*/
}
</script>
Your idea to get only visible items is just fine, and you can do it like this:
function submitRecords() {
const displayShow = [];
//declare array
[...document.querySelectorAll('#myUL li:not([style="display: none;"])')].forEach(element => {
//get all li items and for each of them:
displayShow.push(element.textContent.slice(0, -1))
//push its text Content into array, and also just remove last x (button) character
});
console.clear();
console.log(displayShow);
}
Ps: li element does not have .value, you can red content with: textContent
Just remove onsubmit event from form, and add back onkeypress="return isNumberKey(event)" to input i made modifications just for demonstration:
EXAMPLE:
// Create a "close" button and append it to each list item
var myNodelist = document.getElementsByTagName("LI");
var i;
for (i = 0; i < myNodelist.length; i++) {
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
myNodelist[i].appendChild(span);
}
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function () {
var div = this.parentElement;
div.style.display = "none";
};
}
// Create a new list item when clicking on the "Add" button
function addNumber() {
var li = document.createElement("li");
var inputValue = document.getElementById("number").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === "") {
alert("Add at least one phone number!");
} else {
document.getElementById("myUL").appendChild(li);
}
// remove elements from form after added to list
document.getElementById("number").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("\u00D7");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
// without this, the element is not deleted
for (i = 0; i < close.length; i++) {
close[i].onclick = function () {
var div = this.parentElement;
div.style.display = "none";
};
}
}
// store values after submit
function submitRecords() {
const displayShow = [];
[...document.querySelectorAll('#myUL li:not([style="display: none;"])')].forEach(element => {
displayShow.push(element.textContent.slice(0, -1))
});
console.clear();
console.log(displayShow);
}
#myUL {
/* text-align: center; */
width: 40%;
float: left;
}
/* Style the list items */
ul li {
position: relative;
padding: 12px 8px 12px 40px;
list-style-type: none;
background: #eee;
border-top: lightgrey 1px solid;
border-bottom: lightgrey 1px solid;
font-size: 20px;
transition: 0.2s;
/* this allows for the borders of 2 adiacent items to overlap */
margin-top: -1px;
}
/* Style the close button */
.close {
cursor: pointer;
position: absolute;
right: 0;
top: 0;
padding: 12px 16px 12px 16px;
}
.close:hover {
background-color: red;
color: white;
}
.addBtn {
background: #eee;
border: black 1px solid;
padding: 4px;
color: black;
cursor: pointer;
}
.addBtn:hover {
background-color: #ddd;
}
<div class="inputForm">
<form onsubmit="event.preventDefault();">
<input
type="text"
id="number"
placeholder="Enter number"
/>
<span onclick="addNumber()" class="addBtn">Add</span>
<br /><br />
<input
onclick="submitRecords()"
id="send"
type="submit"
value="SEND"
/>
</form>
</div>
<!-- this is needed to generate the list of numbers -->
<ul id="myUL"></ul>
I made only small modification to your code to get the desired values from the <li> element.
function submitRecords() {
divs = document.getElementsByTagName("li");
var divsArray = [];
var displayShow = Object.values(divs).filter(function (el) {
return getComputedStyle(el).display !== "none";
});
displayShow.forEach(function(item){let ind=item.innerHTML.indexOf('<span');
divsArray.push(item.innerHTML.substr(0,ind))});
alert(divsArray);
}
I am trying to create a text font colour drop down button where it gives you an option of multiple colour to pick from and then it would change the colour of the text. I am not sure on how to approach this and I am not meant to use jQuery. Any help would be appreciated. In the code below it shows other examples of other button where they change the user input entered into the contenteditable. I want the font colour button to do the same but just change the colour of the text
const TAB_KEY = 9;
const ENTER_KEY = 13;
const SHIFT_KEY = 16
const editor = document.querySelector('.editor');
editor.appendChild(document.createElement('li'));
editor.addEventListener('keydown', (e) => {
let code = e.keyCode || e.which;
if (code == TAB_KEY) {
e.preventDefault();
let parent = e.target;
let ul = document.createElement('ul');
let li = document.createElement('li');
ul.appendChild(li);
parent.appendChild(ul);
moveCursorToEnd(li);
} else if (code == ENTER_KEY) {
e.preventDefault();
let parent = e.target;
let li = document.createElement('li');
parent.appendChild(li);
moveCursorToEnd(li);
} else if (code == TAB_KEY * TAB_KEY){
e.preventDefault();
let parent = e.target;
let ol = document.createElement('ol');
let li = document.createElement('li');
ol.appendChild(li);
parent.appendChild(ol);
moveCursorToEnd(li);
}
});
function moveCursorToEnd(el) {
el.focus();
document.execCommand('selectAll', false, null);
document.getSelection().collapseToEnd();
}
/*editor.addEventListener('click', (x) => {
x = document.getElementById("b");
if(x.style.fontWeight == "bolder"){
x.style.fontWeight = "normal";
} else {
x.style.fontWeight = "bolder";
}
});*/
function bold(){
if(document.execCommand("bold")){
document.execCommand("normal");
}else{
document.execCommand("bold");
}
}
/*function underline(){
let x = document.getElementById("text");
if(x.style.textDecoration == "underline"){
x.style.textDecoration = "none";
}else{
x.style.textDecoration = "underline";
}
}*/
function underline(){
if(document.execCommand("underline")){
document.execCommand("none");
}else{
document.execCommand("underline");
}
}
/*Turns the font of the text to Italic*/
function italic(){
if(document.execCommand("italic")){
document.execCommand("normal");
}else{
document.execCommand("italic");
}
}
function highlighSelectedText(){
let sel = window.getSelection().getRangeAt(0);
let selText = sel.extractContents();
let span = document.createElement("span");
span.style.backgroundColor = "yellow";
span.appendChild(selText);
sel.insertNode(span);
}
/*function printPage(){
let printButton = document.getElementById("ul");
printButton.style.visibility = 'hidden';
window.print();
printButton.style.visibility = 'visible';
}*/
body{
margin-top:1em;
margin-bottom: 10em;
margin-right: 1em;
margin-left: 1em;
border: solid;
border-color: #0033cc;
background-color: #f6f6f6;
}
div button{
padding: 1em 2em;
color: white;
background-color: #0000cc;
}
div input{
padding: 1em 2em;
color: white;
background-color: #0000cc;
}
div{
list-style-type:square;
list-style-position: inside;
margin-left: 0.25em;
margin-bottom: 5em;
}
section {
padding: 1em 2em;
color: white;
background-color: #0000cc;
}
.editor {
font-weight: normal;
}
div contenteditable{
margin-bottom: 10em;
}
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<head>
<title>Outliner</title>
<link href="style.css" rel="stylesheet" title="Style">
<div>
<button id="b" onclick="bold()"> B </button>
<button onclick="underline()"> U </button>
<button onclick="italic()"> I </button>
<input type="button" onclick="highlighSelectedText()" value="Highlight"/>
<div id="text" class="editor" contenteditable="true" draggable="true"></div>
</div>
<section>
<input id="saveAs"></input>
<button onclick="saveTextFile()">Download</button>
<input type="file" id="load"/>
<button onclick="loadFile()">Load</button>
</section>
<section>
<button class="btn btn-primary" onclick="saveChanges()">Save Text</button>
<button class="btn btn-warning" onclick="clearStorage()">Reset</button>
</section>
</head>
<script type= "text/javascript" src='setting.js'></script>
</body>
First off we will use a CSS variable. Lets declare a value at :root
:root {
--font-color: #000;
}
Now we will use that value to style the font color of our P tags.
p {
color: var(--font-color);
}
Now when somebody clicks one of the color names, we want to change the value of --font-color. (Notice we are using the data- attribute model to store the color we want to change too).
document.documentElement.style.setProperty('--font-color', target.dataset.color);
And presto we can now change color easily. This works for other values also.
Here is a great article
document.addEventListener('click', ({ target }) => {
if(target.matches('p')) {
document.documentElement.style.setProperty('--font-color', target.dataset.color);
}
});
:root {
--font-color: #000;
}
p {
width: 30%;
border: 2px solid #00000030;
border-radius: 7px;
margin: 0.25rem;
padding: 0.25rem;
color: var(--font-color);
}
<h2>Click a color</h2>
<p data-color="#f00">Red</p>
<p data-color="#0f0">Green</p>
<p data-color="#00f">Blue</p>
<p data-color="#000">Reset</p>
You can manipulate the style variable:
<div id="text">
Choose a color
</div>
<input id="color" type="color">
<button onclick="document.getElementById('text').style.color = document.getElementById('color').value;">Change Color</button>
I am currently working to create a custom alert box for any errors and below is the code I am using, the alert box is appearing fine but it's not auto-closing after 600 milliseconds, its only closed after the manual click of the close button. what I am doing wrong here and how to auto-disappear the alert box
I moved the setTimeout outside the click event and set the div value:
function displayError(errorMessage) {
var messageObject = "<div class='alert' id='alertbox'><span class='closebtn' id='closebtn'>×</span><strong><font color='#f44336;'>Error!</font></strong>"+errorMessage+"</div>"
document.getElementById("divMessageContainer").innerHTML += messageObject;
var close = document.getElementsByClassName("closebtn");
var i;
for (i = 0; i < close.length; i++) {
var div = close[i].parentElement;
setTimeout(function(){div.style.display = "none"; }, 600);
close[i].onclick = function(){
div.style.opacity = "0";
}
}
}
div#alertbox{padding: 10px;bottom: 40px;left: 5px; max-width: 800px; margin-left: auto;margin-right: auto;z-index: 99; max-width: 700px; color: #000;background-color: #EEE;border-radius: 10px; padding-right: 5px; padding-left: 10px;}
span#closebtn {margin-left: 15px;color: black;font-weight: bold;float: right;font-size: 22px;line-height: 20px; cursor: pointer; transition: 0.3s;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<html>
<body>
<div id="divMessageContainer"></div>
<button onclick="displayError()">button</button>
</body>
</html>
I have followed the below steps and fixed the issue reported here, The below approach allowed me to show multiple alert box at the same time and auto close them based on the message number instead of close all the alert box at the same time
<!DOCTYPE html>
<html>
<style>
div.alertbox{padding: 10px;bottom: 40px;left: 5px; max-width: 800px; margin-left: auto;margin-right: auto;z-index: 99; max-width: 700px; color: #000;background-color: #EEE;border-radius: 10px; padding-right: 5px; padding-left: 10px;}
span#closebtn {margin-left: 15px;color: black;font-weight: bold;float: right;font-size: 22px;line-height: 20px; cursor: pointer; transition: 0.3s;}
</style>
<body>
<div id="divMessageContainer"></div>
<button onclick="displayError()">button</button>
</body>
<script>
var messageCount = 0;
var messageTimeout = 3000;
function displayError(errorMessage) {
var messageObject = "<div class='alertbox' id='alertbox"+messageCount+"'><span class='closebtn' id='closebtn'>×</span><strong><font color='#f44336;'>Error!</font></strong>"+errorMessage+"</div>"
document.getElementById("divMessageContainer").innerHTML += messageObject;
var messageID = messageCount;
setTimeout(function(){removeElement("alertbox" + messageID); }, messageTimeout);
closeAlertbox();
}
function removeElement(id) {
if (document.getElementById(id)) {
return (elem=document.getElementById(id)).parentNode.removeChild(elem);
}
}
function closeAlertbox() {
var close = document.getElementsByClassName("closebtn");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function(){
var div = this.parentElement;
div.style.opacity = "0";
setTimeout(function()
{ div.style.display = "none";
}, 10);
}
}
}
</script>
</html>
I would recommend using remove() to remove the alertbox, so there won't be any closebuttons left and the for-loop can be removed.
Maybe this would be a possible solution:
function displayError(errorMessage) {
var messageObject = "<div id='moo' class='alert alert-danger alert-dismissible' role='alert' auto-close='2000'><div class='alert' id='alertbox'><span class='closebtn' id='closebtn'>×</span><strong><font color='#f44336;'>Error!</font></strong>"+errorMessage+"</div>";
var container = document.getElementById("divMessageContainer");
container.innerHTML += messageObject;
var box = document.getElementById("alertbox");
var close = document.querySelector(".closebtn");
close.onclick = function(){
box.remove();
};
setTimeout(function(){
box.style.opacity = 0;
setTimeout(function() {
box.remove();
}, 1000);
}, 2000);
}
div#alertbox{padding: 10px;bottom: 40px;left: 5px; max-width: 800px; margin-left: auto;margin-right: auto;z-index: 99; max-width: 700px; color: #000;background-color: #EEE;border-radius: 10px; padding-right: 5px; padding-left: 10px; -webkit-transition: opacity 1s linear;}
span#closebtn {margin-left: 15px;color: black;font-weight: bold;float: right;font-size: 22px;line-height: 20px; cursor: pointer; transition: 0.3s;}
<div id="divMessageContainer"></div>
<button onclick="displayError()">button</button>
I also added a transition to opacity, so if the user doesn't manually close the alertbox, it will fade (in this case after 2 seconds, but you can play with that time).
function displayError(errorMessage) {
var messageObject = "<div id='moo' class='alert alert-danger alert-dismissible' role='alert' auto-close='2000'><div class='alert' id='alertbox'><span class='closebtn' id='closebtn'>×</span><strong><font color='#f44336;'>Error!</font></strong>"+errorMessage+"</div>"
document.getElementById("divMessageContainer").innerHTML += messageObject;
var close = document.getElementsByClassName("closebtn");
var i, index;
for (i = 0; i < close.length; i++) {
setTimeout(function(){
close[index].parentElement.style.display = "none";
index++;
}, 600);
close[i].onclick = function(){
var div = this.parentElement;
div.style.display = "none";
}
}
}
Try this one. Take care about loop when using async.
I need to make a Javascript To Do list (checklist), which I have already completed, but I cannot figure out how to make an edit and delete button also appear with each of the items the are entered. Here is what I have so far
<!doctype html>
<html>
<head>
<title>To Do List</title>
<link rel="stylesheet" type="text/css" href="ToDoList.css">
</head>
<body>
<h1> To Do List</h1>
<div id = "listBox">
<input type="text" id="inItemText"><button id = "btnAdd">Add</button>
</div>
<div class="tasks-parent">
<h4>Tasks:</h4>
<ul id = "todolist">
</ul>
</div>
<script src ="ToDoList.js"></script>
</body>
</html>
#btnAdd {
text-transform: uppercase;
background: #22B473;
border: none;
border-radius: 3px;
font-weight: bold;
color: #FFF;
padding: 3px 10px;
cursor: pointer;
width: auto;
}
.tasks-parent {
border: 2px solid #777;
margin-top: 5px;
width: 17%;
}
html {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
ul {
list-style: none;
padding: 0;
margin: 0;
width: 400px;
}
li {
padding: 5px 10px;
color: #000;
}
li span {
padding-left: 17px;
}
function updateItemStatus() {
var cbId = this.id.replace("cb_", "");
var itemText = document.getElementById("item_" + cbId);
if (this.checked) {
itemText.style.textDecoration = "line-through";
} else {
itemText.style.textDecoration = "none";
}
}
function addNewItem(list, itemText) {
var date = new Date();
var id = "" + date.getMinutes(); + date.getSeconds() +
date.getMilliseconds() + "";
var listItem = document.createElement("li");
listItem.id = "li_" + id;
var checkBox = document.createElement("input");
checkBox.type = "checkbox";
checkBox.id = "cb_" + id;
checkBox.onclick = updateItemStatus;
var span = document.createElement("span");
span.id = "item_" + id;
span.innerText = itemText;
listItem.appendChild(checkBox);
listItem.appendChild(span);
list.appendChild(listItem);
}
var inItemText = document.getElementById("inItemText");
inItemText.focus();
var btnNew = document.getElementById("btnAdd");
btnNew.onclick = function() {
var inItemText = document.getElementById("inItemText");
var itemText = inItemText.value;
if (!itemText || itemText === "" || itemText === " ") {
return false;
}
addNewItem(document.getElementById("todolist"), itemText);
};
inItemText.onkeyup = function(event) {
if (event.which == 13) {
var itemText = inItemText.value;
if (!itemText || itemText === "" || itemText === " ") {
return false;
}
addNewItem(document.getElementById("todolist"), itemText);
inItemText.focus();
inItemText.select();
}
};
You need to create additional two elements(one for edit and one for delete) and append them like you did with other elements:
function updateItemStatus() {
var cbId = this.id.replace("cb_", "");
var itemText = document.getElementById("item_" + cbId);
if (this.checked) {
itemText.style.textDecoration = "line-through";
} else {
itemText.style.textDecoration = "none";
}
}
function addNewItem(list, itemText) {
var date = new Date();
var id = "" + date.getMinutes(); + date.getSeconds() +
date.getMilliseconds() + "";
var listItem = document.createElement("li");
listItem.id = "li_" + id;
var checkBox = document.createElement("input");
checkBox.type = "checkbox";
checkBox.id = "cb_" + id;
checkBox.onclick = updateItemStatus;
var span = document.createElement("span");
span.id = "item_" + id;
span.innerText = itemText;
//create edit
var edit = document.createElement("a");
edit.href = "#";
edit.innerText = "edit";
//create delete
var deleteBtn = document.createElement("a");
deleteBtn.href = "#";
deleteBtn.innerText = "delete";
listItem.appendChild(checkBox);
listItem.appendChild(span);
//and append them in li
listItem.appendChild(edit);
listItem.appendChild(deleteBtn);
list.appendChild(listItem);
}
var inItemText = document.getElementById("inItemText");
inItemText.focus();
var btnNew = document.getElementById("btnAdd");
btnNew.onclick = function() {
var inItemText = document.getElementById("inItemText");
var itemText = inItemText.value;
if (!itemText || itemText === "" || itemText === " ") {
return false;
}
addNewItem(document.getElementById("todolist"), itemText);
};
inItemText.onkeyup = function(event) {
if (event.which == 13) {
var itemText = inItemText.value;
if (!itemText || itemText === "" || itemText === " ") {
return false;
}
addNewItem(document.getElementById("todolist"), itemText);
inItemText.focus();
inItemText.select();
}
};
#btnAdd {
text-transform: uppercase;
background: #22B473;
border: none;
border-radius: 3px;
font-weight: bold;
color: #FFF;
padding: 3px 10px;
cursor: pointer;
width: auto;
}
.tasks-parent {
border: 2px solid #777;
margin-top: 5px;
width: 35%;
}
html {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
ul {
list-style: none;
padding: 0;
margin: 0;
width: 400px;
}
li {
padding: 5px 10px;
color: #000;
}
li span {
padding-left: 17px;
}
li a {
padding: 0 5px 0 5px;
}
<h1> To Do List</h1>
<div id="listBox">
<input type="text" id="inItemText">
<button id="btnAdd">Add</button>
</div>
<div class="tasks-parent">
<h4>Tasks:</h4>
<ul id="todolist">
</ul>
</div>
You need to include the buttons inside your appended span. Also need to change .innerText to .innerHTML
span.innerHTML = itemText + "<button>Edit</button><button>Delete</button>";
add classes to the inserted buttons to style