parent node undefined after removing last element - javascript

I'm trying to make a to do list where you can dynamically append a remove button that appears with each new appended element in a parent div. clicking the remove button is sup[posed to remove the corresponding new element only
This works for the last item on the list, but when I try to remove others the console says it's parent node is null.
any advice as to what's going on here?
var input = document.getElementById("boxInput");
var output = document.getElementById("output")
var submit = document.getElementById("submit")
var i = 0;
function addElement(parentId, elementTag, elementId, html) {
var output = document.getElementById(parentId);
var newElement = document.createElement(elementTag);
newElement.setAttribute('id', elementId);
newElement.innerHTML = html;
output.appendChild(newElement)
}
function removeElement(elementId) {
var element = document.getElementById(elementId);
element.parentNode.removeChild(element);
}
var itemId = 0;
function additem() {
i += 1
itemId++;
const btn = document.createElement("button");
btn.onclick = function() {}
var html = i + ". " + input.value + " " + `<button onclick="javascript:removeElement('item-' + itemId + ''); return false;">X</button>`;
addElement("output", "p", ("item-" + itemId), html);
return itemId
}
submit.addEventListener("click", additem);
#box {
margin:auto;
border-width: 3px;
border-radius:5px;
border-color:black;
border-style:solid;
width:300px;
height:100px;
margin-top:200px;
line-height:100px;
display:flex;
justify-content:center;
align-items:center;
}
#boxInput {
width:150px;
text-align:center;
margin-right:5px;
}
#output {
margin-top:20px;
width:100%;
text-align:center;
}
h1 {
margin:center;
text-align:center;
position:relative;
top:190px;
}
.delete {
margin-left:5px;
}
<h1>To Do List!</h1>
<div id="box">
<input id="boxInput" placeholder="add an item"/>
<button id="submit">Submit</button>
</div>
<div id="output">
</div>

There is no need for itemId or something like that. Just create a div for each todo item. Add a <button> and <span> to it. Add event listener to button in which you remove the whole todo div from the output element
var input = document.getElementById("boxInput");
var output = document.getElementById("output")
var submit = document.getElementById("submit")
function additem() {
const todo = document.createElement('div');
const btn = document.createElement('button');
btn.innerHTML = "Remove"
const text = document.createElement('span');
text.innerHTML = input.value;
todo.appendChild(text);
todo.appendChild(btn);
btn.addEventListener('click', (e) => {
output.removeChild(todo)
})
output.appendChild(todo)
}
submit.addEventListener("click", additem);
#box {
margin:auto;
border-width: 3px;
border-radius:5px;
border-color:black;
border-style:solid;
width:300px;
height:100px;
margin-top:200px;
line-height:100px;
display:flex;
justify-content:center;
align-items:center;
}
#boxInput {
width:150px;
text-align:center;
margin-right:5px;
}
#output {
margin-top:20px;
width:100%;
text-align:center;
}
h1 {
margin:center;
text-align:center;
position:relative;
top:190px;
}
.delete {
margin-left:5px;
}
<h1>To Do List!</h1>
<div id="box">
<input id="boxInput" placeholder="add an item"/>
<button id="submit">Submit</button>
</div>
<div id="output">
</div>

Related

Highlight menu item on scroll does not work

