Instantiate ES6 class - javascript

I am trying to implement the following tags with my design.
I am using the class Tags to simply create tags within my input field, however when I initialize the library I get an error.
const ACTIVE_CLASS = "bg-light";
const VALUE_ATTRIBUTE = "data-value";
class Tags {
/**
* #param {HTMLSelectElement} selectElement
*/
constructor(selectElement) {
this.selectElement = selectElement;
this.selectElement.style.display = "none";
this.placeholder = this.getPlaceholder();
this.allowNew = selectElement.dataset.allowNew ? true : false;
// Create elements
this.holderElement = document.createElement("div");
this.containerElement = document.createElement("div");
this.dropElement = document.createElement("ul");
this.searchInput = document.createElement("input");
this.holderElement.appendChild(this.containerElement);
this.containerElement.appendChild(this.searchInput);
this.holderElement.appendChild(this.dropElement);
// insert after
this.selectElement.parentNode.insertBefore(this.holderElement, this.selectElement.nextSibling);
// Configure them
this.configureSearchInput();
this.configureHolderElement();
this.configureDropElement();
this.configureContainerElement();
this.buildSuggestions();
}
/**
* Attach to all elements matched by the selector
* #param {string} selector
*/
static init(selector = "select[multiple]") {
let list = document.querySelectorAll(selector);
for (let i = 0; i < list.length; i++) {
let el = list[i];
let inst = new Tags(el);
}
}
/**
* #returns {string}
*/
getPlaceholder() {
let firstOption = this.selectElement.querySelector("option");
if (!firstOption) {
return;
}
if (!firstOption.value) {
let placeholder = firstOption.innerText;
firstOption.remove();
return placeholder;
}
if (this.selectElement.getAttribute("placeholder")) {
return this.selectElement.getAttribute("placeholder");
}
if (this.selectElement.getAttribute("data-placeholder")) {
return this.selectElement.getAttribute("data-placeholder");
}
return "";
}
configureDropElement() {
this.dropElement.classList.add("dropdown-menu");
}
configureHolderElement() {
this.holderElement.classList.add("form-control");
this.holderElement.classList.add("dropdown");
}
configureContainerElement() {
this.containerElement.addEventListener("click", (event) => {
this.searchInput.focus();
});
// add initial values
let initialValues = this.selectElement.querySelectorAll("option[selected]");
for (let j = 0; j < initialValues.length; j++) {
let initialValue = initialValues[j];
if (!initialValue.value) {
continue;
}
this.addItem(initialValue.innerText, initialValue.value);
}
}
configureSearchInput() {
this.searchInput.type = "text";
this.searchInput.autocomplete = false;
this.searchInput.style.border = 0;
this.searchInput.style.outline = 0;
this.searchInput.style.maxWidth = "100%";
this.adjustWidth();
this.searchInput.addEventListener("input", (event) => {
this.adjustWidth();
if (this.searchInput.value.length >= 1) {
this.showSuggestions();
} else {
this.hideSuggestions();
}
});
// keypress doesn't send arrow keys
this.searchInput.addEventListener("keydown", (event) => {
if (event.code == "Enter") {
let selection = this.getActiveSelection();
if (selection) {
this.addItem(selection.innerText, selection.getAttribute(VALUE_ATTRIBUTE));
this.resetSearchInput();
this.hideSuggestions();
} else {
// We use what is typed
if (this.allowNew) {
this.addItem(this.searchInput.value);
this.resetSearchInput();
this.hideSuggestions();
}
}
event.preventDefault();
return;
}
if (event.code == "ArrowUp") {
this.moveSelectionUp();
}
if (event.code == "ArrowDown") {
this.moveSelectionDown();
}
if (event.code == "Backspace") {
if (this.searchInput.value.length == 0) {
this.removeLastItem();
this.adjustWidth();
}
}
});
}
moveSelectionUp() {
let active = this.getActiveSelection();
if (active) {
let prev = active.parentNode;
do {
prev = prev.previousSibling;
} while (prev && prev.style.display == "none");
if (!prev) {
return;
}
active.classList.remove(ACTIVE_CLASS);
prev.querySelector("a").classList.add(ACTIVE_CLASS);
}
}
moveSelectionDown() {
let active = this.getActiveSelection();
if (active) {
let next = active.parentNode;
do {
next = next.nextSibling;
} while (next && next.style.display == "none");
if (!next) {
return;
}
active.classList.remove(ACTIVE_CLASS);
next.querySelector("a").classList.add(ACTIVE_CLASS);
}
}
/**
* Adjust the field to fit its content
*/
adjustWidth() {
if (this.searchInput.value) {
this.searchInput.size = this.searchInput.value.length + 1;
} else {
// Show the placeholder only if empty
if (this.getSelectedValues().length) {
this.searchInput.placeholder = "";
this.searchInput.size = 1;
} else {
this.searchInput.size = this.placeholder.length;
this.searchInput.placeholder = this.placeholder;
}
}
}
/**
* Add suggestions from element
*/
buildSuggestions() {
let options = this.selectElement.querySelectorAll("option");
for (let i = 0; i < options.length; i++) {
let opt = options[i];
if (!opt.getAttribute("value")) {
continue;
}
let newChild = document.createElement("li");
let newChildLink = document.createElement("a");
newChild.append(newChildLink);
newChildLink.classList.add("dropdown-item");
newChildLink.setAttribute(VALUE_ATTRIBUTE, opt.getAttribute("value"));
newChildLink.setAttribute("href", "#");
newChildLink.innerText = opt.innerText;
this.dropElement.appendChild(newChild);
// Hover sets active item
newChildLink.addEventListener("mouseenter", (event) => {
this.removeActiveSelection();
newChild.querySelector("a").classList.add(ACTIVE_CLASS);
});
newChildLink.addEventListener("click", (event) => {
event.preventDefault();
this.addItem(newChildLink.innerText, newChildLink.getAttribute(VALUE_ATTRIBUTE));
this.resetSearchInput();
this.hideSuggestions();
});
}
}
resetSearchInput() {
this.searchInput.value = "";
this.adjustWidth();
}
/**
* #returns {array}
*/
getSelectedValues() {
let selected = this.selectElement.querySelectorAll("option:checked");
return Array.from(selected).map((el) => el.value);
}
/**
* The element create with buildSuggestions
*/
showSuggestions() {
if (!this.dropElement.classList.contains("show")) {
this.dropElement.classList.add("show");
}
// Position next to search input
this.dropElement.style.left = this.searchInput.offsetLeft + "px";
// Get search value
let search = this.searchInput.value.toLocaleLowerCase();
// Get current values
let values = this.getSelectedValues();
// Filter the list according to search string
let list = this.dropElement.querySelectorAll("li");
let found = false;
let firstItem = null;
for (let i = 0; i < list.length; i++) {
let item = list[i];
let text = item.innerText.toLocaleLowerCase();
let link = item.querySelector("a");
// Remove previous selection
link.classList.remove(ACTIVE_CLASS);
// Hide selected values
if (values.indexOf(link.getAttribute(VALUE_ATTRIBUTE)) != -1) {
item.style.display = "none";
continue;
}
if (text.indexOf(search) !== -1) {
item.style.display = "list-item";
found = true;
if (!firstItem) {
firstItem = item;
}
} else {
item.style.display = "none";
}
}
// Special case if nothing matches
if (!found) {
this.dropElement.classList.remove("show");
}
// Always select first item
if (firstItem) {
if (this.holderElement.classList.contains("is-invalid")) {
this.holderElement.classList.remove("is-invalid");
}
firstItem.querySelector("a").classList.add(ACTIVE_CLASS);
} else {
// No item and we don't allow new items => error
if (!this.allowNew) {
this.holderElement.classList.add("is-invalid");
}
}
}
/**
* The element create with buildSuggestions
*/
hideSuggestions(dropEl) {
if (this.dropElement.classList.contains("show")) {
this.dropElement.classList.remove("show");
}
if (this.holderElement.classList.contains("is-invalid")) {
this.holderElement.classList.remove("is-invalid");
}
}
/**
* #returns {HTMLElement}
*/
getActiveSelection() {
return this.dropElement.querySelector("a." + ACTIVE_CLASS);
}
removeActiveSelection() {
let selection = this.getActiveSelection();
if (selection) {
selection.classList.remove(ACTIVE_CLASS);
}
}
removeLastItem() {
let items = this.containerElement.querySelectorAll("span");
if (!items.length) {
return;
}
let lastItem = items[items.length - 1];
this.removeItem(lastItem.getAttribute(VALUE_ATTRIBUTE));
}
/**
* #param {string} text
* #param {string} value
*/
addItem(text, value) {
if (!value) {
value = text;
}
let span = document.createElement("span");
span.classList.add("badge");
span.classList.add("bg-primary");
span.classList.add("me-2");
span.setAttribute(VALUE_ATTRIBUTE, value);
span.innerText = text;
this.containerElement.insertBefore(span, this.searchInput);
// update select
let opt = this.selectElement.querySelector('option[value="' + value + '"]');
if (opt) {
opt.setAttribute("selected", "selected");
} else {
// we need to create a new option
opt = document.createElement("option");
opt.value = value;
opt.innerText = text;
opt.setAttribute("selected", "selected");
this.selectElement.appendChild(opt);
}
}
/**
* #param {string} value
*/
removeItem(value) {
let item = this.containerElement.querySelector("span[" + VALUE_ATTRIBUTE + '="' + value + '"]');
if (!item) {
return;
}
item.remove();
// update select
let opt = this.selectElement.querySelector('option[value="' + value + '"]');
if (opt) {
opt.removeAttribute("selected");
}
}
}
export default Tags;
import Tags
Tags.init();
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
<meta name="generator" content="Hugo 0.80.0">
<title>Insider</title>
<link rel="canonical" href="">
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons#1.4.0/font/bootstrap-icons.css">
<!-- Favicons -->
<link rel="apple-touch-icon" href="https://getbootstrap.com/docs/5.0/assets/img/favicons/apple-touch-icon.png" sizes="180x180">
<link rel="icon" href="https://getbootstrap.com/docs/5.0/assets/img/favicons/favicon-32x32.png" sizes="32x32" type="image/png">
<link rel="icon" href="https://getbootstrap.com/docs/5.0/assets/img/favicons/favicon-16x16.png" sizes="16x16" type="image/png">
<link rel="manifest" href="https://getbootstrap.com/docs/5.0/assets/img/favicons/manifest.json">
<link rel="mask-icon" href="https://getbootstrap.com/docs/5.0/assets/img/favicons/safari-pinned-tab.svg" color="#7952b3">
<link rel="icon" href="https://getbootstrap.com/docs/5.0/assets/img/favicons/favicon.ico">
<meta name="theme-color" content="#7952b3">
<!-- Custom styles for this template -->
<link href="https://unpkg.com/bootstrap-table#1.18.3/dist/bootstrap-table.min.css" rel="stylesheet">
</head>
<body>
<header class="p-3 bg-dark text-white">
<div class="container">
<div class="d-flex flex-wrap align-items-center justify-content-center justify-content-lg-start">
<ul class="nav col-12 col-lg-auto me-lg-auto mb-2 justify-content-center mb-md-0">
<li>
<button class="btn btn-outline-light" type="button" data-bs-toggle="modal" data-bs-target="#exampleModal">Check
</button>
</li>
</ul>
</div>
</div>
</header>
<main class="container pt-3">
<div class="row mt-3">
<h2>Content</h2>
</div>
</main>
<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Your Check</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<br>
<p class="h2">Check</p>
<p>Input your symbols and we will send you all relevant information.</p>
<br>
<form>
<div class="col">
<select class="form-select" id="validationTags" multiple="" data-allow-new="true" style="display: none;">
<option value="1" selected="selected">JavaScript</option>
<option value="2">HTML5</option>
<option value="3">CSS3</option>
<option value="4">jQuery</option>
<option value="5">React</option>
<option value="6">Angular</option>
<option value="7">Vue</option>
<option value="8">Python</option>
</select>
<div class="form-control dropdown">
<div><span class="badge bg-primary me-2" data-value="1">JavaScript</span><input type="text" autocomplete="false" placeholder="" size="1" style="border: 0px; outline: 0px; max-width: 100%;">
</div>
<ul class="dropdown-menu">
<li><a class="dropdown-item" data-value="1" href="#">JavaScript</a></li>
<li><a class="dropdown-item" data-value="2" href="#">HTML5</a></li>
<li><a class="dropdown-item" data-value="3" href="#">CSS3</a></li>
<li><a class="dropdown-item" data-value="4" href="#">jQuery</a></li>
<li><a class="dropdown-item" data-value="5" href="#">React</a></li>
<li><a class="dropdown-item" data-value="6" href="#">Angular</a></li>
<li><a class="dropdown-item" data-value="7" href="#">Vue</a></li>
<li><a class="dropdown-item" data-value="8" href="#">Python</a></li>
</ul>
</div>
<div class="invalid-feedback">Please select a valid tag.</div>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</div>
</div>
</div>
</div>
<!-- Modal END -->
<footer class="text-muted py-5">
<div class="container">
<p class="mb-1">Footer</p>
</div>
</footer>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
</body>
</html>
As you can see the script does not work.
To be honest I am not quite sure why. I am guessing there is a problem when initializing the Tags-class. I currently do it the following:
import Tags
Tags.init();
Any suggestions what is wrong or how to correctly call the init()-function from the Tags-class?
I appreciate your replies!

