Multi uploaded video with multi dynamic progress bar - javascript

I have <input type="file" multiple /> What I've tried to do is when I select multiple videos, and for each one of them I want:
=> a dynamic progress bar.
=> input field(so the user can change the video name).
=> input type image(default video image).
=> save button (it will be clickable if the user add name value or default image, otherwise will be disabled).
please open this image to see what I mean
what I've tried:
index.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>File Upload JavaScript with Progress Ba | CodingNepal</title>
<link rel="stylesheet" href="style.css" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
/>
<link rel="shortcut icon" href="#" />
</head>
<body>
<div class="wrapper">
<header>File Uploader</header>
<form action="#">
<input class="file-input" type="file" name="file" hidden multiple />
<i class="fas fa-cloud-upload-alt"></i>
<p>Browse videos to Upload</p>
</form>
<section class="progress-area"></section>
<section class="uploaded-area"></section>
</div>
</body>
<script>
const form = document.querySelector("form"),
fileInput = document.querySelector(".file-input"),
progressArea = document.querySelector(".progress-area"),
uploadedArea = document.querySelector(".uploaded-area");
form.addEventListener("click", () => {
fileInput.click();
});
fileInput.onchange = ({ target }) => {
let files = target.files.length;
for (let i = 0; i < files; i++) {
if (files[i]) {
let fileName = target.files[i]["name"];
if (fileName.length >= 12) {
let splitName = fileName.split(".");
fileName = splitName[0].substring(0, 13) + "... ." + splitName[1];
}
}
let xhr = new XMLHttpRequest();
xhr.open("POST", "php/upload.php");
xhr.upload.addEventListener("progress", ({ loaded, total }) => {
let fileLoaded = Math.floor((loaded / total) * 100);
let fileTotal = Math.floor(total / 1000);
let fileSize;
fileTotal < 1024
? (fileSize = fileTotal + " KB")
: (fileSize = (loaded / (1024 * 1024)).toFixed(2) + " MB");
let progressHTML = `
<li class="row">
<i class="fas fa-file-alt"></i>
<div class="content">
<div class="details">
<span class="name">${target.files[i]["name"]} • Uploading</span>
<span class="percent">${fileLoaded}%</span>
</div>
<div class="progress-bar">
<div class="progress" style="width: ${fileLoaded}%"></div>
</div>
</div>
</li>
`;
uploadedArea.classList.add("onprogress");
progressArea.innerHTML = progressHTML;
if (loaded === total) {
progressArea.innerHTML = "";
let uploadedHTML = `
<li class="row">
<div class="content upload">
<i class="fas fa-file-alt"></i>
<div class="details">
<span class="name">${target.files[i]["name"]} • Uploaded</span>
<span class="size">${fileSize}</span>
</div>
</div>
<i class="fas fa-check"></i>
</li>
`;
uploadedArea.classList.remove("onprogress");
uploadedArea.insertAdjacentHTML("afterbegin", uploadedHTML);
}
});
let data = new FormData(form);
xhr.send(data);
}
};
</script>
</html>
upload.php
<?php
if (isset($_FILES['files'])) {
for ($count = 0; $count < count($_FILES['files']['name']); $count++) {
$extension = pathinfo($_FILES['files']['name'][$count], PATHINFO_EXTENSION);
$new_name = uniqid() . '.' . $extension;
move_uploaded_file($_FILES['files']['tmp_name'][$count], 'files/' . $new_name);
}
echo 'success';
}
So, in the controller To get the videos,
function getVideos(Request $request){
$request->all();
return true;
}
The problem is he just gives one progress bar!

Related

Why is replaceChild cause problems?