The problem I have is the next one:
Only the last section of my code add the class, but the rest not.
Each section of my html has a unique class and the same class is also in the list tags
const activ = () => {
const linkMenus = document.querySelectorAll('a')
sections.forEach(clas => {
const view = clas.getBoundingClientRect()
if (view.top < 50 && view.top >= -800){
clas.classList.add("active");
linkMenus.forEach(lis => {
if (clas.classList.contains("active") &&
lis.classList.contains(clas.id)){
lis.classList.add("active_nav");
}
else {
lis.classList.remove("active_nav");
}
})
}
else{
clas.classList.remove("active");
}
})
};
window.addEventListener('scroll', activ)
I made this idea before, I will put my HTML, CSS and JS code, you can read it and use the JS code, maybe it will help you.
you can see the code on Codepen or use the snippet.
If you have any question, ask me.
Focus on this code in the JavaScript:
window.scrollY > sections[i].offsetTop && window.scrollY < sections[i].offsetTop + sections[i].offsetHeight
Snippet:
var sections = document.getElementsByTagName("section"),
li = document.getElementsByClassName("li"),
i;
window.onscroll = function () {
for ( i = 0 ; i < sections.length ; i = i + 1 ) {
if ( window.scrollY > sections[i].offsetTop && window.scrollY < sections[i].offsetTop + sections[i].offsetHeight ) {
li[i].classList.add("red");
sections[i].classList.add("red");
} else {
li[i].classList.remove("red");
sections[i].classList.remove("red");
}
}
}
body
{
margin:0;
padding:0;
font-family:sans-serif;
height:2800px;
background:#ccc;
}
.fixed
{
position:fixed;
width:300px;
height:200px;
background:#ccc;
right:20px;
top:50px;
padding:20px;
box-sizing:border-box;
}
.fixed ul
{
margin:0;
padding:0;
}
.fixed ul li
{
line-height:40px;
list-style-type:none;
font-size:25px;
font-weight:bold;
}
section
{
width:100%;
height:600px;
background:yellowgreen;
box-sizing:border-box;
border:4px solid;
margin-top:25px;
line-height:600px;
font-size:40px;
text-align:center;
font-weight:bold;
}
.red
{
color:red;
}
<div class="fixed">
<ul>
<li class="li">one</li>
<li class="li">two</li>
<li class="li">three</li>
<li class="li">four</li>
</ul>
</div>
<section>one</section>
<section>two</section>
<section>three</section>
<section>four</section>

Capture selection inside contenteditable div after clicking bold button

I am trying to get the selected text inside a contenteditable div once a button is clicked and so far nothing I try is working. :( Here is the code I have thus far:
html
<html>
<head>
</head>
<body>
<div class="toolbar">
<span class="tool bold" id="tool-bold">B</span>
</div>
<div id="my_textarea" contenteditable>
</div>
</body>
</html>
css
html, body {
margin:0;
padding:0;
}
#my_textarea {
height:20rem;
width:20rem;
resize:none;
border:1px solid #000;
}
.toolbar {
display:flex;
flex-direction:row;
height:50px;
align-items:center;
border:1px solid #000;
width:200px;
padding:10px;
}
.tool {
border:1px solid #000;
width:1em;
height:1em;
line-height:1em;
text-align:center;
cursor:pointer;
}
.tool.bold {
font-weight:bold;
}
javascript
function saveSelection() {
if(window.getSelection) {
sel = window.getSelection();
if(sel.getRangeAt && sel.rangeCount){
return sel.getRangeAt(0);
}
} else if (document.selection && document.selection.createRange) {
return document.selection.createRange();
}
return null;
}
function restoreSelection(range) {
if (range) {
if(window.getSelection) {
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.selection && range.select) {
range.select();
}
}
}
var selection;
window.addEventListener("load", function(){
var textarea = document.getElementById("my_textarea");
var boldTool = document.getElementById("tool-bold");
textarea.addEventListener("blur", function(event){
selection = saveSelection();
});
boldTool.addEventListener("click", function(event){
console.log(selection);
});
});
I managed to only get the desired result if clicking inside an iframe.. If anyone could please help I would so much appreciate it. Thank you in advance and please go easy on me... :)
You may use selectionchange event
var selection;
window.addEventListener("DOMContentLoaded", function(){
var textarea = document.getElementById("my_textarea");
var boldTool = document.getElementById("tool-bold");
document.addEventListener("selectionchange", function(event){
var sel = document.getSelection();
if (sel.anchorNode.parentElement.id == 'my_textarea') {
selection = sel.toString();
}
});
boldTool.addEventListener("click", function(event){
console.log(selection);
});
});
html, body {
margin:0;
padding:0;
}
#my_textarea {
height:20rem;
width:20rem;
resize:none;
border:1px solid #000;
}
.toolbar {
display:flex;
flex-direction:row;
height:50px;
align-items:center;
border:1px solid #000;
width:200px;
padding:10px;
}
.tool {
border:1px solid #000;
width:1em;
height:1em;
line-height:1em;
text-align:center;
cursor:pointer;
}
.tool.bold {
font-weight:bold;
}
<div class="toolbar">
<span class="tool bold" id="tool-bold">B</span>
</div>
<div id="my_textarea" contenteditable>
</div>