In my answer I'm assuming that your question is about how to import a class from a <script> to another <script> using ECMAScript modules, which is not very clear when reading your question.
You just have to specify type="module" on the exporting script and also the importing one, then import one file from the other with its URL.
For example if you have this web site structure:
app/
├─ lib/
│ ├─ tags.js
├─ index.js
├─ index.html
The tags.js file would contain:
class Tags {
// ...
}
export default Tags;
And index.js would contain:
import Tags from './lib/tags.js';
// ...
Here is a demo, I have used data URLs as a workaround because I can't publish JavaScript files in a StackOverflow snippet, but it works exactly the same with regular <script> tags and regular URLs:
const lib = `class Tags {
static init() {
console.log('it works!');
}
}
export default Tags;`;
const libURL = createScript(lib);
const code = `import Tags from '${libURL}';
Tags.init();`;
createScript(code);
function createScript(code) {
const url = `data:application/javascript;charset=utf-8;base64,${btoa(code)}`;
const script = document.createElement('script');
script.src = url;
script.type = 'module';
document.body.appendChild(script);
return url;
}

to initiate a es6 class you would use:
const new_object = new Tags(selectElement)
you pass selectElement into your constructor function and get a new object in return.
i don't know where you are calling this code from, if you want to call it from another file you need to define it in your export default.
this way you can use the es6 import syntax.

