Generate and Download Screenshot of webpage without lossing the styles - javascript

I want to Generate and Download Screenshot of webpage without lossing the styles. I have a web page .In that web page i have a download button . When user click on download button then the screen shot of entire Page need to download as image in user computer . How can i do this ?
Please check my code
Index.html
<html>
<body>
<link href="style.css" rel="stylesheet">
<h1>Scrrenshot</h1>
<form class="cf">
<div class="half left cf">
<input type="text" id="input-name" placeholder="Name">
<input type="email" id="input-email" placeholder="Email address">
<input type="text" id="input-subject" placeholder="Subject">
</div>
<div class="half right cf">
<textarea name="message" type="text" id="input-message" placeholder="Message"></textarea>
</div>
<input type="submit" value="Submit" id="input-submit">
</form>
<a class="btn btn-success" href="javascript:void(0);" onclick="generate();">Generate Screenshot »</a>
</body>
<script>
(function (exports) {
function urlsToAbsolute(nodeList) {
if (!nodeList.length) {
return [];
}
var attrName = 'href';
if (nodeList[0].__proto__ === HTMLImageElement.prototype
|| nodeList[0].__proto__ === HTMLScriptElement.prototype) {
attrName = 'src';
}
nodeList = [].map.call(nodeList, function (el, i) {
var attr = el.getAttribute(attrName);
if (!attr) {
return;
}
var absURL = /^(https?|data):/i.test(attr);
if (absURL) {
return el;
} else {
return el;
}
});
return nodeList;
}
function screenshotPage() {
urlsToAbsolute(document.images);
urlsToAbsolute(document.querySelectorAll("link[rel='stylesheet']"));
var screenshot = document.documentElement.cloneNode(true);
var b = document.createElement('base');
b.href = document.location.protocol + '//' + location.host;
var head = screenshot.querySelector('head');
head.insertBefore(b, head.firstChild);
screenshot.style.pointerEvents = 'none';
screenshot.style.overflow = 'hidden';
screenshot.style.webkitUserSelect = 'none';
screenshot.style.mozUserSelect = 'none';
screenshot.style.msUserSelect = 'none';
screenshot.style.oUserSelect = 'none';
screenshot.style.userSelect = 'none';
screenshot.dataset.scrollX = window.scrollX;
screenshot.dataset.scrollY = window.scrollY;
var script = document.createElement('script');
script.textContent = '(' + addOnPageLoad_.toString() + ')();';
screenshot.querySelector('body').appendChild(script);
var blob = new Blob([screenshot.outerHTML], {
type: 'text/html'
});
return blob;
}
function addOnPageLoad_() {
window.addEventListener('DOMContentLoaded', function (e) {
var scrollX = document.documentElement.dataset.scrollX || 0;
var scrollY = document.documentElement.dataset.scrollY || 0;
window.scrollTo(scrollX, scrollY);
});
}
function generate() {
window.URL = window.URL || window.webkitURL;
window.open(window.URL.createObjectURL(screenshotPage()));
}
exports.screenshotPage = screenshotPage;
exports.generate = generate;
})(window);
</script>
</html>
style.css
#import "compass/css3";
#import url(https://fonts.googleapis.com/css?family=Merriweather);
$red: #e74c3c;
*,
*:before,
*:after {
#include box-sizing(border-box);
}
html, body {
background: #f1f1f1;
font-family: 'Merriweather', sans-serif;
padding: 1em;
}
h1 {
text-align: center;
color: #a8a8a8;
#include text-shadow(1px 1px 0 rgba(white, 1));
}
form {
border: 2px solid blue;
margin: 20px auto;
max-width: 600px;
padding: 5px;
text-align: center;
}
input, textarea {
border:0; outline:0;
padding: 1em;
#include border-radius(8px);
display: block;
width: 100%;
margin-top: 1em;
font-family: 'Merriweather', sans-serif;
#include box-shadow(0 1px 1px rgba(black, 0.1));
resize: none;
&:focus {
#include box-shadow(0 0px 2px rgba($red, 1)!important);
}
}
#input-submit {
color: white;
background: $red;
cursor: pointer;
&:hover {
#include box-shadow(0 1px 1px 1px rgba(#aaa, 0.6));
}
}
textarea {
height: 126px;
}
}
.half {
float: left;
width: 48%;
margin-bottom: 1em;
}
.right { width: 50%; }
.left {
margin-right: 2%;
}
#media (max-width: 480px) {
.half {
width: 100%;
float: none;
margin-bottom: 0;
}
}
/* Clearfix */
.cf:before,
.cf:after {
content: " "; /* 1 */
display: table; /* 2 */
}
.cf:after {
clear: both;
}
.half.left.cf > input {
margin: 5px;
}
For this i used the method [http://www.xpertdeveloper.com/2012/10/webpage-screenshot-with-html5-js/] , here screenshot is generated but without style also it is not downloading . Please help , is there any jQuery library available for this?

You can achieve this using the following JavaScript libraries ...
html2canvas ( for taking screenshot of webpage )
FileSave.js ( for downloading the screenshot as an image )
ᴅᴇᴍᴏ
(function(exports) {
function urlsToAbsolute(nodeList) {
if (!nodeList.length) {
return [];
}
var attrName = 'href';
if (nodeList[0].__proto__ === HTMLImageElement.prototype || nodeList[0].__proto__ === HTMLScriptElement.prototype) {
attrName = 'src';
}
nodeList = [].map.call(nodeList, function(el, i) {
var attr = el.getAttribute(attrName);
if (!attr) {
return;
}
var absURL = /^(https?|data):/i.test(attr);
if (absURL) {
return el;
} else {
return el;
}
});
return nodeList;
}
function screenshotPage() {
var wrapper = document.getElementById('wrapper');
html2canvas(wrapper, {
onrendered: function(canvas) {
canvas.toBlob(function(blob) {
saveAs(blob, 'myScreenshot.png');
});
}
});
}
function addOnPageLoad_() {
window.addEventListener('DOMContentLoaded', function(e) {
var scrollX = document.documentElement.dataset.scrollX || 0;
var scrollY = document.documentElement.dataset.scrollY || 0;
window.scrollTo(scrollX, scrollY);
});
}
function generate() {
screenshotPage();
}
exports.screenshotPage = screenshotPage;
exports.generate = generate;
})(window);
#import url(https://fonts.googleapis.com/css?family=Merriweather);
$red: #e74c3c;
*,
*:before,
*:after {
#include box-sizing(border-box);
}
html,
body {
background: #f1f1f1;
font-family: 'Merriweather', sans-serif;
padding: 1em;
}
h1 {
text-align: center;
color: #a8a8a8;
#include text-shadow(1px 1px 0 rgba(white, 1));
}
form {
border: 2px solid blue;
margin: 20px auto;
max-width: 600px;
padding: 5px;
text-align: center;
}
input,
textarea {
border: 0;
outline: 0;
padding: 1em;
#include border-radius(8px);
display: block;
width: 100%;
margin-top: 1em;
font-family: 'Merriweather', sans-serif;
#include box-shadow(0 1px 1px rgba(black, 0.1));
resize: none;
&:focus {
#include box-shadow(0 0px 2px rgba($red, 1)!important);
}
}
#input-submit {
color: white;
background: $red;
cursor: pointer;
&:hover {
#include box-shadow(0 1px 1px 1px rgba(#aaa, 0.6));
}
}
textarea {
height: 126px;
}
}
.half {
float: left;
width: 48%;
margin-bottom: 1em;
}
.right {
width: 50%;
}
.left {
margin-right: 2%;
}
#media (max-width: 480px) {
.half {
width: 100%;
float: none;
margin-bottom: 0;
}
}
/* Clearfix */
.cf:before,
.cf:after {
content: " ";
/* 1 */
display: table;
/* 2 */
}
.cf:after {
clear: both;
}
.half.left.cf > input {
margin: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.4.1/html2canvas.min.js"></script>
<div id="wrapper">
<h1>Scrrenshot</h1>
<form class="cf">
<div class="half left cf">
<input type="text" id="input-name" placeholder="Name">
<input type="email" id="input-email" placeholder="Email address">
<input type="text" id="input-subject" placeholder="Subject">
</div>
<div class="half right cf">
<textarea name="message" type="text" id="input-message" placeholder="Message"></textarea>
</div>
<input type="submit" value="Submit" id="input-submit">
</form>
</div>
<a class="btn btn-success" href="javascript:void(0);" onclick="generate();">Generate Screenshot »</a>

I found that dom-to-image did a much better job than html2canvas. See the following question & answer: https://stackoverflow.com/a/32776834/207981
If you're looking to download the image(s) you'll want to combine it with FileSaver.js (already mentioned here), and if you want to download a zip with multiple image files all generated client-side take a look at jszip.

Few options for this
either use this
<html>
<head>
<title> Download-Button </title>
</head>
<body>
<p> Click the image ! You can download! </p>
<a download="logo.png" href="http://localhost/folder/img/logo.png" title="Logo title">
<img alt="logo" src="http://localhost/folder/img/logo.png">
</a>
</body>
</html>
or You can use Mordernizr
or maybe this works
<a href="/path/to/image" download>
<img src="/path/to/image" />
</a>
refer to this link aswell
[1] http://www.w3schools.com/tags/att_a_download.asp

Related

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

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

when adding a new item the functionality of the previous item changes

const addBtn = document.querySelector(".add");
const modal = document.querySelector(".modal__container");
const library = document.querySelector(".library__container");
const submitBook = document.querySelector(".add__book");
const deleteBtn = document.querySelector(".fas fa-trash-alt");
//Modal inputs
const modalTitle = document.querySelector("#title");
const modalAuthor = document.querySelector("#author");
const modalPages = document.querySelector("#pages");
const isRead = document.querySelector("#read-status");
//Toggle Modal
const hideModal = () => {
modal.style.display = "none";
};
const showModal = () => {
modal.style.display = "block";
const cancel = document.querySelector(".cancel");
cancel.addEventListener("click", (e) => {
e.preventDefault();
hideModal();
});
};
addBtn.addEventListener("click", showModal);
let myLibrary = [];
let index = 0;
function Book(title, author, pages, read) {
this.title = title,
this.author = author,
this.pages = pages,
this.read = read
}
submitBook.addEventListener("click", addBookToLibrary);
function addBookToLibrary(e) {
e.preventDefault();
let bookTitle = modalTitle.value;
let bookAuthor = modalAuthor.value;
let bookPages = modalPages.value;
let bookStatus = isRead.checked;
//Display error message if inputs are empty
if (bookTitle === "" || bookAuthor === "" || bookPages === "") {
const errorMessage = document.querySelector(".error__message--container");
hideModal();
errorMessage.style.display = "block";
const errorBtn = document.querySelector(".error-btn");
errorBtn.addEventListener("click", () => {
errorMessage.style.display = "none";
showModal();
})
} else {
let book = new Book(bookTitle, bookAuthor, bookPages, bookStatus);
myLibrary.push(book);
hideModal();
render();
}
}
function render() {
library.innerHTML = "";
for (let i = 0; i < myLibrary.length; i++) {
library.innerHTML +=
'<div class="book__container">' +
'<div class="book">' +
'<div class="title__content">' +
'<span class="main">Title : </span><span class="book__title">' +` ${myLibrary[i].title}`+'</span>' +
'</div>' +
'<div class="author__content">' +
'<span class="main">Author : </span><span class="book__author">'+` ${myLibrary[i].author}`+'</span>' +
'</div>' +
'<div class="pages__content">' +
'<span class="main">Pages : </span><span class="book__pages">'+` ${myLibrary[i].pages}`+'</span>' +
'</div>' +
'<div class="book__read-elements">' +
'<span class="book__read">I read it</span>' +
'<i class="fas fa-check"></i>' +
'<a href="#"><i class="fas fa-times"></i>' +
'<i class="fas fa-trash-alt"></i>' +
'</div>' +
'</div>' +
'</div>'
readStatus(myLibrary[i].checked)
}
modalTitle.value = "";
modalAuthor.value = "";
modalPages.value = "";
isRead.checked = false;
}
function readStatus(bookStatus) {
const bookStatusContainer = document.querySelector(".book__read");
if (bookStatus) {
bookStatusContainer.classList.add("yes");
bookStatusContainer.textContent = "I read it";
bookStatusContainer.style.color = "rgb(110, 176, 120)";
} else {
bookStatusContainer.classList.add("no");
bookStatusContainer.textContent = "I have not read it";
bookStatusContainer.style.color = "rgb(194, 89, 89)";
}
}
#import url('https://fonts.googleapis.com/css2?family=Poppins:wght#300;400;600&display=swap');
:root {
--light-gray: #dededef3;
--title-color: #333756;
--main-color: #c6c6c6f3;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
body {
font-family: 'Poppins', sans-serif;
background-color: var(--light-gray);
}
header {
text-align: center;
padding-top: 4rem;
color: var(--title-color);
text-transform: uppercase;
letter-spacing: 4px;
}
button {
margin: 1rem;
padding: 0.8rem 2rem;
font-size: 14px;
border-radius: 25px;
background: white;
color: #333756;
font-weight: 600;
border: none;
cursor: pointer;
transition: 0.6s all ease;
}
:focus {
/*outline: 1px solid white;*/
}
button:hover {
background: var(--title-color);
color: white;
}
.add__book:hover,
.cancel:hover {
background: var(--main-color);
color: var(--title-color)
}
.all,
.books__read,
.books__not-read {
border-radius: 0;
text-transform: uppercase;
letter-spacing: 0.1rem;
background: var(--light-gray);
border-bottom: 4px solid var(--title-color)
}
.library__container {
display: flex;
justify-content: center;
flex-wrap: wrap;
}
.book__container {
display: flex;
margin: 2rem 2rem;
}
.modal__container {
display: none;
position: fixed;
z-index: 4;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
padding-top: 0px;
}
.book,
.modal {
padding: 2rem 2rem;
border-radius: 15px;
background: #333756;
line-height: 3rem;
}
.modal {
position: relative;
width: 50%;
margin: 0 auto;
margin-top: 8rem;
}
.modal__content {
display: flex;
flex-direction: column;
}
label {
color: white;
margin-right: 1rem;
}
input {
padding: 0.5rem;
font-size: 14px;
}
.book__read-elements {
display: flex;
justify-content: space-between;
}
.main,
i {
color: white;
pointer-events: none;
margin: 0.5rem;
}
.book__title,
.book__author,
.book__pages,
.book__read {
color: var(--main-color)
}
.error__message--container {
display: none;
position: fixed;
z-index: 4;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.4);
}
.error__message--modal {
position: relative;
margin: 0 auto;
margin-top: 10rem;
width:40%;
}
.error {
display: flex;
flex-direction: column;
align-items: center;
color: rgb(101, 3, 3);
font-size: 20px;
font-weight: bold;
background: rgb(189, 96, 96);
padding: 3rem 5rem;
border-radius: 10px;
}
.error-btn {
color: rgb(101, 3, 3);
font-weight: bold;
}
.error-btn:hover {
color: white;
background: rgb(101, 3, 3);
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/css/all.min.css" integrity="sha256-2XFplPlrFClt0bIdPgpz8H7ojnk10H69xRqd9+uTShA=" crossorigin="anonymous" />
<link rel="stylesheet" href="styles.css">
<title>Library</title>
</head>
<body>
<header>
<h1>My Library</h1>
<button class="add">Add New Book</button>
<div class="buttons">
<button class="all">View All</button>
<button class="books__read">Read</button>
<button class="books__not-read">Not Read</button>
</div>
</header>
<div class="error__message--container">
<div class="error__message--modal">
<div class="error">
<p>Complete the form!</p>
<button class ="error-btn">Ok</button>
</div>
</div>
</div>
<!--Modal-->
<form class="modal__container">
<div class="modal">
<div class="modal__content">
<label for="">Title:</label>
<input type="text" id="title">
</div>
<div class="modal__content">
<label for="">Author:</label>
<input type="text" id="author">
</div>
<div class="modal__content">
<label for="">Pages:</label>
<input type="number" id="pages">
</div>
<div>
<label for="read-status">Check the box if you've read this book</label>
<input type="checkbox" id="read-status" value ="check">
</div>
<button class="add__book">Add</button>
<button class="cancel">Cancel</button>
</div>
</form>
<!--End of Modal-->
<div class="library__container"></div>
<script src="script.js"></script>
</body>
</html>
I'm new to OOP and I'm struggling.
I'm building a library where you can add a book with the title, author nr of pages and if you've read it or not. When I add the first book if I check the box it displays that to book is not read(which is false). When I add a new book the read functionality is not applied to that book at all. I have no idea how to fix it
In this function you are checking the status if isRead which is incorrect.
Do this
Call the readStatus function inside the for loop
Pass the current parameter readStatus(myLibrary[i].checked)
Modify readStatus as shown below
function readStatus(status) {
const bookReadStatus = document.querySelector(".book__read");
if (status) {
bookReadStatus.classList.add("yes");
bookReadStatus.textContent = "I read it";
bookReadStatus.style.color = "rgb(110, 176, 120)";
} else {
bookReadStatus.classList.add("no");
bookReadStatus.textContent = "I have not read it";
bookReadStatus.style.color = "rgb(194, 89, 89)";
}
}

Adding a square root function to a calc using js

So, I made a calculator, and I want to add a square root function, but I know there is no already made function that finds the square root of numbers. So what elements can I combine to find the square root of a number?
const screen = document.querySelector("#screen");
const clearButton = document.querySelector("#clear");
const equalsButton = document.querySelector("#equals");
const decimalButton = document.querySelector("#decimal");
let isFloat = false;
let signOn = false;
let firstNumber = "";
let operator = "";
let secondNumber = "";
let result = "";
const allClear = () => {
isFloat = false;
signOn = false;
firstNumber = "";
operator = "";
secondNumber = "";
result = "";
screen.value = "0";
};
const calculate = () => {
if (operator && result === "" && ![" ", "+", "-", "."].includes(screen.value[screen.value.length - 1])) {
secondNumber = screen.value.substring(firstNumber.length + 3);
switch (operator) {
case "+":
result = Number((Number(firstNumber) + Number(secondNumber)).toFixed(3));
break;
case "-":
result = Number((Number(firstNumber) - Number(secondNumber)).toFixed(3));
break;
case "*":
result = Number((Number(firstNumber) * Number(secondNumber)).toFixed(3));
break;
case "/":
result = Number((Number(firstNumber) / Number(secondNumber)).toFixed(3));
break;
default:
}
screen.value = result;
}
};
clear.addEventListener("click", allClear);
document.querySelectorAll(".number").forEach((numberButton) => {
numberButton.addEventListener("click", () => {
if (screen.value === "0") {
screen.value = numberButton.textContent;
} else if ([" 0", "+0", "-0"].includes(screen.value.substring(screen.value.length - 2))
&& numberButton.textContent === "0") {
} else if ([" 0", "+0", "-0"].includes(screen.value.substring(screen.value.length - 2))
&& numberButton.textContent !== "0") {
screen.value = screen.value.substring(0, screen.value.length - 1) + numberButton.textContent;
} else if (result || result === 0) {
allClear();
screen.value = numberButton.textContent;
} else {
screen.value += numberButton.textContent;
}
});
});
decimalButton.addEventListener("click", () => {
if (result || result === 0) {
allClear();
isFloat = true;
screen.value += ".";
} else if (!isFloat) {
isFloat = true;
if ([" ", "+", "-"].includes(screen.value[screen.value.length - 1])) {
screen.value += "0.";
} else {
screen.value += ".";
}
}
});
document.querySelectorAll(".operator").forEach((operatorButton) => {
operatorButton.addEventListener("click", () => {
if (result || result === 0) {
isFloat = false;
signOn = false;
firstNumber = String(result);
operator = operatorButton.dataset.operator;
result = "";
screen.value = `${firstNumber} ${operatorButton.textContent} `;
} else if (operator && ![" ", "+", "-", "."].includes(screen.value[screen.value.length - 1])) {
calculate();
isFloat = false;
signOn = false;
firstNumber = String(result);
operator = operatorButton.dataset.operator;
result = "";
screen.value = `${firstNumber} ${operatorButton.textContent} `;
} else if (!operator) {
isFloat = false;
firstNumber = screen.value;
operator = operatorButton.dataset.operator;
screen.value += ` ${operatorButton.textContent} `;
} else if (!signOn
&& !["*", "/"].includes(operatorButton.dataset.operator)
&& screen.value[screen.value.length - 1] === " ") {
signOn = true;
screen.value += operatorButton.textContent;
}
});
});
equalsButton.addEventListener("click", calculate);
* {
box-sizing: border-box;
font-family: 'Roboto', sans-serif;
font-weight: 300;
margin: 0;
padding: 0;
}
body {
background-color: #222;
height: 100vh;
}
header {
background-color: #333;
padding: 40px 0;
}
header h1 {
-webkit-background-clip: text;
background-clip: text;
background-image: linear-gradient(to right bottom, #fff, #777);
color: transparent;
font-size: 40px;
letter-spacing: 2px;
text-align: center;
text-transform: uppercase;
}
main {
background-color: #222;
display: flex;
justify-content: center;
padding: 60px 0;
}
main #container {
background-color: #333;
box-shadow: 0 5px 5px #111;
padding: 20px;
}
.clearfix:after {
clear: both;
content: " ";
display: block;
font-size: 0;
height: 0;
visibility: hidden;
}
#container .row:not(:last-child) {
margin-bottom: 9px;
}
#container input,
#container button {
float: left;
}
#container input:focus,
#container button:focus {
outline: none;
}
#container input {
background-color: #222;
border: 1px solid #999;
border-right-width: 0;
color: #999;
font-size: 22px;
font-weight: 300;
height: 80px;
padding-right: 14px;
text-align: right;
width: 261px;
}
#container button {
background-color: #222;
border: none;
box-shadow: 0 3px 0 #111;
color: #999;
font-size: 20px;
height: 80px;
margin-right: 7px;
width: 80px;
}
#container button:active {
box-shadow: 0 2px 0 #111;
transform: translateY(1px);
}
#container #clear,
#container .operator,
#container #equals {
color: #111;
}
#container #clear,
#container .operator {
margin-right: 0;
}
#container #clear {
background-color: #e95a4b;
border: 1px solid #999;
border-left-width: 0;
box-shadow: none;
cursor: pointer;
}
#container #clear:active {
box-shadow: none;
transform: none;
}
#container .operator {
background-color: #999;
box-shadow: 0 3px 0 #555;
}
#container .operator:active {
box-shadow: 0 2px 0 #555;
}
#container #equals {
background-color: #2ecc71;
box-shadow: 0 3px 0 #155d34;
}
#container #equals:active {
box-shadow: 0 2px 0 #155d34;
}
#media only screen and (max-width: 400px) {
header {
padding: 28px 0;
}
header h1 {
font-size: 36px;
}
main {
padding: 40px 0;
}
main #container {
padding: 16px;
}
#container .row:not(:last-child) {
margin-bottom: 7px;
}
#container input {
font-size: 18px;
height: 60px;
padding-right: 10px;
width: 195px;
}
#container button {
font-size: 16px;
height: 60px;
margin-right: 5px;
width: 60px;
}
}
<!DOCTYPE html>
<html lang="en">
<head>
<title>Calculator</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://fonts.googleapis.com/css?family=Roboto:300" rel="stylesheet">
<link href="Project 1.css" rel="stylesheet">
</head>
<body>
<header>
<h1>Calculator</h1>
</header>
<main>
<div id="container">
<div class="row clearfix">
<input id="screen" value="0" disabled type="text">
<button id="clear">AC</button>
</div>
<div class="row clearfix">
<button class="number">1</button>
<button class="number">2</button>
<button class="number">3</button>
<button data-operator="+" class="operator">+</button>
</div>
<div class="row clearfix">
<button class="number">4</button>
<button class="number">5</button>
<button class="number">6</button>
<button data-operator="-" class="operator">-</button>
</div>
<div class="row clearfix">
<button class="number">7</button>
<button class="number">8</button>
<button class="number">9</button>
<button data-operator="*" class="operator">×</button>
</div>
<div class="row clearfix">
<button id="decimal">.</button>
<button class="number">0</button>
<button id="equals">=</button>
<button data-operator="/" class="operator">÷</button>
</div>
</div>
</main>
<script src="Project 1.js"></script>
</body>
</html>
This is the code for the calc.. Feel free to edit it and explain to me what you did.
There is already one.
The Math.sqrt() function returns the square root of a number, that is, ∀x≥0,Math.sqrt(x)=x
=the uniquey≥0such thaty2=x
MDN Docs
You can use javascript built in
Math.sqrt(number)