function httpGet(theUrl) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", theUrl, false); // false for synchronous request
xmlHttp.send(null);
return xmlHttp.responseText;
}
var videosT = httpGet("https://www.googleapis.com/youtube/v3/search?part=snippet&channelId=abcxyz&maxResults=6&order=date&type=video&key=abcxyz");
const videos = JSON.parse(videosT);
for (let step = 0; step < 6; step++) {
fetch('js/videos.html')
.then(res => res.text())
.then(text => {
let oldelem = document.getElementById("vid_" + step);
let newelem = document.createElement("div");
newelem.innerHTML = text;
oldelem.parentNode.replaceChild(newelem, oldelem);
})
}
html:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ashk3000</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-gH2yIJqKdNHPEq0n4Mqa/HGKIhSkIHeL5AyhkYV8i59U5AR6csBvApHHNl/vI1Bx" crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
</head>
<body class="d-flex flex-column" viewport-fit=cover>
<!-- Navbar -->
<script id="navbar_placeholder" src="js/nav.js" page="home"></script>
<!-- Headers -->
<div
class="d-none d-lg-block shadow bg-body border border-5 border-top-0 rounded-bottom w-75 position-relative start-50 translate-middle-x mb-5">
<div class="container-fluid py-5">
<h1 class="display-5 fw-bold">Home</h1>
</div>
</div>
<div class="d-lg-none shadow-sm bg-body border-bottom border-5 w-100 position-relative mb-3">
<div class="container-fluid py-5">
<h1 class="display-5 fw-bold">Home</h1>
</div>
</div>
<!-- Start -->
<div class="container">
<div class="row">
<div id="vid_0"></div>
<div id="vid_1"></div>
<div id="vid_2"></div>
<div class="w-100"></div>
<div id="vid_3"></div>
<div id="vid_4"></div>
<div id="vid_5"></div>
</div>
</div>
<script src="js/videos.js"></script>
<!-- Footer -->
<div class="mt-auto"></div>
<script id="footer_placeholder" src="js/footer.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.2.0/dist/js/bootstrap.bundle.min.js"
integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa"
crossorigin="anonymous"></script>
</body>
</html>
videos.html:
<div class="card col" style="width: 18rem;">
<img src="" id="thumbnail" class="card-img-top" alt="">
<div class="card-body">
<h5 id="title" class="card-title">Title</h5>
Watch
</div>
</div>
Hello, I am getting the replit "Not Found" screen when I try this code. I think it has to do with replaceChild. I am new to java script and dont know what it happening. A lot of it is from the internet. I am trying to make it show recent youtube uploads. It wants me to add more text. sorry this is rushed.
When you replace the element, you need to give it the ID of the element that it's replacing, so you will be able to find it the next time.
for (let step = 0; step < 6; step++) {
fetch('js/videos.html')
.then(res => res.text())
.then(text => {
let oldelem = document.getElementById("vid_" + step);
let newelem = document.createElement("div");
newelem.id = oldelem.id; // copy the ID.
newelem.innerHTML = text;
oldelem.parentNode.replaceChild(newelem, oldelem);
var pic = document.getElementById('thumbnail');
pic.classList.add('thumbnail_' + step);
pic.id = "thumbnail_" + step;
pic.setAttribute('src', videos.items[step].snippet.thumbnails.high.url);
})
}
Or instead of replacing the element, you could just update the innerHTML of the old element.
for (let step = 0; step < 6; step++) {
fetch('js/videos.html')
.then(res => res.text())
.then(text => {
let oldelem = document.getElementById("vid_" + step);
oldelem.innerHTML = text;
var pic = document.getElementById('thumbnail');
pic.classList.add('thumbnail_' + step);
pic.id = "thumbnail_" + step;
pic.setAttribute('src', videos.items[step].snippet.thumbnails.high.url);
})
}

How do i fix the result without reloading the site?