The error export declarations may only appear at top level of a module is already explained in #Guerric P's answer.
You are calling Tags.init(); from the same file as the definition, so if you really want that you can remove:
export default Tags;
import Tags
because it's a class definition and you are calling a static function:
Tags.init(); /* default 'select[multiple]' */
it will result in no error.

Related

Get the product that i click on [JS]

I want to be able to get the product that I click on. Right now I get the whole product array directly. Any tips or help?
This is what I get now when i press buy button: (GIF) https://gyazo.com/ea20d377adc802782dcf88079fd209b5
This is my JS code:
const shopContainer = document.querySelector(".shop-content");
let productTitle;
let productDescription;
let productImage;
let productPrice;
let productCategory;
let productId;
let productKey = [];
let productArray = [];
let output = "";
const url = "https://fakestoreapi.com/products";
let data = fetch(url)
.then((res) => res.json())
.then((data) => {
for (let i = 0; i < data.length; i++) {
productTitle = data[i].title;
productDescription = data[i].description;
productImage = data[i].image;
productPrice = data[i].price;
productCategory = data[i].category;
productId = data[i].id;
productArray[i] = [
productTitle,
productDescription,
productImage,
productPrice,
productCategory,
productId,
];
productKey[i] = data[i].id;
localStorage.setItem(productKey[i], JSON.stringify(productArray[i]));
}
showApi();
console.log(productArray)
});
console.log(localStorage)
function showApi() {
for (let i = 0; i < productArray.length; i++) {
output += `
<div class="product-box">
<img class="product" src="${productArray[i][2]}" alt="product image">
<h2 class="product-title">${productArray[i][0]}</h2>
<div class="bottom-box">
<span class="price">${productArray[i][3]}$</span>
<i class='bx bx-shopping-bag add-cart' id="${i}" onclick="returnKey()"></i>
</div>
</div>
`;
}
shopContainer.innerHTML = output;
console.log(productArray);
};
let knapp = document.getElementsByClassName("bx bx-shopping-bag");
console.log(knapp);
let inputCart = document.querySelector(".inputCart")
function returnKey() {
if (localStorage.length !== 0){
Object.keys(localStorage).forEach(function (key){
object = JSON.parse(localStorage.getItem(key))
completeProduct = (object)
let cartPrice = document.createElement("p");
let cartTitle = document.createElement("p");
let cartImage = document.createElement("img");
inputCart.appendChild(cartPrice);
inputCart.appendChild(cartImage);
inputCart.appendChild(cartTitle);
cartTitle.setAttribute("class", "cart-title")
cartImage.setAttribute("src", completeProduct[2]);
cartImage.setAttribute("width", "75");
cartImage.setAttribute("height", "75");
cartTitle.innerHTML = completeProduct[0];
cartPrice.innerHTML = ("$" + completeProduct[3]);
})
inputCart.innerHTML = cartTitle;
}
};
let removeBtn = document.getElementById("removebutton").addEventListener('click', clearCart);
let buyBtn = document.getElementById("buyBtn").addEventListener('click', buyCart);
function clearCart() {
removeCart = window.confirm("Are you sure you want to clear your cart?");
if (removeCart) {
inputCart.innerHTML = "";
}
}
function buyCart() {
shopMore = window.confirm("Are you finished shopping?");
if (shopMore) {
alert("Thank your for shopping at CatchShop!");
window.location.reload();
}
}
let cartIcon = document.querySelector("#cart-icon");
let cart = document.querySelector(".cart");
let closeCart = document.querySelector("#close-cart");
cartIcon.onclick = () => {
cart.classList.add("active");
};
closeCart.onclick = () => {
cart.classList.remove("active");
};
let filterBtn = document.querySelector("#filter-button");
let filterContainer = document.querySelector(".filter-container");
let closeFilter = document.querySelector("#close-filterbox");
filterBtn.onclick = () => {
filterContainer.classList.add("active");
};
closeFilter.onclick = () => {
filterContainer.classList.remove("active");
};
And this is my HTML:
<!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">
<link rel="stylesheet" href="assets/css/style.css">
<link href="https://fonts.googleapis.com/css2?family=Quicksand&family=Roboto&display=swap" rel="stylesheet">
<link href='https://unpkg.com/boxicons#2.1.4/css/boxicons.min.css' rel='stylesheet'>
<link rel="icon" href="./assets/images/android-chrome-192x192.png">
<title>CatchShop</title>
</head>
<body>
<header>
<div class="nav container">
CatchShop
Contact
About us
<i class='bx bxs-shopping-bag' id="cart-icon"></i>
<div class="cart">
<img class="companylogo" src="./assets/images/android-chrome-192x192.png" alt="logo">
<h2 class="yourcart">Your Cart</h2>
<i class='bx bx-x' id="close-cart"></i>
<div class="inputCart"></div>
<i class='bx bxs-trash-alt cart-remove' id="removebutton"></i>
<button type="button" class="btn-buy" id="buyBtn">Buy now</button>
</div>
</div>
</header>
<section class="shop container">
<div class="shop-content">
</div>
</section>
<div id="showCars"></div>
<footer>
<div class="companyname">
CatchShop
<img class="footerlogo" src="./assets/images/android-chrome-192x192.png" alt="logo">
</div>
<div class="social-media">
<i class='bx bxl-twitter' id="social-media-icon"></i>
<i class='bx bxl-facebook' id="social-media-icon"></i>
<i class='bx bxl-instagram' id="social-media-icon"></i>
</div>
</footer>
<script src="./assets/js/store.js"></script>
<script src="./assets/js/main.js"></script>
</body>
</html>
I've tried to add event.target.id with no sucess.
May be if i am not wrong then you have make mistake in below function:
function showApi() {
for (let i = 0; i < productArray.length; i++) {
output += `
<div class="product-box">
<img class="product" src="${productArray[i][2]}" alt="product image">
<h2 class="product-title">${productArray[i][0]}</h2>
<div class="bottom-box">
<span class="price">${productArray[i][3]}$</span>
<i class='bx bx-shopping-bag add-cart' id="${i}" onclick="returnKey(${productArray[i][3]})"></i>
</div>
</div>
`;
}
shopContainer.innerHTML = output;
console.log(productArray);
};
I have made change in above code for to pass productID in function returnKey
function returnKey(productID) {
if (localStorage.length !== 0){
let cartTitle = document.createElement("p");
Object.keys(localStorage).forEach(function (key){
object = JSON.parse(localStorage.getItem(key))
completeProduct = (object)
if(productID == completeProduct.productId){
let cartPrice = document.createElement("p");
let cartImage = document.createElement("img");
inputCart.appendChild(cartPrice);
inputCart.appendChild(cartImage);
inputCart.appendChild(cartTitle);
cartTitle.setAttribute("class", "cart-title")
cartImage.setAttribute("src", completeProduct[2]);
cartImage.setAttribute("width", "75");
cartImage.setAttribute("height", "75");
cartTitle.innerHTML = completeProduct[0];
cartPrice.innerHTML = ("$" + completeProduct[3]);
}
});
inputCart.innerHTML = cartTitle;
}
};
As per productId record get filter & showing one record which is clicked.