Disable NVDA from reading 'clickable' for series highchart

How can I prevent NVDA screen reader from reading 'clickable' for series Highcharts? The series values are wrapped inside a "tspan" tag and don't have any click event associated with it. Thanks for the help in advance.
Adding a 2nd screenshot (I'll attach a fiddle once I figure it out) in response to Graham Ritchie's comment.
window.EJ = window.EJ || {},
EJ.features = EJ.features || {};
EJ.events = {};
(function(q) {
'use strict';
var topics = {},
subUid = -1;
q.subscribe = function(topic, func) {
if (!topics[topic]) {
topics[topic] = [];
}
var token = (++subUid).toString();
topics[topic].push({
token: token,
func: func
});
return token;
};
q.publish = function(topic, args) {
if (!topics[topic]) {
return false;
}
setTimeout(function() {
var subscribers = topics[topic],
len = subscribers ? subscribers.length : 0;
while (len--) {
subscribers[len].func(topic, args);
}
}, 0);
return true;
};
q.unsubscribe = function(token) {
for (var m in topics) {
if (topics[m]) {
for (var i = 0, j = topics[m].length; i < j; i++) {
if (topics[m][i].token === token) {
topics[m].splice(i, 1);
return token;
}
}
}
}
return false;
};
}(EJ.events));
/**
* Features loader
* Iterates over all data-features attributes in the DOM and will execute EJ.features.featureName.init()
*/
EJ.features = {
init: function() {
var features = $('[data-features]');
if (!features.length) return false;
for (var i = 0, n = features.length; i < n; i++) {
var $el = $(features[i]),
func = $el.data('features');
if (this[func] && typeof this[func].init === 'function') {
this[func].init($el);
}
}
}
};
EJ.features.careerFitTool = (function(quiz) {
quiz.init = function(el) {
if (!el) {
throw new Error('You must supply the constructor an element instance to operate on.');
}
var currQuestionIndex = -1,
$start = el.find('.quiz-start'),
$finish = el.find('.quiz-finish'),
$startOver = el.find('.quiz-startOver'),
$previousQuestion = el.find('.previous-question'),
$nextQuestion = el.find('.next-question'),
$stateDefault = el.find('.state-default'),
$stateActive = el.find('.state-quiz'),
$questions = el.find('.question-field'),
$progressIndicator = el.find('.progress-indicator'),
numOfQuestions = $questions.length
$answers = el.find('.answer');
var faPct = 0;
var boaPct = 0;
var hqPct = 0;
$previousQuestion.on('click', function() {
changeQuestion('prev');
});
$nextQuestion.on('click', function() {
changeQuestion('next');
});
$start.on('click', function() {
changeState('default', 'quiz');
});
$finish.on('click', function() {
changeState('quiz', 'finished');
});
$startOver.on('click', function() {
changeState('finished', 'default');
currQuestionIndex = -1;
$(el).find('form')[0].reset();
focusLetsGetStarted();
});
$answers.on('change', function() {
$nextQuestion.removeClass('disabled')
.attr('disabled', false);
})
/**
* Change state of quiz.
* #param {string} currState Current state (default/quiz/finished)
* #param {string} nextState Desired next state (default/quiz/finished)
*/
function changeState(currState, nextState) {
el.find('.state-' + currState).hide();
el.find('.state-' + nextState).show();
if (currState === 'default') {
$previousQuestion.hide();
$($questions[++currQuestionIndex]).show();
$($progressIndicator[currQuestionIndex]).addClass('active');
}
}
function computeJobFitPercents() {
var faAmount = 0;
var boaAmount = 0;
var hqAmount = 0;
var totalOptionAmount = 0;
var faPercent = 0;
var boaPercent = 0;
var hqPercent = 0;
for (var i = 1; i <= 45; i++) {
var radios = document.getElementsByName('group' + i);
for (var j = 0; j < radios.length; j++) {
var radio = radios[j];
var radioString = radio.value;
if (radioString.indexOf("Financial Advisor") >= 0 && radio.checked) {
faAmount++;
}
if (radioString.indexOf("Branch Office Administrator") >= 0 && radio.checked) {
boaAmount++;
}
if (radioString.indexOf("Headquarters") >= 0 && radio.checked) {
hqAmount++;
}
}
totalOptionAmount = faAmount + boaAmount + hqAmount;
faPercent = parseFloat(((faAmount / totalOptionAmount) * 100).toFixed());
boaPercent = parseFloat(((boaAmount / totalOptionAmount) * 100).toFixed());
hqPercent = parseFloat(((hqAmount / totalOptionAmount) * 100).toFixed());
var totalPercent = faPercent + boaPercent + hqPercent;
}
generatePieChart(faPercent, boaPercent, hqPercent);
// Populate the variables required to display the result
faPct = faPercent;
boaPct = boaPercent;
hqPct = hqPercent;
}
/**
* This function generates pie chart for the given inputs.
* It generates a job fir graph for the questions answered by the user.
*/
function generatePieChart(faPrcnt, boaPrcnt, hqPrcnt) {
Highcharts.setOptions({
colors: ['#F3BD06', '#f6d050 ', '#fae49b']
});
// Build the chart
$('#pieChartContainer').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
width: 230
},
credits: {
enabled: false
},
title: {
text: null
},
scrollbar : {
enabled : false
},
tooltip: {
enabled: false,
pointFormat: '<b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: false,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true,
borderWidth: 0,
point: {
events: {
mouseOver: function() {
//pieChart.tooltip.hide();
}
}
}
}
},
exporting: {
enabled: false
},
legend: {
layout: 'vertical',
floating: false,
borderRadius: 0,
borderWidth: 0,
align: 'center',
verticalAlign: 'bottom',
labelFormatter: function() {
return this.y + '%' + ' ' + '-' + this.name;
}
},
series: [{
type: 'pie',
name: 'Career Chart',
point: {
events: {
legendItemClick: function() {
return false;
}
}
},
data: [
['Financial Advisor', faPrcnt],
['Branch Office Administrator', boaPrcnt], {
name: 'Headquarters',
y: hqPrcnt,
sliced: false,
selected: false
}
]
}]
});
}
/**
* Go to previous or next question
* #param {string} direction 'next' or 'prev'
* #return {boolean} are we on first or last question?
*/
function changeQuestion(direction) {
//Call function to compute the job fit percent as per the answers selected by the user
//computeJobFitPercents();
var questionAnswers;
var isAnswered;
$($questions[currQuestionIndex]).hide();
$progressIndicator.removeClass('active');
if (direction === 'next') {
currQuestionIndex++;
} else {
currQuestionIndex--;
}
$($progressIndicator[currQuestionIndex]).addClass('active');
questionAnswers = $($questions[currQuestionIndex]).find('.answer');
for (var i = 0, j = questionAnswers.length; i < j; i++) {
if ($(questionAnswers[i]).prop('checked') === true) {
isAnswered = true;
}
}
if (isAnswered) {
$nextQuestion.removeClass('disabled')
.attr('disabled', false);
} else {
$nextQuestion.addClass('disabled')
.attr('disabled', true);
}
if (currQuestionIndex === -1) {
$($questions[currQuestionIndex]).hide();
changeState('quiz', 'default');
} else if (currQuestionIndex === numOfQuestions) {
//Call function to compute the job fit percent as per the answers selected by the user
computeJobFitPercents();
$($questions[currQuestionIndex]).hide();
changeState('quiz', 'finished');
//Determine the result
$('#faOutcome').hide();
$('#faResultLink').hide();
$('#boaOutcome').hide();
$('#boaResultLink').hide()
$('#hqOutcome').hide();
$('#hqResultLink').hide();
if (faPct >= boaPct) {
if (faPct >= hqPct) {
$('#faOutcome').show();
$('#faResultLink').show();
} else {
$('#hqOutcome').show();
$('#hqResultLink').show();
}
} else if (boaPct >= hqPct) {
$('#boaOutcome').show();
$('#boaResultLink').show();
} else {
$('#hqOutcome').show();
$('#hqResultLink').show();
}
} else {
$($questions[currQuestionIndex]).show();
if (currQuestionIndex === 0) {
$previousQuestion.hide();
} else {
$previousQuestion.show();
}
}
return currQuestionIndex === numOfQuestions || currQuestionIndex === 0;
}
}
return quiz;
}(EJ.features.careerFitTool || {}));
EJ.initialize = function() {
EJ.features.init();
};
$(function() {
EJ.initialize();
$('.comp-registrationForm.modal').modal('show');
});
/* Enter Your Custom CSS Here */
input[type="checkbox"],input[type="radio"] {
box-sizing: border-box;
padding: 0;
margin: 4px 0 0;
margin-top: 1px \9;
/* IE8-9 */
line-height: normal;
position: relative;
opacity: 1;
left: 0;
}
input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus {
outline: thin dotted #333 !important;
outline-offset: -2px !important;
outline-color: #000 !important;
}
.radio,.checkbox {
display: block;
min-height: 20px;
margin-top: 10px;
margin-bottom: 10px;
padding-left: 20px;
vertical-align: middle;
}
.radio label,.checkbox label {
display: inline;
margin-bottom: 0;
font-weight: 400;
cursor: pointer;
}
.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"] {
float: left;
margin-left: -20px;
}
.radio + .radio,.checkbox + .checkbox {
margin-top: -5px;
}
.radio-inline,.checkbox-inline {
display: inline-block;
padding-left: 20px;
margin-bottom: 0;
vertical-align: middle;
font-weight: 400;
cursor: pointer;
}
.radio-inline + .radio-inline,.checkbox-inline + .checkbox-inline {
margin-top: 0;
margin-left: 10px;
}
input[type="radio"][disabled],fieldset[disabled] input[type="radio"],input[type="checkbox"][disabled],fieldset[disabled] input[type="checkbox"],.radio[disabled],fieldset[disabled] .radio,.radio-inline[disabled],fieldset[disabled] .radio-inline,.checkbox[disabled],fieldset[disabled] .checkbox,.checkbox-inline[disabled],fieldset[disabled] .checkbox-inline {
cursor: not-allowed;
}
/*
# Button Primary
*/
.button,.button-cta,.button-cta-floating,.button-previous,.button-download,.button-expand,.button-arrow-only {
color: #fff;
background-color: #f8512e;
border-color: #f96141;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2),inset 0 1px 1px rgba(255,255,255,0.15);
box-shadow: 0 1px 2px rgba(0,0,0,0.2),inset 0 1px 1px rgba(255,255,255,0.15);
-webkit-transition: background-color .25s ease-out;
transition: background-color .25s ease-out;
font-family: "Proxima Nova-Semibold",Helvetica,Arial,sans-serif;
font-weight: 400;
font-size: 15px;
line-height: 1;
padding: 8px 12px;
text-shadow: 0 1px 1px rgba(0,0,0,0.2);
}
.pull-right {
float: right !important;
}
.hide {
display: none !important;
}
.hidden {
display: none !important;
visibility: hidden !important;
}
/* start .comp-careerFitTool */
.comp-careerFitTool {
background: #9b9998;
padding-bottom: 15px;
position: relative;
}
.comp-careerFitTool:before,.comp-careerFitTool:after {
content: " ";
/* 1 */
display: table;
/* 2 */
}
.comp-careerFitTool:after {
clear: both;
}
#media screen and (min-width: 470px) {
.comp-careerFitTool {
padding-bottom: 35px;
}
}
.career-tool-intro {
color: #fff;
font-size: 20px;
padding: 20px;
}
#media screen and (min-width: 960px) {
.career-tool-intro h3 {
font-size: 32px;
}
}
.career-tool-intro p {
margin: 0;
}
#media screen and (min-width: 470px) {
.career-tool-intro {
padding: 25px;
}
}
.career-tool-info {
background: #fff;
border: 1px solid #9b9998;
color: #5b5955;
padding: 20px;
}
.career-tool-info:before,.career-tool-info:after {
content: " ";
/* 1 */
display: table;
/* 2 */
}
.career-tool-info:after {
clear: both;
}
.career-tool-info input[type="radio"],.career-tool-info input[type="checkbox"] {
margin-right: 5px;
vertical-align: top;
}
.career-tool-info label {
font-family: "Proxima Nova-Semibold",Helvetica,Arial,sans-serif;
font-weight: 400;
font-size: 18px;
}
#media screen and (min-width: 730px) and (max-width: 959px) {
.career-tool-info .questions-intro {
font-size: 20px;
}
}
#media screen and (min-width: 960px) {
.career-tool-info .questions-intro {
font-size: 24px;
}
}
.career-tool-info .questions {
margin-bottom: 16px;
}
.career-tool-info .question {
font-family: "Proxima Nova-Semibold",Helvetica,Arial,sans-serif;
font-weight: 400;
}
#media screen and (min-width: 730px) and (max-width: 959px) {
.career-tool-info .question {
font-size: 20px;
}
}
#media screen and (min-width: 960px) {
.career-tool-info .question {
font-size: 28px;
}
}
.career-tool-info .question-field,.career-tool-info .question-changer,.career-tool-info .question-progress {
padding-left: 50px;
}
.career-tool-info .question-field {
position: relative;
}
.career-tool-info .question-number {
font-family: "Proxima Nova-Bold",Helvetica,Arial,sans-serif;
font-weight: 400;
height: 31px;
width: 31px;
background: transparent url(https://cdn-static.findly.com/wp-content/uploads/sites/936/2020/05/question-number.png) no-repeat 0 0;
color: #fff;
display: block;
left: 2px;
line-height: 33px;
position: absolute;
text-align: center;
top: 4px;
}
.career-tool-info .question-changer {
margin-bottom: 18px;
}
.career-tool-info .state,.career-tool-info .question-field {
display: none;
}
.career-tool-info .state-default {
display: block;
}
#media screen and (min-width: 1190px) {
.career-tool-info .state-default .inner-wrap,.career-tool-info .state-finished .inner-wrap {
font-size: 24px;
}
.career-tool-info .state-quiz {
font-size: 20px;
}
}
.career-tool-info .state .inner-wrap {
float: left;
}
#media screen and (min-width: 730px) {
.career-tool-info .state .inner-wrap {
width: 60%;
}
}
#media screen and (min-width: 1190px) {
.career-tool-info .state .inner-wrap {
padding-top: 35px;
padding-right: 25px;
}
}
#media screen and (min-width: 730px) {
.career-tool-info .state .inner-wrap-right {
float: right;
width: 40%;
}
}
#media screen and (max-width: 729px) {
.career-tool-info .state img.pull-right {
display: none;
}
}
#media screen and (min-width: 730px) {
.career-tool-info .state img.pull-right {
margin-bottom: -25px;
margin-right: -25px;
margin-top: -25px;
width: 40%;
}
}
.career-tool-info .quiz-startOver {
text-decoration: underline;
}
#media screen and (min-width: 730px) {
.career-tool-info .pie-chart,.career-tool-info .legend {
float: left;
padding: 0 1%;
width: 48%;
}
}
.career-tool-info .pie-chart img {
display: block;
height: auto;
max-width: 100%;
}
#media screen and (max-width: 729px) {
.career-tool-info .pie-chart {
display: none;
}
}
#media screen and (min-width: 730px) {
.career-tool-info .legend {
margin-top: 20px;
}
}
.career-tool-info .opportunity {
margin-bottom: 18px;
}
.career-tool-info .opportunity:before,.career-tool-info .opportunity:after {
content: " ";
/* 1 */
display: table;
/* 2 */
}
.career-tool-info .opportunity:after {
clear: both;
}
#media screen and (min-width: 470px) {
.career-tool-info {
padding: 25px;
}
}
#media screen and (min-width: 730px) {
.career-tool-info .score,.career-tool-info .position {
float: left;
}
.career-tool-info .score {
width: 40%;
}
.career-tool-info .position {
width: 60%;
}
.career-tool-info .key {
height: 20px;
width: 20px;
background: #fbc81b;
display: block;
float: left;
margin-right: 15px;
}
.career-tool-info .key2 {
background: #9b9998;
}
.career-tool-info .key3 {
background: #3f3f3f;
}
}
.progress-indicator {
height: 18px;
width: 18px;
display: inline-block;
*display: inline;
*zoom: 1;
background: transparent url(https://cdn-static.findly.com/wp-content/uploads/sites/936/2020/05/progress-indicator.png) no-repeat 0 0;
}
.progress-indicator.active {
background-image: url(https://cdn-static.findly.com/wp-content/uploads/sites/936/2020/05/progress-indicator-active.png);
}
/* /end .comp-careerFitTool */
<!doctype html>
<html lang="en">
<head>
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<script src="https://careers.edwardjones.com/images/highcharts.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
</head>
<body>
<section class="comp-careerFitTool l-spacer" data-features="careerFitTool">
<div class="career-tool-intro">
<h2>Test highcharts after 3 questions</h2>
<p>Find the Right Opportunity for You.</p>
</div>
<div class="career-tool-info">
<form action="">
<div class="state state-default">
<div class="inner-wrap">
<h3>Unsure of what role may be right for you?</h3>
<p>Take a short quiz to see where your interests fit best at Edward Jones.</p>
<p><a class="button-cta quiz-start" href="javascript:;">Let's get started</a></p>
</div>
<img src="https://cdn-static.findly.com/wp-content/uploads/sites/936/2020/05/career-fit-tool.png" alt="Career fit tool" class="pull-right">
</div>
<div class="state state-quiz">
<div class="questions">
<fieldset id="questionDiv1" aria-live="assertive" class="question-field">
<legend>
<span aria-label="question number 1 of 8" class="question-number">1</span>
<p class="questions-intro">Please select the option below that best applies to you.</p>
<p class="question">The type of role that interests me more:</p>
</legend>
<div>
<p><label for="question100"> <input type="radio" id="question100" name="group1" class="answer" value="Financial Advisor">Entrepreneurial/Business Development</label></p>
<p><label for="question200"> <input type="radio" id="question200" name="group1" class="answer" value="Branch Office Administrator">Support someone building their business</label></p>
</div>
</fieldset>
<fieldset id="questionDiv2" aria-live="assertive" class="question-field">
<legend>
<img src="https://cdn-static.findly.com/wp-content/uploads/sites/936/2020/05/career-fit-tool.png" alt="career fit tool" class="pull-right">
<span aria-label="question number 2 of 8" class="question-number">2</span>
<p class="questions-intro">Please select the option below that best applies to you.</p>
<p class="question">How I would like to be compensated for my work:</p>
</legend>
<div>
<p><label for="question101"> <input type="radio" id="question101" name="group2" class="answer" value="Financial Advisor">Commissions</label></p>
<p><label for="question201"> <input type="radio" id="question201" name="group2" class="answer" value="Branch Office Administrator,Headquarters">Salary or hourly</label></p>
</div>
</fieldset>
<fieldset id="questionDiv3" aria-live="assertive" class="question-field">
<legend>
<span aria-label="question number 3 of 8" class="question-number">3</span>
<p class="questions-intro">Please select the option below that best applies to you.</p>
<p class="question">My preferred work style:</p>
</legend>
<div>
<p><label for="question102"> <input type="radio" id="question102" name="group3" class="answer" value="Financial Advisor,Branch Office Administrator">Work autonomously</label></p>
<p><label for="question202"> <input type="radio" id="question202" name="group3" class="answer" value="Headquarters">Work collaboratively on a team</label></p>
</div>
</fieldset>
</div>
<p aria-live="assertive" class="question-changer">
<a aria-label="go to previous question" class="button-previous previous-question" href="javascript:;">Previous</a>
<a aria-label="go to next question" class="button-cta next-question disabled" href="javascript:;">Next</a>
</p>
<p class="question-progress">
<span aria-live="assertive" class="progress-indicator"></span>
<span aria-live="assertive" class="progress-indicator"></span>
<span aria-live="assertive" class="progress-indicator"></span>
</p>
</div>
<div aria-live="assertive" class="state state-finished">
<div class="inner-wrap">
<h3>You're Finished</h3>
<p>Based on your responses, we recommend you explore career opportunities as a</p>
<p id="faOutcome">Financial Advisor</p>
<p id="boaOutcome">Branch Office Administrator</p>
<p id="hqOutcome">Headquarters Professional</p>
</div>
<div class="inner-wrap-right">
<div id="pieChartContainer" tabindex="0"></div>
</div>
<p id="faResultLink">Discover more about this opportunity here </p>
<p id="boaResultLink">Discover more about this opportunity here </p>
<p id="hqResultLink">Discover more about this opportunity here </p>
<p><a class="quiz-startOver" href="javascript:;">Start Over</a></p>
</div>
</form>
</div>
</section>
</body>
</html>

Update an array with data from inputs

I have several inputs, which I am copying n times and I am trying to add numeric values from inputs in the array. I marked word "add" because an array may be already filled by other numbers.
I'm trying to apply method from UncleDave's answer here:
JavaScript - Add Value from input box to array
Example:
I have an array:
var exampleArray = [[1, 1.5], [1, 1], [0, 25.5]];
What I have done:
Wrote value 25 in first input. Wrote value 1.5 in the second input.
Create two new inputs.
Wrote value 25.4 in first input. Wrote value 1 in the second input.
Pressed button for adding into an array.
What I am trying to reach:
var exampleArray = [[1, 1.5], [1, 1], [0, 25.5], [25, 1.5], [25.4, 1]];
What I have reached:
"Udefined" in the console log.
Here Is jsfiddle link with my code: https://jsfiddle.net/aectann/k3qwoz0g/12/
updated with snippet (ok, it was not hard at this time, MTCoster, thank you for advice):
var totalInputs;
var myInputs;
var tmpARR = [];
var count = 0,
types = ['t', 'C' /*, 'Q'*/ ],
button = document.getElementById('button');
button.addEventListener("click", createInputs, false);
function createInputs() {
if (!validInput()) {
return;
}
count += 1;
createInput(count);
}
function createInput(count) {
totalInputs = document.getElementsByClassName('myInput').length;
var existingNode = document.getElementsByClassName('myInput')[totalInputs - 1];
types.forEach(function(type) {
var newNode = existingNode.cloneNode();
newNode.value = null;
newNode.id = type + +count;
newNode.placeholder = 'Placeholder ' + type;
newNode.dataset.id = 'id' + count;
appendNode(newNode);
})
}
function appendNode(node) {
document.querySelector('#div').appendChild(node);
}
function validInput() {
myInputs = document.getElementsByClassName('myInput');
var valid = true;
Array.prototype.slice.call(myInputs).forEach(function(input) {
input.classList.remove('error');
if (!input.value) {
input.classList.add('error');
valid = false;
}
});
return valid;
}
function removeError(event) {
event.classList.remove('error');
}
function guardarNumeros() {
boxvalue = document.getElementsByClassName('myInput').value;
tmpARR.push(boxvalue);
console.log(tmpARR);
return false;
}
#title {
font-family: 'Times New Roman', Times, serif;
font-size: 200%;
}
#step {
font-size: 15pt;
clear: both;
}
#step2 {
font-size: 15pt;
clear: both;
}
#step3 {
font-size: 15pt;
clear: both;
}
summary {
background: #009688;
color: #fff;
padding: 5px;
margin-bottom: 3px;
text-align: left;
cursor: pointer;
padding: 5px;
width: 250px;
/*background-color: #4CAF50;*/
}
summary:hover {
background: #008999;
}
.displayBlockInline-Flex {
display: inline-flex;
}
#margin20 {
margin-left: 20px;
vertical-align: middle;
}
#container {
width: auto;
height: auto;
margin: 0 auto;
display: none;
}
a.myButton {
color: #fff;
/* цвет текста */
text-decoration: none;
/* убирать подчёркивание у ссылок */
user-select: none;
/* убирать выделение текста */
background: rgb(212, 75, 56);
/* фон кнопки */
outline: none;
/* убирать контур в Mozilla */
text-align: center;
cursor: pointer;
width: 150px;
padding-bottom: 11px;
}
a.myButton:hover {
background: rgb(232, 95, 76);
}
/* при наведении курсора мышки */
a.myButton:active {
background: rgb(152, 15, 0);
}
/* при нажатии */
.button1 {
/* background-color: #fc0; /* Цвет фона слоя */
/* padding: 5px; /* Поля вокруг текста */
float: left;
/* Обтекание по правому краю */
width: 450px;
/* Ширина слоя */
}
.button2 {
/* background-color: #c0c0c0; /* Цвет фона слоя */
/* padding: 5px; /* Поля вокруг текста */
width: 650px;
/* Ширина слоя */
float: right;
/* Обтекание по правому краю */
}
.clear {
clear: left;
/* Отмена обтекания */
}
.wrapper {
width: 1100px;
margin-left: 20px;
}
/*inputs*/
#div {
text-align: center;
}
.myInput {
height: 40px;
outline: none;
width: auto;
border: 1px solid #999;
border-radius: 4px;
padding: 5px 10px;
margin: 5px;
display: inline-block;
}
.myInput.error {
border: 1px solid red;
}
#action {
margin: 10px 0;
text-align: center;
}
#button {
width: 190px;
height: 40px;
background: #009688;
color: #fff;
font-weight: 600;
font-size: 13px;
border-radius: 4px;
border: none;
/* text-transform: uppercase;*/
outline: none;
cursor: pointer;
}
#button:hover {
background: #008999;
}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js"></script>
<center>
<input type="text" class="myInput" name="nameAlloy" placeholder="Name">
</center>
<div id="div">
<!--<form onsubmit="return guardarNumeros()">-->
<div id="action">
<button type="button" id="button">Add more inputs</button>
</div>
<input type="number" onkeypress="removeError(this)" class="myInput" data-id="id0" name="value[]" placeholder="Enter value 1">
<input type="number" onkeypress="removeError(this)" class="myInput" data-id="id0" name="value[]" placeholder="Enter value 2">
<div id="action">
<input type="submit" id="button" value="Add to array">
</div>
<!--</form>-->
</div>
The getElementsByClassName() method returns a collection of all
elements in the document with the specified class name, as a NodeList
object.
You can iterate over the collections for all the numeric inputs and update your result. But I would suggest is to create another class for numeric inputs, so you wouldn't need to check for the type of the input and would keep your code generic.
You can try this code and feel free to clear your doubts in the comments.
function guardarNumeros() {
boxvalue = document.getElementsByClassName('myInput');
i = 0;
while (i < boxvalue.length) {
if (boxvalue[i].type == "number") {
if (boxvalue[i+1] && boxvalue[i+1].type == "number") {
tmp = [boxvalue[i].value, boxvalue[i+1].value]
tmpARR.push(tmp);
i+=2;
}
} else {
i++;
}
}
console.log(tmpARR);
return false;
}
The error is in "guardarNumeros" function because getElementsByClassName returns a collection and collection does not have a "value" property.
try this code
function guardarNumeros() {
const inputs = [...document.getElementsByClassName('myInput')];
const inputNumberArr = inputs.filter(x => x.type === 'number');
// tmpARR = [];
for (let i = 0; i < inputNumberArr.length; i++) {
const element = inputNumberArr[i];
if (i % 2 === 0) {
tmpARR.push([element.value]);
} else if (tmpARR[tmpARR.length -1] instanceof Array) {
tmpARR[tmpARR.length -1].push(element.value);
} else {
tmpARR.push([element.value]);
}
}
return false;
}

Categories