Adding elements to DOM with different coordinates each time

I'm creating a to-do list and I have a constructor function for creating the list items. Each time the user hits enter in the input field I want a new task element to be created just below the first one. As of now, I've tried several methods: looping through the constructor function and looping through the individual command that gives the position of the element within the constructor function.
let addTask = document.getElementById('addItem');
addTask.value = '';
let items = [];
let taskBG;
let taskText;
function Task(){
taskBG = document.createElement('div');
taskBG.style.height = '60px';
taskBG.style.width = '800px';
taskBG.style.marginTop = '-680px';
taskBG.style.marginLeft = '502px';
taskBG.style.backgroundColor = 'red';
taskText = document.createElement('div');
taskText.style.position = 'absolute';
taskText.style.marginTop = '-680px';
taskText.style.marginLeft = '550px';
taskText.style.fontSize = '50px';
taskText.style.fontWeight = 'bold';
taskText.style.color = 'lightgrey';
taskBG.appendChild(taskText);
document.body.appendChild(taskText);
document.body.appendChild(taskBG);
};
addTask.addEventListener('keydown', (ev) => {
if(ev.keyCode == 13){
items.push(addTask.value);
new Task();
addTask.value = '';
for(let i=0; i < items.length; i++){
taskText.textContent = items[i];
};
};
});
body {
background-image:url(backg.jpg);
background-size:2400px, 2400px;
}
#mainBG {
height:900px;
width:900px;
background-color:rgb(72, 73, 73);
opacity:0.6;
display:grid;
margin:0 auto;
}
#mainTitle {
display:grid;
margin:0 auto;
height:100px;
width:700px;
background-color:black;
border-radius:10px;
}
#mainText {
color:white;
font-weight:bold;
display:grid;
margin:0 auto;
font-size:70px;
font-family:"Arial Black", Gadget, sans-serif;
}
#addItem {
display:grid;
margin:0 auto;
height:30px;
width:400px;
margin-top:-360px;
border-radius:10px;
background-color:rgb(128, 201, 201);
color:white;
font-weight:bold;
font-family:"Arial Black", Gadget, sans-serif;
font-size:20px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> To-Do </title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="mainBG">
<div id="mainTitle">
<div id="mainText">To-Do</div>
</div>
<input id="addItem" type="text" placeholder="Add a Task!">
</div>
<script src="app.js"></script>
</body>
</html>
Try this:
let addTask = document.getElementById('addItem');
addTask.value = '';
let items = [];
let taskBG;
let taskText;
var totalTasks = 0;
function Task(){
taskBG = document.createElement('div');
taskBG.style.height = '60px';
taskBG.style.width = '800px';
if (totalTasks == 0) {
taskBG.style.marginTop = '-680px';
}
taskBG.style.marginLeft = '502px';
taskBG.style.backgroundColor = 'red';
taskText = document.createElement('div');
taskText.style.position = 'absolute';
if (totalTasks == 0) {
taskText.style.marginTop = '-680px';
}
taskText.style.marginLeft = '550px';
taskText.style.fontSize = '50px';
taskText.style.fontWeight = 'bold';
taskText.style.color = 'lightgrey';
taskBG.appendChild(taskText);
document.body.appendChild(taskText);
document.body.appendChild(taskBG);
if (totalTasks == 0) {
totalTasks = 1;
}
};
addTask.addEventListener('keydown', (ev) => {
if(ev.keyCode == 13){
items.push(addTask.value);
new Task();
addTask.value = '';
for(let i=0; i < items.length; i++){
taskText.textContent = items[i];
};
};
});
body {
background-image:url(backg.jpg);
background-size:2400px, 2400px;
}
#mainBG {
height:900px;
width:900px;
background-color:rgb(72, 73, 73);
opacity:0.6;
display:grid;
margin:0 auto;
}
#mainTitle {
display:grid;
margin:0 auto;
height:100px;
width:700px;
background-color:black;
border-radius:10px;
}
#mainText {
color:white;
font-weight:bold;
display:grid;
margin:0 auto;
font-size:70px;
font-family:"Arial Black", Gadget, sans-serif;
}
#addItem {
display:grid;
margin:0 auto;
height:30px;
width:400px;
margin-top:-360px;
border-radius:10px;
background-color:rgb(128, 201, 201);
color:white;
font-weight:bold;
font-family:"Arial Black", Gadget, sans-serif;
font-size:20px;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title> To-Do </title>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="mainBG">
<div id="mainTitle">
<div id="mainText">To-Do</div>
</div>
<input id="addItem" type="text" placeholder="Add a Task!">
</div>
<script src="app.js"></script>
</body>
</html>
I have just added totalTasks var with the value of 0 and in task() function I am checking if the variable is 0 then add marginTop otherwise do not add it. As marginTop only needed in the first task for the remaining it doesn't be needed.