Function creates unwanted copy of an array as an element of itself

Basically, I have a function that creates N input fields based on user choice, then I want to get those inputs for processing later on, though for some reason it creates a copy of the return over and over again, unless I add something like "conj.pop()" in the return. I wouldn't like to work not knowing why it only works if I pop the last one.
I put a console.log to keep track and the returned array was something like this:
Array(3)
0: 'A'
1: 'B'
2: (3) ['A','B','Array(3)]
If you expand this last array it repeats infinitely this very same description.
OBS: The inputs I've been using were simple 2,2 and A B, C D.
OBS2: The code wasn't previously in english so I translated some stuff, and left other small ones as they were variables only.
document.getElementById("ok1").onclick = () => {
const esp_qtd = document.getElementById("esp_qtd").value;
const car_qtd = document.getElementById("car_qtd").value;
document.getElementById("parte1").classList.add("invisivel");
document.getElementById("parte2").classList.remove("invisivel");
console.log(esp_qtd, car_qtd);
const generateFields = (tipo) => {
const qtd = document.getElementById(tipo + "_qtd").value;
const parent = document.getElementById(tipo + "_lista");
for (let i = 0; i < qtd; i++) {
const input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("id", (tipo + i));
parent.appendChild(input);
if (qtd > 5) {
if (((i + 1) % 3) == 0) parent.appendChild(document.createElement("br"));
}
console.log(i);
}
}
generateFields("esp");
generateFields("car");
const inputFields = (tipo, conj) => {
const qtd = document.getElementById(tipo + "_qtd").value;
for (let i = 0; i < qtd; i++) {
conj[i] = document.getElementById(tipo + i).value;
console.log("Iteration: " + i, conj);
}
return conj;
}
document.getElementById("ok2").onclick = () => {
const conjE = [];
const conjC = [];
conjE.push(inputFields("esp", conjE));
conjC.push(inputFields("car", conjC));
console.log(conjE);
console.log(conjC);
}
}
* {
font-family: 'Roboto', sans-serif;
font-size: 14pt;
margin-top: 1rem;
}
.invisivel {
display: none;
}
label {
margin-top: 1rem;
}
input {
margin-top: 0.5rem;
margin-right: 1rem;
margin-bottom: 0.5rem;
}
button {
margin-top: 1rem;
}
<!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>DOC</title>
<link rel="stylesheet" href="style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- PART 1 -->
<div id="parte1">
<form>
<label>N1</label><br>
<input type="text" id="esp_qtd"><br>
<label>N2</label><br>
<input type="text" id="car_qtd"><br>
<button id="ok1" type="button">OK</button>
</form>
</div>
<!-- PART 2 -->
<div id="parte2" class="invisivel">
<div id="esp_lista">
<label>ELEMENTS 1</label><br>
</div>
<div id="car_lista">
<label>ELEMENTS 2</label><br>
</div>
<button id="ok2" type="button">OK</button>
</div>
</div>
<script src="index.js"></script>
</body>
</html>
Please change your JS as follows:
document.getElementById("ok1").onclick = () => {
const esp_qtd = document.getElementById("esp_qtd").value;
const car_qtd = document.getElementById("car_qtd").value;
document.getElementById("parte1").classList.add("invisivel");
document.getElementById("parte2").classList.remove("invisivel");
console.log(esp_qtd, car_qtd);
const generateFields = (tipo) => {
const qtd = document.getElementById(tipo + "_qtd").value;
const parent = document.getElementById(tipo + "_lista");
for (let i = 0; i < qtd; i++) {
const input = document.createElement("input");
input.setAttribute("type", "text");
input.setAttribute("id", tipo + i);
parent.appendChild(input);
if (qtd > 5) {
if ((i + 1) % 3 == 0) parent.appendChild(document.createElement("br"));
}
console.log(i);
}
};
generateFields("esp");
generateFields("car");
const inputFields = (tipo, conj) => {
const qtd = document.getElementById(tipo + "_qtd").value;
console.log("Conj:" + qtd);
for (let i = 0; i < qtd; i++) {
conj[i] = document.getElementById(tipo + i).value;
console.log("Iteration: " + i, conj);
}
return conj;
};
document.getElementById("ok2").onclick = () => {
const conjE = [];
const conjC = [];
inputFields("esp", conjE);
inputFields("car", conjC);
console.log(conjE);
console.log(conjC);
};
};
I have only removed conjE.push() and conjC.push().
Explanation:
You are passing an array to store your data in it. But you're also returning the same array and storing it in it again. This creates an infinite loop of values. Either pass the variable or return the list.

Filter active tasks, completed tasks, and all tasks in a to Do List with javascript

I am having some difficulty filtering through a list of tasks in To Do List project.
I use an object to store the core properties of each task created like the id, content, completed, and date.
The filter should occurs after the user selects an option in a drop down menu.
I use an Event Listener to catch the id of the option selected, but I don't know what to do with that Id. For example, when the user selects the option 'completed' the app should only display the completed task, or the tasks that have a property of 'completed:true'.
I also want to filter the list in a fancy way such as make tasks fade out when filtering.
URL: https://alonzocarlos95.github.io/WDD-330/
//html
<!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">
<!--ClockPicker libraries-->
<link rel="stylesheet" href="https://weareoutman.github.io/clockpicker/dist/jquery-clockpicker.min.css"></link>
<!-- <script src="http://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Moment JS library CDN -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.25.1/moment.min.js"></script> -->
<!--Material Icons and Fonts-->
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght#0,200;1,100&display=swap" rel="stylesheet">
<!--Small view-->
<link rel="stylesheet" href="css/small.css" media="screen">
<title>Document</title>
</head>
<body>
<header>
<nav>
<ul>
<li><span class="material-icons">done</span></li>
<li class="drop-down" ><div class="dropdown"><button class="dropbtn" onclick="showModal()">All Lists<span class="material-icons" style="vertical-align: middle;">arrow_drop_down</span></button><div id="myDropdown" class="dropdown-content"><span id="select1">All Lists</span><span id="select2">Active</span><span id="select3">Completed</span></div></div></li>
<li><span class="label_list">BYU-Idaho To do List</span></li>
<li><span class="material-icons">search</span></li>
<li><img src="images/b2-removebg-preview.png" alt="logo"></li>
</ul>
</nav>
</header>
<main>
<div class="notes">
<img id="no_tasks" src="images/palms-300x220.png" alt="No tasks">
</div>
<div class="main_list" id="main_list">
<ul id="parentList">
</ul>
</div>
<div class="new_task_container" id="container_schedule">
<div class="new_task" id="new_todo">
<label>What is to be done?</label>
<div class="new_input">
<input type="text" name="todo" id="todo" placeholder="Enter task here">
<span class="material-icons">keyboard_voice</span>
</div>
<label>Due Date</label>
<input type="date" id="date" name="date" placeholder="Date not set">
</div>
<div class="new_task_group2">
<div class="new_time" id="new_time_container">
<input type="text" name="time" id="time" placeholder="Time not set(all day)">
<span class="material-icons">schedule</span>
<!-- <input type="checkbox" style="display: none;"> -->
</div>
</div>
</div>
</main>
<div class="add_task">
<button id="add" class="bounce">+</button>
</div>
<script src="https://weareoutman.github.io/clockpicker/dist/jquery-clockpicker.min.js"></script>
<script src="js/todo.js"></script>
</body>
</html>
//Javacript
let toDoList = [];
let options = {weekday:'long', year:'numeric', month:'long', day:'numeric'};
let indicador = 0;
let list_container = document.getElementById('main_list');
document.getElementById('container_schedule').style.display = 'none';
const chosenDate = document.getElementById("date");
const time = document.getElementById('new_time_container');
let ulTasks = document.getElementById('parentList');
time.style.display = 'none';
document.getElementById('add').addEventListener('click', () => {
document.getElementById('container_schedule').style.display = 'block';
document.getElementById('add').innerHTML = '<span class="material-icons">done</span>';
let inputNewTask = document.getElementById("todo");
let valInputNewTask = inputNewTask.value;
let valInputNewTask2 = inputNewTask.value;
let dateSet = document.getElementById('date').value;
if(indicador === 0){
indicador = 1;
list_container.style.display = "none";
}else {
if(!isBlank(valInputNewTask)){ //Valida si el valor del input no es null o undefined o whitespace
indicador = 0;
inputNewTask.value = "";
inputNewTask.focus();
let newDateSet = valDate(dateSet);
taskCreated();
manageTask(valInputNewTask2,newDateSet);
}
else {
alert("Enter task at first.");
}
}
} );
document.getElementById('date').addEventListener('change',() => {
// alert("New date");
time.style.display = 'flex';
});
function taskCreated(){
document.getElementById('container_schedule').style.display = 'none';
// debugger;
if(document.getElementsByClassName('notes').length >= 1){
document.getElementsByClassName('notes')[0].remove();
}
document.getElementById('add').textContent = '+';
}
/*Clock picker functionality*/
$("input[name=time]").clockpicker({
placement: 'bottom',
align: 'left',
autoclose: true,
default: 'now',
donetext: "Select",
init: function() {
console.log("colorpicker initiated");
},
beforeShow: function() {
console.log("before show");
},
afterShow: function() {
console.log("after show");
},
beforeHide: function() {
console.log("before hide");
},
afterHide: function() {
console.log("after hide");
},
beforeHourSelect: function() {
console.log("before hour selected");
},
afterHourSelect: function() {
console.log("after hour selected");
},
beforeDone: function() {
console.log("before done");
},
afterDone: function() {
console.log("after done");
}
});
function isBlank(str) {
//debugger;
return (!str || /^\s*$/.test(str));
}
function valDate(dateToDo){
// debugger;
if(dateToDo === null || dateToDo === ''){
dateToDo = "No date";
return dateToDo;
}
else {
dateToDo = new Date(dateToDo);
dateToDo.setDate(dateToDo.getDate()+1);
// testDate = new Date(Date.UTC(dateToDo));
dateToDo = dateToDo.toLocaleString('en-US',options);
return dateToDo;
}
}
function manageTask(getTask,dateSet){
const todo = {
id: Date.now(),
content: getTask,
completed: false,
date: dateSet
}
toDoList.push(todo);
addToLocalStorage(toDoList);
// storeData(todo);
}
function addToLocalStorage(toDoList){
// debugger;
localStorage.setItem('toDoList',JSON.stringify(toDoList));
renderTodos(toDoList);
}
function renderTodos(toDoList){
// debugger;
ulTasks.innerHTML = '';
toDoList.forEach(function(valInputNewTask2,index){
console.log(index);
const checked = toDoList.completed ? 'checked': null;
let currentTasks = document.createElement('li');
currentTasks.id = valInputNewTask2.id;
currentTasks.setAttribute('style','display:flex;background-color:#519872;width:100%;border-radius:7px;margin:0 0 10px 0;padding:6px 4px 6px 4px;min-height:3em;box-shadow: rgba(14, 30, 37, 0.12) 0px 2px 4px 0px, rgba(14, 30, 37, 0.32) 0px 2px 16px 0px;');
currentTasks.innerHTML = '<input id='+index+' type = "checkbox" class="checkInactive"><div style="display:flex;flex-direction:column;flex-grow:2;"><span style="margin-left:2em;">'+valInputNewTask2.content+'</span><span style="margin-left:2em;color:#17301C;">'+valInputNewTask2.date+'</span></div><div class="clear"><span class="material-icons">clear</span></div>';
if(valInputNewTask2.completed === true){
currentTasks.classList.add('checkActive');
currentTasks.firstChild.checked = true;
}
document.getElementById('parentList').appendChild(currentTasks);
});
list_container.style.display = "block";
}
function getFromLocalStorage(){
const getReference = localStorage.getItem('toDoList');
if(getReference){
document.querySelector('.notes').style.display = 'none';
toDoList = JSON.parse(getReference);
renderTodos(toDoList);
}
}
function showModal(){
document.getElementById('myDropdown').classList.toggle('show');
}
getFromLocalStorage();
function toggle(id){
toDoList.forEach(function(item){
if(item.id == id){
item.completed = !item.completed;
}
});
addToLocalStorage(toDoList);
}
function deleteToDo(id){
debugger
// alert(id);
toDoList = toDoList.filter(function(getTask){
return getTask.id != id;
});
addToLocalStorage(toDoList);
}
debugger;
ulTasks.addEventListener('click',function(event){
debugger;
if(event.target.type === 'checkbox'){
toggle(event.target.parentElement.getAttribute('id'));
}
if(event.target.parentElement.classList.contains('clear')){
debugger;
deleteToDo(event.target.parentElement.parentElement.getAttribute('id'));
}
});
//Close the dropdown if the user clicks outside it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementById("myDropdown");
if (myDropdown.classList.contains('show')) {
myDropdown.classList.remove('show');
}
}
}
//Drop down Events
document.getElementById("myDropdown").addEventListener('click',function(event){
debugger;
if(event.target.localName === 'span'){
alert(event.target.id);
}
});
I don't know about the animations but at least for the filtering:
Ideally you should be using the select html element to create a dropdown menu and use the value attribute of the option elements to perform actions when an option is selected. Read more here: https://www.w3schools.com/tags/tag_select.asp
In your case, we can use the text inside the span tag, instead of the id to see which option was selected and render the todos based on the selected option.
We can then use the JS ES6 array function .filter(item => condition), which loops over the items in the array and returns a new array with all the items that match the provided condition.
document.getElementById('myDropdown').addEventListener('click', function(event) {
if (e.target.localName === 'span'){
let selectedOption = e.target.innerText;
if(selectedOption === 'All Tasks')
renderToDos(toDoList); // render everything
else if(selectedOption === 'Active'){
let activeToDos = toDoList.filter(todo => todo.completed === false);
renderToDos(activeToDos); // only render the todos which have not been completed
}
else if(selectedOption === 'Completed'){
let completedToDos = toDoList.filter(todo => todo.completed === true);
renderToDos(completedToDos); // only render the todos which have not been completed
}
}
});