Whenever I am writing apple or samsung, It is showing results, but if I don't refresh the page for the second time, it gives me error. However, If I reload the website, then it is showing me the results of samsung or oppo or whatever. Can you please tell me where I made the mistake ? I am attaching the HTML and JS below :
// error handle
const displayHandle = (direction, id) => {
const errorMessage = document.getElementById(id);
errorMessage.style.display = direction;
}
// clear previous result
const clearSearchResult = (direction) => {
const searchResult = document.getElementById(direction);
searchResult.innerHTML = '';
}
// details button action form
const allDetails = (id) => {
// console.log(id)
fetch(`https://openapi.programming-hero.com/api/phone/${id}`)
.then(response => response.json())
.then(data => {
const sensorName = data.data.mainFeatures.sensors;
let storeSensorName = '';
for (const sensor of sensorName) {
storeSensorName = `${storeSensorName} ${sensor}, `
}
const mobileDetails = document.getElementById('show-details');
mobileDetails.innerHTML = `
<div class=" row row-cols-1 row-cols-md-3 g-4">
<div class="col">
<div class="card">
<img src=${data.data.image} class="card-img-top w-50 h-50" alt="...">
<div id="details-body" class="card-body">
<h5 class="card-title">Brand: ${data.data.brand}</h5>
<p class="card-text">Storage: ${data.data.mainFeatures.storage}</p>
<p class="card-text">ChipSet: ${data.data.mainFeatures.chipSet}</p>
<p class="card-text">DisplaySize: ${data.data.mainFeatures.displaySize}</p>
<p class="card-text">Sensors : ${storeSensorName}</p>
</div>
</div>
</div>
</div>
`;
// inject release Date
const container = document.getElementById('details-body');
const p = document.createElement('p');
if (data.data.releaseDate) {
p.innerText = `Release Information:${data.data.releaseDate}`;
container.appendChild(p);
} else {
p.innerText = `Release Information Not Found`;
container.appendChild(p);
}
});
}
//search button action form
document.getElementById('search-btn').addEventListener('click', function() {
clearSearchResult('show-details');
clearSearchResult('show-mobile');
displayHandle('none', 'error-message');
displayHandle('none', 'show-all-Button')
// get search field
const searchBox = document.getElementById('search-box');
const searchData = searchBox.value;
fetch(`https://openapi.programming-hero.com/api/phones?search=${searchData}`)
.then(res => res.json())
.then(data => {
if (data.data.length != 0) {
displayMobile(data.data)
} else {
displayHandle('block', 'error-message');
}
})
// clear search field
searchBox.value = ' ';
})
const displayMobile = (mobiles) => {
// console.log(phones);
const showMobile = document.getElementById('show-mobile');
let count = 0;
for (const mobile of mobiles) {
if (count < 20) {
const div = document.createElement('div');
div.classList.add("col");
div.innerHTML = `
<div class="card d-flex align-items-center">
<img src=${mobile.image} class="card-img-top w-50 h-50" alt="...">
<div class="card-body">
<h5 class="card-title">Model : ${mobile.phone_name}</h5>
<p class="card-text">Brand : ${mobile.brand}</p>
<button class="card-button" onclick="allDetails('${mobile.slug}')">Details</button>
</div>
</div>
`;
showMobile.appendChild(div);
} else {
displayHandle('block', 'show-all-Button');
}
count++;
}
}
<!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>
<!-- connection with bootstrap -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<style>
.display-handle {
display: none;
color: rgb(231, 49, 49);
}
.card-button {
color: white;
background-color: brown;
border-radius: 10px;
}
</style>
</head>
<body>
<!-- search box section
----------------->
<section class="container w-75 mx-auto pt-5">
<h5 id="error-message" class="display-handle text-center">Not found..! Press authentic data...</h5>
<h3 class="text-center bg-dark text-white">Mobile Maya</h3>
<div class="input-group mb-3">
<input id="search-box" type="text" class="form-control" placeholder="Enter your desired mobile " aria-label="" aria-describedby="button-addon2">
<button class="btn btn-success" type="button" id="search-btn">Search</button>
</div>
</section>
<!-- display products details -->
<section id="show-details" class="container">
<!-- inject details here -->
</section>
<!-- search result display section
---------------------------------->
<section class="container pt-5">
<div id="show-mobile" class=" row row-cols-1 row-cols-md-3 g-4">
</div>
</section>
<!-- show all button -->
<section class="container">
<div class="d-flex justify-content-center">
<button style="color: white; background-color:tomato; border-radius: 8px;" id="show-all-Button" class="display-handle" type="button" class="btn btn-primary">Show All</button>
</div>
</section>
<!-- connection with js
----------- -->
<script src="js/app.js"></script>
<!-- connection with bootstrap script -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p" crossorigin="anonymous"></script>
</body>
</html>
It is because of this line, you don't really clear the search field :
// clear search field
searchBox.value = ' ';
You should either assign the empty string value '' or call the method trim() on searchData.