How can i check if an input field is empty or not when a variable is inserted in this field by jquery?

I want to check if an input field is empty or not and then add/remove class from another element (div). As it is now i am using jquery "input" handler so i can check if the field is empty or not when someone is typing text in it or even if he is copy/paste something in there.
My issue is that when i try to pass text in the field using the code below it doesnt work as it should.
Kindly check my code below:
$('.home-page-address-field').on('input', function(){
if($('#s').val() == '' ) {
$("#location-btn").addClass('disable2');
}else {
$("#location-btn").removeClass('disable2');
}
});
var cityA = "London";
alert('The var "cityA" will be inserted to the field and the class "disable2" should be removed from the Browse button but it is not !');
$(function () {
$('.home-page-address-field').val(cityA);
});
.home-page-address-field {
height:30px;
margin-right:15px;
border:1px solid #ccc;
padding:0px 8px;
}
.browse-button {
padding:5px;
height:25px;
background:#0088cc;
color:#fff;
display:inline-block;
width:120px;
text-align:center;
}
.disable2{
opacity:0.4;
pointer-events:none;
background:gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="s" placeholder="Enter your city..." class="home-page-address-field"/>
<div id="location-btn" class="disable2 browse-button">BROWSE</div>
Changing the val() programatically doesn't trigger any event handlers. For that, you can use .trigger():
$('.home-page-address-field').on('input', function(){
if($('#s').val() == '' ) {
$("#location-btn").addClass('disable2');
}else {
$("#location-btn").removeClass('disable2');
}
});
var cityA = "London";
alert('The var "cityA" will be inserted to the field and the class "disable2" should be removed from the Browse button but it is not !');
$(function () {
$('.home-page-address-field').val(cityA).trigger('input');
});
.home-page-address-field {
height:30px;
margin-right:15px;
border:1px solid #ccc;
padding:0px 8px;
}
.browse-button {
padding:5px;
height:25px;
background:#0088cc;
color:#fff;
display:inline-block;
width:120px;
text-align:center;
}
.disable2{
opacity:0.4;
pointer-events:none;
background:gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="s" placeholder="Enter your city..." class="home-page-address-field"/>
<div id="location-btn" class="disable2 browse-button">BROWSE</div>

Need help in drag and drop uploading

When I select and drag and drop multiple files in the drop files area, it goes to Uploads folder but I see only one item under the drop files area each time when uploading.
I want to show multiple files instead of one file/item under the drop files area when uploading.
How can I do that?
if(file_exists($serverpath)) is not working. I don't know why.
Can you people look into it?
I want the same uploaded file rename from 0 to 1,2,3 when I upload files when files exist(if(file_exists($serverpath))) in Uploads folder.
When I click on a image it shows a image box.
I need the .Crop-Box resizable and draggable.
I am using mozilla firefox and google chrome.
Here is the code:
*{margin:0; padding:0;}
body{background:black;}
#Container{
margin:200px auto;
width:620px;
padding-bottom:20px;
background:#ffffff;
color:black;
border:1px solid gray;
border-radius:5px;
}
#Text{
margin:20px;
color:green;
font-family:verdana;
font-size:12pt;
}
#Drop{
margin:20px auto;
padding:20px;
color:gray;
width:500px;
height:40px;
background:#f1f1f1;
border:1px dotted #ccc;
border-radius:5px;
}
.progressbar{
margin:20px auto;
width:80%;
height:20px;
background:#ddd;
border-radius:5px;
display:none;
}
.progress{
width:0%;
height:20px;
border-radius:5px;
background:linear-gradient(to bottom, lightblue, #2196f3);
}
.progresstext{
float:right;
}
.InsertInto{
margin-top:20px;
}
.image{
margin:20px;
width:15%;
height:20%;
display:none;
}
.FileDiv{
margin-bottom:20px;
}
.filenam{
position:absolute;
margin-top:-57px;
margin-left:140px;
}
#RealFile{
margin:20px;
display:none;
}
#UploadImage{
margin-left:100px;
padding:20px 200px;
background:#2196f3;
color:white;
border:none;
border-radius:5px;
cursor:pointer;
}
button:focus{
outline:none;
}
#Submit{
margin-left:100px;
padding:20px 200px;
background:#219549;
color:white;
border:none;
border-radius:5px;
cursor:pointer;
}
.Crop-Main{
position:relative;
width:600px;
min-width:600px;
height:520px;
margin:100px auto;
padding:20px;
background:#f1f1f1;
color:black;
border:1px solid #ccc;
border-radius:5px;
z-index:1;
display:none;
}
#Close{
background:#2196f3;
color:white;
padding:10px;
font-family:verdana;
font-size:12pt;
cursor:pointer;
border-radius:5px;
margin:20px;
margin-right:0px;
float:right;
user-select:none;
}
.Crop-Container{
position:relative;
width:600px;
margin:80px auto;
min-height:300px;
}
.Crop-Container img{
width:600px;
user-select:none;
}
.Crop-Box{
position:absolute;
width:200px;
height:200px;
top:0;
left:0;
background:rgba(69,69,69,0.6);
border:1px solid white;
z-index:2;
cursor:move;
}
#Save{
position:absolute;
padding:20px 80px;
background:green;
color:white;
border:none;
border-radius:5px;
font-family:verdana;
font-size:12pt;
cursor:pointer;
margin:-70px 200px;
}
.InsertInto img{
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<html>
<link rel="stylesheet" type="text/css" href="style.css"/>
<script src="jquery.min.js"></script>
<body>
<div class="Crop-Main">
<span id="Close">X</span>
<div class="Crop-Container">
<img src=""/>
<div class="Crop-Box"></div>
</div>
<button id="Save" onclick="save()">Save</button>
</div>
<div id="Container">
<div id="Text">Advanced File Uploader</div>
<div id="Drop">Drop files here</div>
<div class="progressbar">
<div class="progress"></div>
<div class="progresstext">0%</div>
</div>
<div class="InsertInto">
</div>
<input type="file" name="realfile" id="RealFile" multiple="true"><br/><br/>
<button id="UploadImage" type="button">Upload</button>
<br/><br/>
<form action="uploads.php" method="POST" id="myForm" enctype="multipart/form-data">
<input type="submit" name="submit" id="Submit" value="Submit">
</form>
</div>
<script>
var obj = document.querySelector("#Drop");
var realf = document.querySelector("#RealFile");
obj.ondragover = function(e){
$(this).css("border-color","green");
return false;
}
obj.ondragleave = function(e){
return false;
$(this).css("border","none");
}
obj.ondrop = function(e){
e.preventDefault();
$(this).css("border-color","#2196f3");
var files = e.dataTransfer.files;
upload(files);
console.log(files);
}
realf.onchange = function(e){
var files = e.currentTarget.files;
upload(files);
console.log(files);
}
function upload(e){
var formdata = new FormData();
var xhttp = new XMLHttpRequest();
var i;
for(i=0; i < e.length; i++){
formdata.append("realfile[]", e[i]);
}
if(xhttp.upload){
xhttp.open("POST", "upload.php", true);
xhttp.upload.addEventListener("progress", function(e){
var parcent = (e.loaded / e.total) * 100;
document.querySelector(".progressbar").style.display = "block";
document.querySelector(".progress").style.width = parcent+"%";
document.querySelector(".progresstext").innerHTML = parcent+"%";
});
xhttp.onreadystatechange = function(){
if(xhttp.readyState == 4 && xhttp.status == 200){
var result;
result = this.responseText;
var newresult = JSON.parse(result);
var i;
document.querySelector(".progressbar").style.display = "none";
var insertinto = document.querySelector(".InsertInto");
var filediv = document.createElement("DIV");
filediv.className = "FileDiv";
insertinto.appendChild(filediv);
var img = document.createElement("IMG");
img.className = "image";
filediv.appendChild(img);
img.setAttribute("src",newresult.url);
img.setAttribute("width","100%");
img.setAttribute("height","100%");
img.style.display = "block";
img.addEventListener("click", function(e){
var cropmain = document.querySelector(".Crop-Main");
cropmain.style.display = "block";
document.querySelector("#Container").style.display = "none";
var imgsrc = $(this).attr("src");
$(".Crop-Container img").attr("src", imgsrc);
});
var close = document.querySelector("#Close");
close.addEventListener("click", function(e){
document.querySelector(".Crop-Main").style.display = "none";
document.querySelector("#Container").style.display = "block";
});
var filenam = document.createElement("DIV");
filenam.className = "filenam";
filenam.innerHTML = newresult.name;
insertinto.appendChild(filenam);
if(newresult != "" && newresult != "Not Ok"){
for(i=0; i<newresult.length; i++){
if(newresult[i].status == true){
}
}
}
console.log(xhttp.responseText);
}
}
xhttp.send(formdata);
}
}
$("#UploadImage").click(function(e){
$("#RealFile").click();
});
$(".InsertInto").on("click", ".InsertInto img", function(){
var img = $(this).attr("src");
$(".Crop-Container").find("img").attr("src", img);
var w = $(".Crop-Container img").width();
var h = $(".Crop-Container img").height();
$(".Crop-Container").width(w);
$(".Crop-Container").height(h);
document.querySelector(".Container").style.display = "none";
document.querySelector(".Crop-Main").style.display = "block";
});
</script>
</body>
</html>
PHP
<?php
$status = array();
$allow = array("image/jpeg", "image/png");
//print "<pre>"
//print_r($_FILES["file"]);
//print "</pre>"
foreach($_FILES["realfile"]["name"] as $pos => $val){
if(!in_array(strtolower($_FILES["realfile"]["type"][$pos]), $allow)){
$status = array(
"name" => $_FILES["realfile"]["name"],
"type" => $_FILES["realfile"]["type"],
"url" => "",
"message" => "Invalid file type",
"status" => false
);
}
else{
$tmpname = $_FILES['realfile']['tmp_name'][$pos];
$filename = $_FILES["realfile"]["name"][$pos];
//$path = "Uploads/".$filename;
$addition = 0;
$serverpath = $_SERVER['DOCUMENT_ROOT']."Uploads/".$filename;
if(file_exists($serverpath)){
while(file_exists($serverpath)){
$addition = $addition + 1;
$info = pathinfo($serverpath);
$directory = $info["dirname"];
$oldname = $info["filename"];
$oldext = $info["extension"];
$serverpath = $directory."/".$oldname.$addition.".".$oldext;
}
$serverpath = "Uploads/".$oldname.$addition.".".$oldext;
}
else{
$serverpath = "Uploads/".$filename;
}
move_uploaded_file($tmpname, $serverpath);
$status = array(
"name" => $_FILES["realfile"]["name"][$pos],
"type" => $_FILES["realfile"]["type"][$pos],
"url" => $serverpath,
"message" => "File Uploaded",
"status" => true
);
}
}
echo json_encode($status);
?>

Categories

Resources