How would I edit a specific list item from an unordered list from a modal pop up text field

I believe using this might be the best way to go about this. Although I admittedly don't fully understand how to use this outside of an object literal.
Basically I would like modalControls.editModal() to change the text node within the specific li.list-group-item that was clicked (specifically the <i class="fa fa-pencil-square-o float-right"></i> that was clicked).
I am able to return the proper text mode in the console, but if I have more then one li.list-group-item in the document it always returns the first one.
You can see the html and javascript below, and the working code here: http://gfitzpatrickportfolio.com/practice/
HTML:
<!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>Bootstrap + Javascript List</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css"
integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb"
crossorigin="anonymous" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN"
crossorigin="anonymous">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<div class="input-group">
<input type="text" class="rounded form-control" id="myInput" />
<span id="myButton" class="input-group-addon bg-info text-white" onClick="listActions.addItem()">ADD</span>
</div>
<ul class="list-group" id="myOutput">
</ul>
</div> <!-- .containter -->
<!--modal-->
<div id="outter-modal">
<div id="modal-content" class="input-group bg-white col-lg-4 col-sm-6 col-10">
<input type="text" class="rounded form-control" id="editInput" />
<span id="editBtn" class="input-group-addon bg-info text-white" onClick="listActions.editItem()">EDIT</span>
</div>
</div>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"
integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN"
crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"
integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh"
crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"
integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ"
crossorigin="anonymous"></script>
<script src="app.js"></script>
</body>
</html>
Javascript:
let myOutput = document.getElementById('myOutput');
let myInput = document.getElementById('myInput');
let listGroupItems = document.querySelectorAll('.list-group-item');
let modalContainer = document.getElementById('outter-modal');
let editInput = document.getElementById('editInput');
let listActions = {
addItem: function() {
if (myInput.value === '') {
console.log('Field is empty!');
} else {
let li = document.createElement('li');
let inputValue = document.createTextNode(myInput.value);
li.innerHTML = '<i class="fa fa-times-circle-o float-right" aria-hidden="true" onClick="listActions.removeItem(this)"></i> <i class="fa fa-pencil-square-o float-right" aria-hidden="true" onClick="modalControls.editModal(this)"></i>';
li.className = 'list-group-item';
myOutput.appendChild(li);
li.appendChild(inputValue);
}
myInput.value = '';
},
editItem: function() {
let li = document.querySelector('.list-group-item');
console.log(li.childNodes[3])
console.log(editInput.value);
editInput.value = '';
},
toggleItem: function(e) {
let selectedItem = e.target;
let checkMark = document.createElement('i');
checkMark.classList.add('fa', 'fa-check-circle', 'float-left');
if (selectedItem.classList.contains('bg-success') && selectedItem.classList.contains('list-group-item')) {
selectedItem.classList.remove('bg-success');
selectedItem.classList.remove('text-white');
let iconIndex = '';
for (let i = 0; i < selectedItem.childNodes.length; i++) {
if (selectedItem.childNodes[i].className === "fa fa-check-circle float-left") {
iconIndex = i;
}
}
selectedItem.removeChild(selectedItem.childNodes[iconIndex]);
} else if (!selectedItem.classList.contains('bg-success') && selectedItem.classList.contains('list-group-item')) {
selectedItem.classList.add('bg-success');
selectedItem.classList.add('text-white');
selectedItem.appendChild(checkMark);
}
},
removeItem: function(deleteBtn) {
//when the <i> tag is created for the X button (inside the addItem function) the onClick property passes in (this). The parameter of removeItem (item) is = to (this)
deleteBtn.parentNode.remove();
}
};
// function addItem() {
// if (myInput.value === '') {
// console.log('Field is empty!');
// } else {
// let li = document.createElement('li');
// let inputValue = document.createTextNode(myInput.value);
//
// li.innerHTML = '<i class="fa fa-times-circle-o float-right" aria-hidden="true" onClick="removeItem(this)"></i> <i class="fa fa-pencil-square-o float-right" aria-hidden="true" onClick="modalControls.editModal(this)"></i>';
// li.className = 'list-group-item';
// myOutput.appendChild(li);
// li.appendChild(inputValue);
// }
// myInput.value = '';
// }
// function editItem(item) {
// console.log(item);
// }
// function toggleItem(e) {
// let selectedItem = e.target;
// let checkMark = document.createElement('i');
// checkMark.classList.add('fa', 'fa-check-circle', 'float-left');
//
//
// if (selectedItem.classList.contains('bg-success') && selectedItem.classList.contains('list-group-item')) {
// selectedItem.classList.remove('bg-success');
// selectedItem.classList.remove('text-white');
// let iconIndex = '';
//
// for (let i = 0; i < selectedItem.childNodes.length; i++) {
// if (selectedItem.childNodes[i].className === "fa fa-check-circle float-left") {
// iconIndex = i;
// }
// }
// selectedItem.removeChild(selectedItem.childNodes[iconIndex]);
// } else if (!selectedItem.classList.contains('bg-success') && selectedItem.classList.contains('list-group-item')) {
// selectedItem.classList.add('bg-success');
// selectedItem.classList.add('text-white');
// selectedItem.appendChild(checkMark);
// }
// }
// function removeItem(deleteBtn) {
// //when the <i> tag is created for the X button (inside the addItem function) the onClick property passes in (this). The parameter of removeItem (item) is = to (this)
// deleteBtn.parentNode.remove();
// }
let modalControls = {
editModal: function() {
modalContainer.style.display = 'block';
},
closeModal: function(e) {
if(e.target === modalContainer) {
modalContainer.style.display = 'none';
}
}
};
myOutput.addEventListener('click', listActions.toggleItem);
modalContainer.addEventListener('click', modalControls.closeModal);
One way would be to store the current list item in a global variable. Something like...
var currentListItem;
let listActions = {
// ...
editItem: function () {
if (currentListItem) {
// I believe this will change only the text and not its descendant nodes (unsure)
currentListItem.nodeValue = editInput.value;
}
// ...
},
// ...
}
let modalControls = {
// when you open the modal, set the current list item
editModal: function (btn) {
currentListItem = btn.parentNode;
// ...
},
// when you close, unset the current list item
closeModal: function (e) {
currentListItem = null;
// ...
}
};
Another way can be to mark the current list item (e.g. by like adding a class edit) upon opening the modal. Upon saving i.e. editItem, you search for the <li> element with class edit using document.getSelector('li.edit'), modify it, and remove the class.
So, basically, you need to store the <li> element being edited and you can do it with the parentElement property of the element being passed to modalControls.editModal, and then, in listActions.editItem replace the value.
let currentElement; // Element being edited
let listActions = {
editItem: function() {
currentElement.innerHTML = currentElement.innerHTML.replace(currentElement.innerText, editInput.value);
editInput.value = '';
}
}
let modalControls = {
editModal: function(i) {
// *i* is *this* in *modalControls.editModal(this)*
modalContainer.style.display = 'block';
currentElement = i.parentElement;
modalContainer.getElementsByTagName('input')[0].value = currentElement.innerText;
}
}