On click only works once

for my responsive (mobile) hamburger-menu, i wanted to show the menu, when a class is pressed.
But it only works once ('click' is only locked once in the console, so it doesn't register the clicks after it was pressed one time). NOTE: I use PHP for the side and for the menu html.
What is my mistake? Thank you for your advice!
var btn = document.querySelector(".toggle-btn");
var navbar = document.querySelector(".menue");
btn.addEventListener('click', () => {
console.log('click');
navbar.classList.toggle("active");
})
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class="nav-bar">
<nav>
<div class="logo">
<img src="../png/lg_nord_logo_navbar.png" alt="">
</div>
<a href="#" class="toggle-btn">
<span class="bar">Bar 1</span>
<span class="bar">Bar 2</span>
<span class="bar">Bar 3</span>
</a>
<div class="menue">
<ul>
<li>Disziplinen
<ul>
<li>30 meter startblock</li>
<li>30 meter fliegend</li>
<li>60 meter</li>
<li>10er Hopserlauf</li>
<li>Klappmesser</li>
<li>Klimmzüge</li>
<li>Liegestütze</li>
<li>Standweitsprung</li>
</ul>
</li>
<li>Daten hinzufügen
<ul>
<li>30 meter startblock</li>
<li>30 meter fliegend</li>
<li>60 meter</li>
<li>10er Hopserlauf</li>
<li>Klappmesser</li>
<li>Klimmzüge</li>
<li>Liegestütze</li>
<li>Standweitsprung</li>
</ul>
</li>
<li><i class="material-icons">support_agent</i>Athleten (beta)
<ul>
<li>Tom-Luca</li>
<li>Marc          </li>
<li>Leo          </li>
<li>Lukas</li>
<li>Vincent</li>
<li>Damien</li>
<li>Karsten</li>
</ul>
</li>
<li><i class="material-icons">admin_panel_settings</i> Einstellungen</li>
<li><a class="state" href="login.php">Login</a></li>
<li><i class="fas fa-sign-out-alt"></i> Logout</li>
</ul>
</div>
</nav>
</div>
```
My PHP code:
<?php
session_start();
if(!isset($_SESSION["username"])){
header("Location: ../index.php");
exit;
}
require("../rank_manager.php");
if(getRank($_SESSION["username"]) == USER){
header("Location: ../errors/error.php?code=101&name=not_enought_permissions&type=website");
exit;
}
if(isBanned($_SESSION["username"])){
header("Location: logout.php");
exit;
}
?>
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#34495e">
<title>Daten hinzufügen</title>
<link rel="stylesheet" href="./css/style.theme.css">
<script src="https://kit.fontawesome.com/c54c107c6a.js" crossorigin="anonymous"></script>
<script type="text/javascript "src="../../theme/themeManager.js" defer></script>
<script type="text/javascript "src="navbar_menu.js" defer></script>
</head>
<body class="light">
<div class="themeChange">
<button id="changeTheme"><i class="material-icons">dark_mode</i></button>
</div>
<div class="preloader">
<img src="../png/preloader-final.gif" alt="">
</div>
<?php
include("../navbar/navbar.html");
?>
<div class="data">
<form action="standweitsprung.php" method="post">
<h1>Daten eintragen</h1>
<br><br>
<input type="text" name="period" placeholder="Zeitraum">
<input name="tom" id="tom_input" type="number" step="0.01" placeholder="Tom">
<input name="marc" id="marc_input" type="number" step="0.01" placeholder="Marc">
<input name="leo" id="leo_input" type="number" step="0.01" placeholder="Leo">
<input name="lukas" id="lukas_input" type="number" step="0.01" placeholder="Lukas">
<input name="vincent" id="vincent_input" type="number" step="0.01" placeholder="Vincent">
<input name="damien" id="damien_input" type="number" step="0.01" placeholder="Damien">
<input name="karsten" id="karsten_input" type="number" step="0.01" placeholder="Karsten">
<button type="submit" name="submit">Daten absenden</button>
</form>
</div>
<?php
if(isset($_POST["submit"])){
$period = $_POST["period"];
$tom = $_POST["tom"];
$marc = $_POST["marc"];
$leo = $_POST["leo"];
$lukas = $_POST["lukas"];
$vincent = $_POST["vincent"];
$damien = $_POST["damien"];
$karsten = $_POST["karsten"];
if($tom == "") {
$tom = null;
}
if($lukas == "") {
$lukas = null;
}
if($leo == "") {
$leo = null;
}
if($marc == "") {
$marc = null;
}
if($vincent == "") {
$vincent = null;
}
if($damien == "") {
$damien = null;
}
if($karsten == "") {
$karsten = null;
}
$content = array(
"period" => $period,
"tom" => $tom,
"marc" => $marc,
"leo" => $leo,
"lukas" => $lukas,
"vincent" => $vincent,
"damien" => $damien,
"karsten" => $karsten,
);
if(filesize("../data/standweitsprung.json") == 0) {
$first_record = array($content);
$data_to_save = $first_record;
} else {
$old_records = json_decode(file_get_contents("../data/standweitsprung.json"));
array_push($old_records, $content);
$data_to_save = $old_records;
}
if(!(file_put_contents("../data/standweitsprung.json", json_encode($data_to_save, JSON_PRETTY_PRINT), LOCK_EX))) {
$error = "Error storing content";
} else {
$success = "Daten gespeichert";
}
}
?>
<div class="turn-device">
<img src="../png/rotate-device-light.png" alt="">
</div>
<script src="../javascript/preloader.js"></script>
</body>
</html>
I've fixed it. The problem was that the mobile nav-bar had rendered a transparent object on top of the button, so I never clicked the button actually. The solution was to give the button a higher z-index.

Unable to access the DOM which I passed as a string. How to do it by using external function as I defined in the code?

I want to add an event to the "Important" link i.e. When One user clicks the "Important" link, the corresponding card color should be changed and saved in the localstorage but, when I am accessing that DOM file which I passed as a string, I am unable to do it. For e.g. - I can't access to document.getElementsByClassName("noteCard") in function markNotes(index). But at the same time
console.log("Color is not applied") executes successfully. If I am adding document.body.style.backgroundColor = "lightblue"; then also body color changes accordingly, but the I want to change the background color of the card with class "noteCard" only. I am really stuck with it.
Below is my HTML code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Magic Notes</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<link rel="stylesheet" href="Customstyle.css">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar navbar-dark bg-dark">
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarTogglerDemo01" aria-controls="navbarTogglerDemo01" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarTogglerDemo01">
<a class="navbar-brand" href="#">Magic Notes</a>
<ul class="navbar-nav mr-auto mt-2 mt-lg-0">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="https://www.facebook.com/balabhadra.chand/" target="_blank">About me</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" id="searchTitle" type="search" placeholder="Search by title" aria-label="Search">
</form>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" id="searchTxt" type="search" placeholder="Search text" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0 " id="searchBtn" type="submit">Search</button>
</form>
</div>
</nav>
<h1 class="heading">It's all about magic !!!</h1>
<div class="card" style="width: 1000px;">
<div class="input-group">
<div class="input-group-prepend">
<span class="input-group-text">Add a title to your note</textarea></span>
</div>
<textarea class="form-control" id="addTitle" aria-label="With textarea"></textarea>
</div>
<div class="card-body">
<form>
<div class="form-group">
<label for="exampleFormControlTextarea1">Write your Note</label>
<textarea class="form-control" id="addTxt" rows="3"></textarea>
</div>
</form>
<button class="btn btn-primary" id="addBtn">ADD NOTE</button>
</div>
</div>
<hr>
<h5>Your Notes</h5>
<hr>
<div id="notes" class="row container-fluid"></div>
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js#1.16.0/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js" integrity="sha384-OgVRvuATP1z7JjHLkuOU7Xw704+h835Lr+6QL9UvYjZE3Ipu6Tp75j7Bh/kR0JKI" crossorigin="anonymous"></script>
<script src="myscript.js"></script>
</body>
Here is my JavaScript code
console.log('MagicNotes')
showNotes();
let addBtn = document.getElementById("addBtn");
addBtn.addEventListener("click", function(e) {
let addTxt = document.getElementById("addTxt");
let addTitle = document.getElementById("addTitle");
let notes = localStorage.getItem("notes");
if (notes != null) {
notesObj = JSON.parse(notes);
} else {
notesObj = [];
}
let myObj = {
title: addTitle.value,
text: addTxt.value
}
notesObj.push(myObj)
localStorage.setItem("notes", JSON.stringify(notesObj));
addTxt.value = "";
addTitle.value = "";
showNotes();
});
function showNotes() {
let notes = localStorage.getItem("notes");
if (notes != null) {
notesObj = JSON.parse(notes);
} else {
notesObj = [];
}
let html = "";
notesObj.forEach(function(element, index) {
html += `<div class="noteCard card" style="width: 18rem;">
<div class="card-body">
<h5 class="card-title">Title: ${element.title}</h5>
<p class="card-text">${element.text}</p>
<a href="#" id="${index}"onclick="deleteNotes(this.id)" class="card-link" >Delete Note</a>
Important
</div>
</div>`;
});
let notesElem = document.getElementById("notes");
if (notesObj.length != 0) {
notesElem.innerHTML = html;
} else {
notesElem.innerHTML = `Please add a note by clicking "ADD NOTE"`;
}
}
function deleteNotes(index) {
let notes = localStorage.getItem("notes");
if (notes != null) {
notesObj = JSON.parse(notes);
} else {
notesObj = [];
}
notesObj.splice(index, 1);
localStorage.setItem("notes", JSON.stringify(notesObj));
showNotes();
}
function markNotes(index) {
let notes = localStorage.getItem("notes");
if (notes != null) {
notesObj = JSON.parse(notes);
} else {
notesObj = [];
}
document.getElementsByClassName("noteCard").style.color = "lightblue";
console.log("Color is not applied")
localStorage.setItem("notes", JSON.stringify(notesObj));
showNotes();
}
let searchText = document.getElementById('searchTxt');
searchText.addEventListener("input", function(txt) {
let inputVal = searchText.value.toLowerCase();
// console.log('Input event fired!', inputVal);
let noteCards = document.getElementsByClassName('noteCard');
Array.from(noteCards).forEach(function(element) {
let cardTxt = element.getElementsByTagName("p")[0].innerText;
if (cardTxt.includes(inputVal)) {
element.style.display = "block";
} else {
element.style.display = "none";
}
// console.log(cardTxt);
})
})
let searchTitle = document.getElementById('searchTitle');
searchTitle.addEventListener("input", function(title) {
let inputValTitle = searchTitle.value.toLowerCase();
let noteCardsTitle = document.getElementsByClassName('noteCard');
Array.from(noteCardsTitle).forEach(function(element) {
let cardTitle = element.getElementsByTagName("h5")[0].innerText;
if (cardTitle.includes(inputValTitle)) {
element.style.display = "block";
} else {
element.style.display = "none";
}
// console.log(cardTitle);
})
})
You were missing index while fetching element inside markNotes:
function markNotes(index) {
let notes = localStorage.getItem("notes");
if (notes != null) {
notesObj = JSON.parse(notes);
} else {
notesObj = [];
}
let noteCard = document.getElementsByClassName("noteCard")[index];
noteCard.style.color = "lightblue";
console.log("Color is applied")
localStorage.setItem("notes", JSON.stringify(notesObj));
//showNotes(); you don't need to add this again
}
complete working code fiddle link

Why is text in between bold tags not rendered bold?

I am building a web tool for authors that follows a format we need for our backend. I didn't like a number of pre-made solutions for rich text editors as they were having way more features than I would need so I decided to parse my text through a function to detect bold using ** in the text.
I came across a regex solution here and when I used it, it detected the bold text and substituted * for <b> but displayed the tags instead of making the text between <b> and </b> bold.
I am new to HTML, CSS and JS so probably this is a simple error, but I couldn't find out how to deal with it myself...
// Tracks number of current textareas i.e. paragraphs
var element_counter = 0;
// Add Paragraph on button press
document.getElementById("addParagraph").addEventListener("click", function() {
var textarea = document.createElement("textarea");
var text = "Here goes your new paragraph.";
var node = document.createTextNode(text);
textarea.setAttribute("id", element_counter);
//textarea.setAttribute("class", "flow-text");
//textarea.setAttribute("oninput", "this.style.height = '';this.style.height = this.scrollHeight + 'px'");
textarea.append(node);
var section = document.getElementById("editor");
section.appendChild(textarea);
element_counter++;
reloadPreview();
});
// Add Image on button press
document.getElementById("addImage").addEventListener("click", function() {
var image = document.createElement("input");
image.setAttribute("type", "file");
image.setAttribute("id", element_counter);
image.setAttribute("accept", "image/*");
image.setAttribute("class", "file-field input-field");
var section = document.getElementById("editor");
section.appendChild(image);
element_counter++;
});
// Remove paragraph with confirmation step on button press
var confirm = false;
document.getElementById("removeLastItem").addEventListener("click", function() {
// Ensure there is an object to remove and wait for confirmation
if (document.getElementById(element_counter-1) != null) {
if (confirm === false) {
confirm = true;
document.getElementById("removeLastItem").innerHTML = "Confirm";
} else {
document.getElementById("removeLastItem").innerHTML = "Remove last item";
var element = document.getElementById(element_counter-1);
element.parentNode.removeChild(element);
confirm = false;
element_counter--;
reloadPreview();
}
}
});
// Remove all with confirmation step on button press
var confirmRemoveAll = false;
document.getElementById("removeAll").addEventListener("click", function() {
// Ensure there is an object to remove and wait for confirmation
if (document.getElementById(element_counter-1) != null) {
if (confirmRemoveAll === false) {
confirmRemoveAll = true;
document.getElementById("removeAll").innerHTML = "Confirm";
} else {
document.getElementById("removeAll").innerHTML = "Remove all";
var element = document.getElementById("editor").innerHTML = ""
confirmRemoveAll = false;
element_counter = 0;
reloadPreview();
}
}
});
// Preview on button press
document.getElementById("previewButton").addEventListener("click", reloadPreview);
// Preview current document status
function reloadPreview() {
// Clear previous preview
document.getElementById("preview").innerHTML = "";
// Add elements iteratively
var section = document.getElementById("preview");
const id = "preview";
for (var counter = 0; counter < element_counter; counter++) {
var type = document.getElementById(counter).nodeName;
// If text element
if (type === "TEXTAREA") {
var paragraph = document.createElement("p");
var text = document.getElementById(counter).value;
var richtext = boldText(text);
paragraph.setAttribute("id", id + counter);
paragraph.setAttribute("class", "flow-text");
paragraph.innerHTML = richtext;
section.appendChild(paragraph);
}
// If image element
if (type === "INPUT") {
// This weird structure allows to render item by item into preview and not mix up the order as onload is otherwise too slow
(function() {
var file = document.getElementById(counter).files[0];
var reader = new FileReader();
var image = document.createElement("img");
image.setAttribute("id", id + counter);
image.setAttribute("class", "materialboxed responsive-img");
section.appendChild(image);
reader.onload = function(e) {
image.setAttribute("src", e.target.result);
}
reader.readAsDataURL(file);
}())
}
}
}
function boldText(text){
var bold = /\*\*(\S(.*?\S)?)\*\*/gm;
var richtext = text.replace(bold, '<b>$1</b>');
return richtext;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Climate Science</title>
<!--Used to unify web page appearance and this preview appearance-->
<link type="text/css" href="/css/materialize.css" rel="stylesheet">
<link type="text/css" href="/css/styles.css" rel="stylesheet">
<link type="text/css" href="/css/mystyles.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons&display=swap" rel="stylesheet">
<script href="text/javascript" src="/js/materialize.js"></script>
<link rel="manifest" href="/manifest.json">
<!-- IOS Support -->
<link rel="apple-touch-icon" href="/img/icons/icon-96x96.png">
<link rel="apple-touch-icon" href="/img/icons/icon-152x152.png">
<meta name="apple-mobile-web-app-status-bar" content="#5368ff">
<meta name="apple-mobile-web-app-status-bar-style" content="default">
<meta name="theme-color" content="#5368ff">
</head>
<body class="grey lighten-5">
<header>
<!-- top nav -->
<div class="navbar-fixed">
<nav class="z-depth-2">
<div class="nav-wrapper">
<ul id="nav-mobile" class="right hide-on-med-and-down">
<li>Log out</li> <!--TODO needed?-->
</ul>
</div>
</nav>
</div>
</header>
<div class="container">
<h3>Editor Area</h3>
<p><b>Linebreaks</b> within paragraphs are currently <b>ignored</b> to follow our internal database format.</p> <!--TODO check if accurate, \n possible integratable?-->
<!--
<h6>Safety switch</h6>
<div id="safetyswitch" class="switch">
<label>
Off
<input type="checkbox">
<span class="lever"></span>
On
</label>
</div>
<p>You can only remove paragraphs while the switch is deactivated!</p>
<h6>Auto-preview</h6>
<div id="safetyswitch" class="switch">
<label>
Off
<input type="checkbox">
<span class="lever"></span>
On
</label>
</div>
<p>The preview will load automatically while you edit your text</p>
<br>
-->
<button id="addParagraph" class="waves-effect waves-light btn">Add new paragraph</button>
<button id="addImage" class="waves-effect waves-light btn">Add new image</button>
<button id="removeLastItem" class="waves-effect waves-light btn">Remove last item</button>
<button id="removeAll" class="waves-effect waves-light btn">Remove all</button>
<div id="editor">
<!-- Here go all the content the author creates-->
</div>
<button id="previewButton" class="waves-effect waves-light btn">Update Preview</button>
<h3>Preview</h3>
<div id="preview">
<!-- Here will be the preview elements when clicking the button -->
<!--
<form action="#">
<p class="flow-text">What changes do you think we're already experiencing? Tap as many that apply</p>
<p>
<label>
<input type="checkbox" />
<span>Raising Sea Levels</span>
</label>
</p>
<p>
<label>
<input type="checkbox" />
<span>Fewer Heat Waves</span>
</label>
</p>
<p>
<label>
<input type="checkbox" />
<span>Worse Droughts</span>
</label>
</p>
<p>
<label>
<input type="checkbox" />
<span>Hotter heat waves</span>
</label>
</p>
<button class="btn waves-effect waves-light btn-large" type="submit" name="action">Submit
<i class="material-icons right">send</i>
</button>
</form>
-->
</div>
</div>
<script href="text/javascript" src="js/preview.js"></script>
<script href="text/javascript" src="js/ui.js"></script>
</body>
</html>
Hi so perhaps use innerHTML to insert HTML into the tag body? So instead of paragraph.append:
paragraph.innerHTML = richtext;

Categories