Only one of two practically identical JavaScript functions being run

I'm probably being very stupid here...
I have two JavaScript functions that are practically identical except each one refers to a different element.
The idea is to show and hide a toast/notification when the document loads.
For one element (errorexplanationcontainer), it works... For the other (alert), it doesn't...
CODE FOR errorexplanationcontainer (WORKS)
<div id="errorexplanationcontainer" class=""></div>
<script type="text/javascript">
window.onload = function() {
var z = document.getElementById("errorexplanationcontainer")
z.className = "show";
setTimeout(function(){ z.className = z.className.replace("show", ""); }, 3000);
}
</script>
^^ This is copied and pasted from the inspect window within Google Chrome. As you can see, the script ran successfully. We know this because class="" is absent in the source document and has been added by the script (after showing class="show" for 3 seconds).
CODE FOR alert (DOESN'T WORK)
<p id="alert">Invalid Email or password.</p>
<script type="text/javascript">
window.onload = function() {
var y = document.getElementById("alert")
y.className = "show";
setTimeout(function(){ y.className = y.className.replace("show", ""); }, 3000);
}
</script>
^^ No class="" here! The script has not worked...
FULL HTML DOC
<html class="mdl-js"><head>
<title>Dennis' Coffee Hut | CuppaDesk</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="/assets/favicon-16x16-347e46971826b54de74f354ae410242483f471bb3051a5f948d83af70770dadc.png" sizes="16x16">
<link rel="icon" type="image/png" href="/assets/favicon-32x32-ac516884b2aa2ea870ddfbd0ae383c0dd66ec1a640181174ac7adaba8e7ccd7d.png" sizes="32x32">
<link rel="apple-touch-icon" type="image/x-icon" href="/assets/apple-touch-icon-af3f73bee131a689a15fede0d2d6f7cf9698786524670279ac74cd128ec5dc40.png" sizes="180x180">
<link rel="mask-icon" type="image/x-icon" href="/assets/safari-pinned-tab-4f97411db829aebf4a4796a8f216e788ba4eeddf4d062a0a1efe473ee10fce3b.svg" color="#99cc33">
<link rel="icon" type="image/png" href="/assets/android-chrome-192x192-cb0ced957daf2743c293b898f5e595fcf07fc0842b9d0aeef37c08b8c5f74d42.png" sizes="192x192">
<link rel="manifest" href="/manifest.json">
<meta name="apple-mobile-web-app-title" content="CuppaDesk">
<meta name="application-name" content="CuppaDesk">
<meta name="msapplication-TileColor" content="#99cc33">
<meta name="msapplication-TileImage" content="/assets/mstile-144x144-5de954b6d137b31283af01b9a7645c90440392de2b44ec88949fdba65cca75e7.png">
<meta name="theme-color" content="#99cc33">
<meta name="csrf-param" content="authenticity_token">
<meta name="csrf-token" content="wphb5Z8aebicMl6E2CiCJiNPnQowqP2TVUrXOWclCukQwiX/xrbLf3jBE4YRyyswVMEaPEszTO/7xxl1/iClsw==">
<link rel="stylesheet" media="all" href="/assets/main.self-b06bcba5344c9fc9a5c6491a38f0780f4594d723339bc0543a25138d83fe3de3.css?body=1" data-turbolinks-track="reload">
<link rel="stylesheet" media="all" href="/assets/places.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload">
<link rel="stylesheet" media="all" href="/assets/scaffolds.self-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.css?body=1" data-turbolinks-track="reload">
<link rel="stylesheet" media="all" href="/assets/application.self-f0d704deea029cf000697e2c0181ec173a1b474645466ed843eb5ee7bb215794.css?body=1" data-turbolinks-track="reload">
<script src="/assets/rails-ujs.self-56055fe2ac3f3902deb9d12c17b2d725d432162b48fc443946daf7dfbc96d88a.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/action_cable.self-be3674a79bb9d13d41d259b2c17fad23aef20946dab3603b9d02374ea795005f.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/cable.self-8484513823f404ed0c0f039f75243bfdede7af7919dda65f2e66391252443ce9.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/places.self-877aef30ae1b040ab8a3aba4e3e309a11d7f2612f44dde450b5c157aa5f95c05.js?body=1" data-turbolinks-track="reload"></script>
<script src="/assets/application.self-eba3cb53a585a0960ade5a8cb94253892706bb20e3f12097a13463b1f12a4528.js?body=1" data-turbolinks-track="reload"></script>
<!-- BEGIN MATERIAL DESIGN LITE -->
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<!-- <link rel="stylesheet" href="/material.min.css"> -->
<script defer="" src="https://code.getmdl.io/1.3.0/material.min.js"></script>
<!-- END MATERIAL DESIGN LITE -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body>
<p id="alert">Invalid Email or password.</p>
<script type="text/javascript">
window.onload = function() {
var y = document.getElementById("alert")
y.className = "show";
setTimeout(function(){ y.className = y.className.replace("show", ""); }, 3000);
}
</script>
<div id="login-container">
<div id="cuppadesk-logo-large"></div>
<div id="card-white">
<h1>Log in</h1>
<div class="dropdown-dots">
<button onclick="dotsDropdown()" class="dropbtn-dots"></button>
<div id="dotsDropdown" class="dropdown-content">
<a href="/users/sign_up">
<div class="dropdown-content-item">Sign up</div>
</a>
<a href="/users/password/new">
<div class="dropdown-content-item">Forgot password</div>
</a>
<a href="/users/confirmation/new">
<div class="dropdown-content-item">Didn't recieve email confirmation</div>
</a>
<a href="/users/unlock/new">
<div class="dropdown-content-item">Didn't receive unlock instructions</div>
</a>
<a href="/users/auth/facebook">
<div class="dropdown-content-item">Log in with
Facebook
</div>
</a>
</div>
</div>
<script>
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function dotsDropdown() {
document.getElementById("dotsDropdown").classList.toggle("show-dots");
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
if (!event.target.matches('.dropbtn-dots')) {
var dropdowns = document.getElementsByClassName("dropdown-content");
var i;
for (i = 0; i < dropdowns.length; i++) {
var openDropdown = dropdowns[i];
if (openDropdown.classList.contains('show-dots')) {
openDropdown.classList.remove('show-dots');
}
}
}
}
</script>
<form class="new_user" id="new_user" action="/users/sign_in" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="authenticity_token" value="wphb5Z8aebicMl6E2CiCJiNPnQowqP2TVUrXOWclCukQwiX/xrbLf3jBE4YRyyswVMEaPEszTO/7xxl1/iClsw==">
<div id="errorexplanationcontainer" class=""></div>
<script type="text/javascript">
window.onload = function() {
var z = document.getElementById("errorexplanationcontainer")
z.className = "show";
setTimeout(function(){ z.className = z.className.replace("show", ""); }, 3000);
}
</script>
<div class="field-white">
<input autofocus="autofocus" placeholder="Email" type="email" value="" name="user[email]" id="user_email">
</div>
<div class="field-white">
<input autocomplete="off" placeholder="Password" type="password" name="user[password]" id="user_password">
</div>
<div class="checkbox">
<input name="user[remember_me]" type="hidden" value="0"><input class="css-checkbox" type="checkbox" value="1" name="user[remember_me]" id="user_remember_me">
<label class="css-label clr" for="user_remember_me">Remember me</label>
</div>
<script>
// generic tools to help with the custom checkbox
function UTIL() { }
UTIL.prototype.bind_onclick = function(o, f) { // chain object onclick event to preserve prior statements (like jquery bind)
var prev = o.onclick;
if (typeof o.onclick != 'function') o.onclick = f;
else o.onclick = function() { if (prev) { prev(); } f(); };
};
UTIL.prototype.bind_onload = function(f) { // chain window onload event to preserve prior statements (like jquery bind)
var prev = window.onload;
if (typeof window.onload != 'function') window.onload = f;
else window.onload = function() { if (prev) { prev(); } f(); };
};
// generic css class style match functions similar to jquery
UTIL.prototype.trim = function(h) {
return h.replace(/^\s+|\s+$/g,'');
};
UTIL.prototype.sregex = function(n) {
return new RegExp('(?:^|\\s+)' + n + '(?:\\s+|$)');
};
UTIL.prototype.hasClass = function(o, n) {
var r = this.sregex(n);
return r.test(o.className);
};
UTIL.prototype.addClass = function(o, n) {
if (!this.hasClass(o, n))
o.className = this.trim(o.className + ' ' + n);
};
UTIL.prototype.removeClass = function(o, n) {
var r = this.sregex(n);
o.className = o.className.replace(r, '');
o.className = this.trim(o.className);
};
var U = new UTIL();
function getElementsByClassSpecial(node, classname) {
var a = [];
var re = new RegExp('(^| )'+classname+'( |$)');
var els = node.getElementsByTagName("*");
for(var i=0,j=els.length; i<j; i++)
if(re.test(els[i].className))a.push(els[i]);
return a;
}
// specific to customized checkbox
function chk_labels(obj, init) {
var objs = document.getElementsByTagName('LABEL');
for (var i = 0; i < objs.length; i++) {
if (objs[i].htmlFor == obj.id) {
if (!init) { // cycle through each label belonging to checkbox
if (!U.hasClass(objs[i], 'chk')) { // adjust class of label to checked style, set checked
if (obj.type.toLowerCase() == 'radio') {
var radGroup = objs[i].className;
var res = radGroup.split(" ");
var newRes = res[0] + " " + res[1];
var relLabels = getElementsByClassSpecial(document.body,newRes);
for (var r = 0; r < relLabels.length; r++) {
U.removeClass(relLabels[r], 'chk');
U.addClass(relLabels[r], 'clr');
}
U.removeClass(objs[i], 'clr');
U.addClass(objs[i], 'chk');
obj.checked = true;
}
else {
U.removeClass(objs[i], 'clr');
U.addClass(objs[i], 'chk');
obj.checked = true;
}
} else { // adjust class of label to unchecked style, clear checked
U.removeClass(objs[i], 'chk');
U.addClass(objs[i], 'clr');
obj.checked = false;
}
return true;
} else { // initialize on page load
if (obj.checked) { // adjust class of label to checked style
U.removeClass(objs[i], 'clr');
U.addClass(objs[i], 'chk');
} else { // adjust class of label to unchecked style
U.removeClass(objs[i], 'chk');
U.addClass(objs[i], 'clr')
}
}
}
}
}
function chk_events(init) {
var objs = document.getElementsByTagName('INPUT');
if (typeof init == 'undefined') init = false;
else init = init ? true : false;
for(var i = 0; i < objs.length; i++) {
if (objs[i].type.toLowerCase() == 'checkbox' || objs[i].type.toLowerCase() == 'radio' ) {
if (!init) {
U.bind_onclick(objs[i], function() {
chk_labels(this, init); // bind checkbox click event handler
});
}
else chk_labels(objs[i], init); // initialize state of checkbox onload
}
}
}
U.bind_onload(function() { // bind window onload event
chk_events(false); // bind click event handler to all checkboxes
chk_events(true); // initialize
});
</script>
<div class="green-submit">
<input type="submit" name="commit" value="Log in" data-disable-with="Log in">
</div>
</form>
</div>
</div>
</body></html>
Again, I'm probably missing something obvious here... I'm completely new to developing and JavaScript is something I particularly struggle with. I've read through many resources but in my mind, the code still looks correct...
Obviously, I'm wrong... So any help will be greatly appreciated!
Use window.addEventListener instead of overwriting window.onload.
For errorexplanationcontainer,
<div id="errorexplanationcontainer" class=""></div>
<script type="text/javascript">
window.addEventListener("load", function() {
var z = document.getElementById("errorexplanationcontainer");
z.className = "show";
setTimeout(function() {
z.className = z.className.replace("show", "");
}, 3000);
}, false);
</script>
For alert,
<p id="alert">Invalid Email or password.</p>
<script type="text/javascript">
window.addEventListener("load", function() {
var y = document.getElementById("alert")
y.className = "show";
setTimeout(function() {
y.className = y.className.replace("show", "");
}, 3000);
}, false);
</script>

Categories