How to add auto page break and footer per page in jsPDF? - javascript

How to add page break automatically when the page will be printed, I use jspdf plugin in vuejs 2, is it possible to add page break using those plugins?
Currently, the 2nd div appears broken in the exported file hence I would like to have the div and footer will appear from the next page.
Here's my code:
.final-proof-container {
width: 1296px;
height: 775px;
/* background-color: #e8e8e8; */
border-top: 6px solid #383434;
border-left: 6px solid #383434;
border-right: 6px solid #383434;
/* padding: 10px 10px 10px 10px; */
/* display: inline-flex;
flex-direction: column;
flex-wrap: wrap; */
}
.final-proof-content {
/* width: 330px; */
min-height: 350px;
background-color: #474747;
display: flex;
flex-direction: row;
color: white;
border-radius: 5%;
/* margin-left: 8px;
margin-right: 4px; */
font-weight: 400;
font-family: "Open Sans", sans-serif;
font-size: 12px;
/* padding: 10px 10px 10px 10px; */
/* margin: 10px 10px 10px 10px; */
/* margin-bottom: 10px; */
}
.material-type {
display: flex;
flex-direction: row;
align-items: center;
}
.left-content {
width: 60%;
padding-top: 10px;
padding-left: 10px;
}
.right-content {
width: 40%;
padding-top: 10px;
padding-left: 5px;
padding-right: 10px;
}
.right-content img {
width: 100%;
height: 50%;
}
.dimensions {
list-style: none;
}
.option-logo {
width: 20px;
height: 12px;
}
.material-circle {
width: 15px;
height: 15px;
border-radius: 50%;
margin-right: 5px;
}
.final-proof-footer {
background-color: black;
width: 1296px;
}
.top-section {
background-color: #303030;
display: flex;
justify-content: space-between;
padding-left: 10px;
padding-right: 10px;
color: white;
font-weight: bolder;
font-family: "Open Sans", sans-serif;
}
.bottom-section {
display: flex;
flex-direction: row;
color: white;
flex-wrap: wrap;
justify-content: center;
height: 175px;
}
.logo {
width: 20%;
display: flex;
justify-content: center;
border-right: 1.5px solid #686767;
border-top: 3px solid #686767;
border-left: 3px solid #686767;
border-bottom: 3px solid #686767;
min-width: 300px;
}
.order {
width: 25%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-right: 1.5px solid #686767;
border-top: 3px solid #686767;
border-left: 3px solid #686767;
border-bottom: 3px solid #686767;
flex-wrap: wrap;
min-width: 300px;
}
.location {
width: 25%;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border-right: 1.5px solid #686767;
border-top: 3px solid #686767;
border-left: 3px solid #686767;
border-bottom: 3px solid #686767;
flex-wrap: wrap;
min-width: 300px;
}
.shipping {
width: 26.8%;
display: flex;
flex-direction: row;
align-items: center;
border-right: 4px solid #686767;
border-top: 3px solid #686767;
border-left: 3px solid #686767;
border-bottom: 3px solid #686767;
justify-content: center;
flex-wrap: wrap;
}
.order img {
width: 40px;
height: 40px;
}
.location img {
width: 40px;
height: 40px;
}
.shipping img {
width: 40px;
height: 40px;
}
.text-content {
display: flex;
flex-direction: column;
line-height: 0.1;
font-size: 14px;
}
.order-type {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
font-weight: bolder;
font-size: 20px;
text-align: center;
margin-right: 30px;
}
.logo img {
width: 200px;
height: 150px;
}
<template>
<div>
<v-btn color="primary" #click="generateReport">Generate</v-btn>
<div ref="order_details">
<div class="final-proof-container">
<v-layout row wrap style="padding: 10px !important">
<v-flex
xs4
md4
lg4
v-for="(item, index) in order.carts"
:key="index"
class="pa-0"
style="margin-bottom: 10px !important"
>
<div class="final-proof-content" style="margin: 10px !important">
<div class="left-content">
<p>Product(s): {{ getSectionNo(item) }}</p>
<p class="mb-1">Material Type:</p>
<div class="materia-type mb-2">
<span>
<div
class="material-circle"
:style="`background-color:${item.material.material_type.color}`"
></div>
{{ item.material.material_type.name }}
</span>
</div>
<p class="mb-1">Dimensions:</p>
<ul
v-if="Array.isArray(getDimensions(item))"
class="dimensions mb-2"
>
<li
v-for="(dimension, key) in getDimensions(item)"
:key="key"
>
{{ dimension.section_no }} - W: {{ dimension.width }}"| H:
{{ dimension.height }}"
</li>
</ul>
<p class="mb-1">Options:</p>
<!--Addition of option list in table layout-->
<table class="option-list" id="option-list">
<tr>
<td>
<img
src="/assets/img/price_point.png"
class="option-logo"
alt="Logo"
/>
</td>
<td><p class="mb-1 pl-1">Price Point: 2/$4.00</p></td>
</tr>
</table>
<table class="option-list">
<tr>
<td>
<img
src="/assets/img/comments.png"
width="20"
height="15"
alt="Comments"
/>
</td>
<td>
<p class="mb-1 pl-1">
Comments/Text: "Thanks for Shopping"
</p>
</td>
</tr>
</table>
<table class="option-list">
<tr>
<td>
<img
src="/assets/img/image.png"
width="20"
height="15"
alt="Logo"
/>
</td>
<td><p class="mb-1 pl-1">Logo: logo.png</p></td>
</tr>
</table>
<table class="quantity-table mt-2">
<tr>
<td>
<img
src="/assets/img/qty.png"
width="21"
height="8"
alt="Quantity"
/>
</td>
<td><p class="mb-2 pl-1">Quantity: 2</p></td>
</tr>
</table>
</div>
<div class="right-content">
<!-- <img :src="item.product.img_path" alt="" /> -->
</div>
</div>
</v-flex>
</v-layout>
</div>
<!-- footer -->
<div class="final-proof-footer">
<div class="top-section">
<div style="margin-top: 12px; margin-bottom: 8px">
ORDER # MEC_EO-150454_AbingstonStopNGas
</div>
<div style="margin-top: 12px; margin-bottom: 10px">
<!-- PAGE <span style="margin-left: 8px">1</span> OF 1 -->
</div>
<div style="margin-top: 12px; margin-bottom: 10px">
Designer: Ryan Strawn
</div>
</div>
<div class="bottom-section">
<div class="logo">
<img src="/assets/img/ww.png" alt="" />
</div>
<div class="order">
<div class="order-type">
<img src="/assets/img/man.png" alt="" />
<div style="margin-top: 12px">Ordered By</div>
</div>
<div class="text-content">
<p>Johnboy VanSampson</p>
<p>johnboy#cocacola.com</p>
<p>720-555-5698</p>
</div>
</div>
<div class="location">
<div class="order-type">
<img src="/assets/img/shop.png" alt="" />
<div style="margin-top: 12px">Project</div>
<div>Location</div>
</div>
<div class="text-content">
<p>Abington Stop N Gas</p>
<p>Attn:Johnboy VanSampson</p>
<p>1562 Hiltop Pallace Blvd.</p>
<p>Swingtown, NJ 77895</p>
</div>
</div>
<div class="shipping">
<div class="order-type">
<img src="/assets/img/car.png" alt="" />
<div style="margin-top: 12px">Shipping</div>
</div>
<div class="text-content">
<p>Abington Stop N Gas</p>
<p>Attn:Johnboy VanSampson</p>
<p>1562 Hiltop Pallace Blvd.</p>
<p>Swingtown, NJ 77895</p>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { jsPDF } from "jspdf";
export default {
props: {
value: {
type: Object,
},
},
data() {
return {
order: {},
htmlToPdfOptions: {
html2canvas: {
useCORS: true,
scale: 2,
},
jsPDF: {
// unit: "px",
format: "letter",
orientation: "landscape",
},
},
};
},
watch: {
value(val) {
this.order = val;
},
},
mounted() {
const vm = this;
// vm.generateReport();
},
methods: {
async generateReport() {
const vm = this;
const doc = new jsPDF({
orientation: "l",
unit: "px",
format: "letter",
hotfixes: ["px_scaling"],
compress: true,
});
doc.html(vm.$refs.order_details, {
margin: 10,
autoPaging: "slice",
html2canvas: {
scale: 0.8,
},
pagesplit: true,
callback: function (doc) {
doc.save("test.pdf");
},
});
},
},
};
</script>

atm, I don't see any property or function to support page break when printing HTML element, you just can do it manually via doc.addPage().
To add header and footer on each page, you can iterate each page of doc, then attach your header and footer to suitable position.
For example:
for (let i = 1; i <= doc.getNumberOfPages(); i++) {
doc.setPage(i)
doc.text('This is header', 10, 30)
}

Related

Problem with displaying number in inner text

newbie here...
I am working on some simple project where I am trying to simulate bank app.
Thing is that when I click on send money button, I want to take value from input value, and then subtract this value from my whole account balance.
Really simple, but after first transaction I get value which I want, but after second time I get innerText displaying "Nan" instead of some number value.
Here it is javascript file, if you can see from this why I get error.
Also here it is html and css if you don't understand what I am talking about.
////////////////// TOTAL MONEY FROM CARDS ///////////////////////
const totalMoney = document.querySelector(`.totalMoney`);
const allcards = document.querySelectorAll(`.cards`);
let totalMoneyAccount = 0;
allcards.forEach((kartica) => {
let novacNaKartici = kartica.querySelector(`.novacNaKartici`).innerText;
novacNaKartici = parseInt(novacNaKartici);
totalMoneyAccount += novacNaKartici;
totalMoney.innerText = ` ${replika2} $`;
});
//////////////////////////// TRANSFER MONEY TO SOMEONE /////////////////////////////
const reciver = document.querySelector(`input[name='recivier']`);
let amount = document.querySelector(`input[name='amount']`);
const sendMoneyBtn = document.querySelector(`.sendBtn`);
const transakcijeParent = document.querySelector(`.transakcije`);
sendMoneyBtn.addEventListener(`click`, () => {
amount = parseInt(amount.value);
totalMoneyAccount = totalMoneyAccount - amount;
updateProfile(totalMoneyAccount);
});
function updateProfile(totalMoneyAccount) {
totalMoney.innerHTML = totalMoneyAccount;
}
<!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="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD#20..48,100..700,0..1,-50..200"
/>
<link rel="stylesheet" href="style.css" />
<title>Bank app</title>
</head>
<body>
<div class="container">
<div class="profile">
<div class="header">
<span class="material-symbols-outlined"> notifications </span>
<span class="material-symbols-outlined"> search </span>
</div>
<div class="person">
<img src="/img/cost1.jpg" alt="" />
<p>Random user</p>
<span class="totalMoney" style="font-size: 20px;"></span>
</div>
<div class="menu">
<div class="account flex">
<span class="material-symbols-outlined"> manage_accounts </span>
<p>Accounts</p>
</div>
<div class="transactions flex">
<span class="material-symbols-outlined"> receipt_long </span>
<p>Transactions</p>
</div>
<div class="bonus flex">
<span class="material-symbols-outlined"> star </span>
<p>Bonus</p>
</div>
<div class="invest flex">
<span class="material-symbols-outlined"> trending_up </span>
<p>Investments</p>
</div>
<div class="logOut flex">
<span class="material-symbols-outlined"> logout </span>
<p>Log Out</p>
</div>
</div>
</div>
<div class="main">
<div class="left">
<div class="naslov">
<p>Cards</p>
<span class="material-symbols-outlined">
add_circle
</span>
</div>
<div class="allCards">
<div class="cards changeJustify">
<div class="singleCard">
<img src="/img/visa.png" alt="" class="changeImg"/>
</div>
<div class="opis">
<p style="color: grey; font-size:20px">VISA</p>
<p style="color: black; font-size:16px" class="balance1 changeBalance">Balance:</p>
</div>
<div class="balance">
<span class="material-symbols-outlined changeSpan dots">
more_vert
</span>
<span style="font-size: 22px; color:grey(59, 59, 59);" class="novacNaKartici">2500$</span>
</div>
</div>
<div class="cards changeJustify">
<div class="singleCard ">
<img src="/img/american.jpg" alt="" class="changeImg"/>
</div>
<div class="opis ">
<p style="color: grey; font-size:20px">VISA</p>
<p style="color: grey; font-size:16px" class="balance1 changeBalance">Balance:</p>
</div>
<div class="balance ">
<span class="material-symbols-outlined changeSpan dots" >
more_vert
</span>
<span style="font-size: 22px; color:black;" class="novacNaKartici">3500$</span>
</div>
</div>
</div>
<p style="font-size: 30px;
color: grey;
font-weight: bold;">Transactions</p>
<div class="transakcije">
</div>
</div>
</div>
<div class="right">
<p style="font-size: 30px;
color: grey;
font-weight: bold;">Transfer money</p>
<div class="transfer">
<label for="recivier">Transfer to</label>
<input type="text" placeholder="antonio3101" name="recivier">
<label for="amount">Amount</label>
<input type="number" placeholder="$300..." name="amount">
<button class="sendBtn">Send</button>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
body {
padding: 0;
margin: 0;
box-sizing: border-box;
font-family: sans-serif;
}
.container {
width: 100vw;
height: 100vh;
display: flex;
background-color: #f1f2f6;
}
.profile {
height: 100vh;
width: 20%;
background-color: #1d1c57;
display: flex;
flex-direction: column;
color: white;
}
.profile .header {
display: flex;
padding: 30px;
align-items: center;
justify-content: space-between;
color: #7979a6;
}
.profile .header span {
font-size: 26px;
}
.profile .header span:hover {
color: white;
}
.profile .person {
margin-top: 40px;
display: flex;
flex-direction: column;
align-items: center;
}
.profile .person img {
width: 150px;
height: 150px;
border-radius: 50%;
}
.profile .person p {
font-size: 26px;
color: #c6c5d8;
}
.profile .menu {
margin-top: 100px;
padding: 20px;
background-color: #262467;
border-radius: 30px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
height: 100%;
position: relative;
font-size: 22px;
color: #7c7eaa;
}
.profile .flex {
margin-left: 20px;
display: flex;
align-items: center;
gap: 20px;
}
.profile .flex:hover {
margin-left: 40px;
color: white;
transition: ease-in-out;
}
.logOut {
position: absolute;
bottom: 50px;
}
/*-------------------------- KARTICE ----------------------------------------- */
.main .naslov {
color: grey;
font-size: 30px;
font-weight: bold;
}
.naslov {
display: flex;
align-items: center;
justify-content: space-between;
}
.naslov span {
font-size: 32px;
}
.naslov span:hover {
color: black;
}
.main .left {
display: flex;
flex-direction: column;
margin-left: 30px;
}
.main .left .cards {
background-color: #ffffff;
padding: 20px;
display: flex;
padding: 20px;
border-radius: 20px;
}
.cards {
margin-top: 10px;
}
.cards .singleCard {
display: flex;
width: 100%;
}
.allCards {
display: flex;
flex-direction: column;
}
.cards .singleCard img {
width: 250px;
padding-right: 10px;
}
.cards .opis p {
margin: 0;
padding: 0;
margin-left: 10px;
}
.cards .opis {
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
.cards .balance {
margin-left: 30px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
}
/*------------------------------- CHANGE CARD -------------------------------- */
.changeImg {
height: 50px;
object-fit: cover;
}
.changeSpan {
display: none;
}
.changeJustify {
display: flex;
align-items: center;
}
.changeBalance {
display: none;
}
/*-------------------------- TRANSAKCIJE ----------------------------------------- */
.transakcije {
background-color: white;
display: flex;
flex-direction: column;
padding: 10px;
}
.single-transaction {
display: flex;
margin-left: 10px;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid grey;
}
.single-transaction img {
height: 60px;
width: 60px;
border-radius: 50%;
object-fit: cover;
}
.single-transaction .destination {
font-size: 16px;
color: rgb(73, 73, 73);
font-weight: bold;
}
.single-transaction .amount {
color: rgb(30, 149, 30);
font-weight: bold;
font-size: 16px;
}
.single-transaction:last-child {
border-bottom: 0;
}
/*-------------------------- RIGHT SECTIONS ----------------------------------------- */
/*-------------------------- TRANSFER MONEY ----------------------------------------- */
.right {
display: flex;
flex-direction: column;
margin-left: 100px;
}
.right .transfer {
background-color: #1d1c57;
padding: 50px 20px;
border-radius: 10px;
margin-left: 10px;
margin-right: 20px;
}
.right .transfer input {
height: 30px;
font: 24px;
margin-left: 10px;
}
.right .transfer label {
margin-left: 20px;
color: white;
}
.right .transfer button {
padding: 10px 15px;
color: black;
background-color: white;
border-radius: 5px;
border: 0;
margin-left: 20px;
margin-right: 20px;
}
You are overwriting your amount variable (which points to an input element) with the value inputted into said input.
Hence, after the first click you no longer have a reference to the input element: your code tries to read the value property of the integer amount of the last transaction. This results in the following evaluation: parseInt(amount.value) -> parseInt(undefined) -> NaN.
Change this code:
sendMoneyBtn.addEventListener(`click`, () => {
amount = parseInt(amount.value);
totalMoneyAccount = totalMoneyAccount - amount;
updateProfile(totalMoneyAccount);
});
to something like this:
sendMoneyBtn.addEventListener(`click`, () => {
const amountValue = parseInt(amount.value);
totalMoneyAccount = totalMoneyAccount - amountValue;
updateProfile(totalMoneyAccount);
});
Credit to #JohnnyMopp for noticing it first.

Show search results only when searching

How can I hide the list of products, and show the results only when searching using the search bar?
Every time I hide the list of products, when I search the entire list appears and not only the search result.
I want to show only the search result when searching using the search bar.
function search() {
var searchBar, ProductsList, Products, ProductsTitle, TextValue, Element
searchBar = document.getElementById('searchBar').value.toUpperCase()
ProductsList = document.getElementById('product-list')
Products = document.querySelectorAll('.product')
ProductsTitle = ProductsList.getElementsByTagName('h2')
for (let i = 0; i < ProductsTitle.length; i++) {
TextValue = Products[i].getElementsByTagName('h2')[0];
if (TextValue) {
Element = TextValue.textContent || e.innerHTML
if (Element.toUpperCase().indexOf(searchBar) > -1) {
Products[i].style.display = ""
} else {
Products[i].style.display = "none"
}
}
}
}
.search-result {
max-width: max-content;
background-color: rgba(0, 0, 0, 0.6);
height: max-content;
}
.products {
padding: 10px;
width: 100%;
display: flex;
flex-direction: column;
position: absolute;
top: 50px;
z-index: 2;
}
.product {
float: right;
display: flex;
align-items: center;
direction: rtl;
color: white;
background-color: rgba(0, 0, 0, 0.6);
border-radius: 6px;
border-bottom: 2px solid red;
}
.product text {
float: left;
}
* {
padding: 0;
margin: 0;
font-family: sans-serif;
}
.search {
width: 100%;
display: flex;
justify-content: center;
padding: 20px;
}
.search input {
border-radius: 20px 0px 0px 20px;
outline: none;
width: 250px;
border-color: red;
padding-left: 20px;
}
.search button {
border-radius: 0px 20px 20px 0px;
padding: 5px 20px;
background-color: red;
color: white;
font-size: 1.2rem;
border-color: red;
cursor: pointer;
outline: none;
border: none;
}
<div class="search">
<input id="searchBar" type="text" placeholder="Search" onkeyup="search()">
<button type="submit">search</button>
</div>
<div class="search-result">
</div>
<div class="img">
<img src="https://www.sare.org/wp-content/uploads/Our-Farms-Our-Future-Podcast-Logo-330x166.jpg" style="width: 100%;" alt="">
</div>
<div class="products" id="product-list">
<div class="product">
<img src="images/img/2.png" alt="" style="width:150px;">
<div class="text">
<h2>Mango</h2>
<h4>1.50€</h4>
</div>
</div>
<div class="product">
<img src="images/img/3.png" alt="" style="width:150px;">
<div class="text">
<h2>pomegranate</h2>
<h4>1.50€</h4>
</div>
</div>
<div class="product">
<img src="images/img/4.png" alt="" style="width:150px;">
<div class="text">
<h2>Grape</h2>
<h4>1.50€</h4>
</div>
</div>
<div class="product">
<img src="images/img/5.png" alt="" style="width:150px;">
<div class="text">
<h2>apple</h2>
<h4>1.50€</h4>
</div>
</div>
<div class="product">
<img src="images/img/6.png" alt="" style="width:150px;">
<div class="text">
<h2>fig</h2>
<h4>1.50€</h4>
</div>
</div>
</div>
You can use classList in parent .products
searchBarValue.length ? productsList.classList.add('active') : productsList.classList.remove('active')
When class is active the wrapper as display:flex
Note: I improved a bit your code
const searchBar = document.getElementById('searchBar')
function search() {
const searchBarValue = document.getElementById('searchBar').value.toUpperCase()
const productsList = document.getElementById('product-list')
const products = document.querySelectorAll('.product')
const productsTitle = productsList.getElementsByTagName('h2')
searchBarValue.length ? productsList.classList.add('active') : productsList.classList.remove('active')
for (let i = 0; i < productsTitle.length; i++) {
const textValue = products[i].getElementsByTagName('h2')[0];
if (textValue) {
const element = textValue.textContent.toUpperCase()
products[i].style.display = element.indexOf(searchBarValue) > -1 ? "" : "none"
}
}
}
searchBar.addEventListener('keyup', search)
.search-result {
max-width: max-content;
background-color: rgba(0, 0, 0, 0.6);
height: max-content;
}
.products {
padding: 10px;
width: 100%;
display: none;
position: absolute;
top: 50px;
z-index: 2;
}
.products.active {
display: flex;
flex-direction: column;
}
.product {
display: flex;
align-items: center;
direction: rtl;
color: white;
background-color: rgba(0, 0, 0, 0.6);
border-radius: 6px;
border-bottom: 2px solid red;
}
.product text {
float: left;
}
* {
padding: 0;
margin: 0;
font-family: sans-serif;
}
.search {
width: 100%;
display: flex;
justify-content: center;
padding: 20px;
}
.search input {
border-radius: 20px 0px 0px 20px;
outline: none;
width: 250px;
border-color: red;
padding-left: 20px;
}
.search button {
border-radius: 0px 20px 20px 0px;
padding: 5px 20px;
background-color: red;
color: white;
font-size: 1.2rem;
border-color: red;
cursor: pointer;
outline: none;
border: none;
}
<div class="search">
<input id="searchBar" type="text" placeholder="Search">
<button type="submit">search</button>
</div>
<div class="search-result">
</div>
<div class="img">
<img src="https://www.sare.org/wp-content/uploads/Our-Farms-Our-Future-Podcast-Logo-330x166.jpg" style="width: 100%;" alt="">
</div>
<div class="products" id="product-list">
<div class="product">
<img src="images/img/2.png" alt="" style="width:150px;">
<div class="text">
<h2>Mango</h2>
<h4>1.50€</h4>
</div>
</div>
<div class="product">
<img src="images/img/3.png" alt="" style="width:150px;">
<div class="text">
<h2>pomegranate</h2>
<h4>1.50€</h4>
</div>
</div>
<div class="product">
<img src="images/img/4.png" alt="" style="width:150px;">
<div class="text">
<h2>Grape</h2>
<h4>1.50€</h4>
</div>
</div>
<div class="product">
<img src="images/img/5.png" alt="" style="width:150px;">
<div class="text">
<h2>apple</h2>
<h4>1.50€</h4>
</div>
</div>
<div class="product">
<img src="images/img/6.png" alt="" style="width:150px;">
<div class="text">
<h2>fig</h2>
<h4>1.50€</h4>
</div>
</div>
</div>

z index 1 doesn't stop modal from pushing down index 0 content

Hi all I have a modal that I made, I set it to have a z-index of 1 and the component its inside of has a z-index of 0 however the modal still stretches the component when it pops up even though it sits ontop of the content like you see in the image below
I would like to make the modal overlay without stretching this component down as it pushes all the other content down which I want to avoid I'm not sure of the best way to accomplish this because the component in purple is reused across multiple views inside my `vue router. I will show the code for my component :) any suggestions on how to accomplish this are appreciated
<template>
<div id="topbarContainer" v-bind:class="{ modalbackground: modal }">
<!-- TOPBAR -->
<div class="topbar">
<h6 id="dashboard">{{name}}</h6>
<div class="searchContainer">
<b-icon-search></b-icon-search>
<small>search</small>
<input class="searchbar" type="text" />
<small class="searchbtn">H</small>
</div>
<div id="topbarRightdiv">
<img class="topbarButtons" src="../assets/superdash/chat-1.png" width="30px" height="30px" />
<img class="topbarButtons" src="../assets/superdash/notifications.png" width="30px" height="30px" />
<img class="topbarButtons" src="../assets/superdash/photo.png" width="30px" height="30px" />
<p id="profileName" #click="showModal">Hemlin <small id="profileArrow">▼</small></p>
</div>
<!--modal -->
<div v-if="this.modal==true" class="modal-content">
<section class="modalSection ModalsectionHeader">
<img class="modalImg" src="../assets/topbar/profile_icons-2.svg"/> <p id="darkmodeText">Dark Mode</p> <img class="modalImg" src="../assets/topbar/togle.svg" #click="toggleDarkmode" v-if="darkmode==true"/> <img class="modalImg" src="../assets/topbar/togle.svg" #click="toggleDarkmode" v-if="darkmode==false"/>
</section>
<section class="modalSection">
<img class="modalImg" src="../assets/topbar/profile_icons.svg"/> <p>Profile</p> <small>></small>
</section>
<section class="modalSection">
<img class="modalImg" src="../assets/topbar/profile_icons-1.svg"/> <p>Wallet</p> <small>></small>
</section>
<section class="modalSection">
<img class="modalImg" src="../assets/topbar/profile_icons-3.svg"/> <p>Saved</p> <small>></small>
</section>
<section class="modalSection">
<img class="modalImg" src="../assets/topbar/profile_icons-4.svg"/> <p>Get Reports</p> <small>></small>
</section>
</div>
</div>
<!-- TOPBAR -->
</div>
</template>
<script>
export default {
name: 'Topbar',
props: ['name'],
data:function(){
return{
modal: false,
darkmode: false,
}
},
methods:{
showModal(){
console.log("clicked")
this.modal = !this.modal
}
,toggleDarkmode(){
console.log('darkmode')
this.darkmode = !this.darkmode
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
#topbarContainer{
z-index: 0;
}
.modalbackground{
background-color: rgba(128, 0, 128, 0.555);
}
.topbar{
display: flex;
font-size: 12px;
font-family: 'Noto Sans JP', sans-serif;
}
#topbarRightdiv{
display: flex;
margin-left: 9em;
}
#topbarRightdiv p{
display: flex;
}
#profileName{
font-size:14px;
padding-top: 1em;
}
#profileName:hover{
cursor: pointer;
}
#profileArrow{
color: #39b3fac5;
}
#profileArrow:hover{
color: #39d3fa;
cursor: pointer;
}
#dashboard{
margin-top: 1em;
padding-left: 1em;
margin-right: 5em;
}
.searchContainer{
margin-top:1em;
margin-left: 1em;
margin-right:3em;
width: 60%;
border-style: none;
border-radius: 13px;
background-color: white;
height: 2em;
box-shadow: 0 1px 2px #88888877;
}
.searchbar{
border-style: none;
border-radius: 13px;
width: 85%;
padding-right: 1em;
}
.searchbtn{
margin-left: .5em;
color: rgb(73, 79, 90);
border-left: 1px rgb(185, 187, 204) solid;
padding-left:1em;
}
.topbarButtons{
margin: 1em;
border-radius: 100%;
background-color: #87b9fa1a;
}
/* Modal Content/Box */
.modal-content {
z-index: 1;
position: relative;
right: 50px;
width: 30em;
height: 20em;
background-color: #fefefe;
padding: 20px;
border: 1px solid #888;
}
.modalSection{
padding-top: .5em;
display: flex;
width: 100%;
justify-content: space-between;
}
.ModalsectionHeader{
padding-bottom: 1em;
margin-bottom: 1em;
border-bottom: 1px solid rgba(97, 95, 95, 0.267);
}
#darkmodeText{
margin: .2em
}
.modalImg{
width: 25px;
height: 25px;
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
</style>
Try to change the position to absolute :
.modal-content {
z-index: 1;
position: relative; <---HERE to absolute
new Vue({
el:'#demo',
props: ['name'],
data:function(){
return{
modal: false,
darkmode: false,
}
},
methods:{
showModal(){
console.log("clicked")
this.modal = !this.modal
},
toggleDarkmode(){
console.log('darkmode')
this.darkmode = !this.darkmode
}
}
})
#topbarContainer{
z-index: 0;
}
.modalbackground{
background-color: rgba(128, 0, 128, 0.555);
}
.topbar{
display: flex;
font-size: 12px;
font-family: 'Noto Sans JP', sans-serif;
}
#topbarRightdiv{
display: flex;
margin-left: 9em;
}
#topbarRightdiv p{
display: flex;
}
#profileName{
font-size:14px;
padding-top: 1em;
}
#profileName:hover{
cursor: pointer;
}
#profileArrow{
color: #39b3fac5;
}
#profileArrow:hover{
color: #39d3fa;
cursor: pointer;
}
#dashboard{
margin-top: 1em;
padding-left: 1em;
margin-right: 5em;
}
.searchContainer{
margin-top:1em;
margin-left: 1em;
margin-right:3em;
width: 60%;
border-style: none;
border-radius: 13px;
background-color: white;
height: 2em;
box-shadow: 0 1px 2px #88888877;
}
.searchbar{
border-style: none;
border-radius: 13px;
width: 85%;
padding-right: 1em;
}
.searchbtn{
margin-left: .5em;
color: rgb(73, 79, 90);
border-left: 1px rgb(185, 187, 204) solid;
padding-left:1em;
}
.topbarButtons{
margin: 1em;
border-radius: 100%;
background-color: #87b9fa1a;
}
/* Modal Content/Box */
.modal-content {
z-index: 1;
position: absolute;
right: 50px;
width: 30em;
height: 20em;
background-color: #fefefe;
padding: 20px;
border: 1px solid #888;
}
.modalSection{
padding-top: .5em;
display: flex;
width: 100%;
justify-content: space-between;
}
.ModalsectionHeader{
padding-bottom: 1em;
margin-bottom: 1em;
border-bottom: 1px solid rgba(97, 95, 95, 0.267);
}
#darkmodeText{
margin: .2em
}
.modalImg{
width: 25px;
height: 25px;
}
/* The Close Button */
.close {
color: #aaa;
float: right;
font-size: 28px;
font-weight: bold;
}
.close:hover,
.close:focus {
color: black;
text-decoration: none;
cursor: pointer;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue.min.css" />
<script src="//unpkg.com/bootstrap-vue#latest/dist/bootstrap-vue-icons.min.js"></script>
<div id="demo">
<div id="topbarContainer" v-bind:class="{ modalbackground: modal }">
<!-- TOPBAR -->
<div class="topbar">
<h6 id="dashboard">{{name}}</h6>
<div class="searchContainer">
<b-icon-search></b-icon-search>
<small>search</small>
<input class="searchbar" type="text" />
<small class="searchbtn">H</small>
</div>
<div id="topbarRightdiv">
<img class="topbarButtons" src="https://picsum.photos/30" width="30px" height="30px" />
<img class="topbarButtons" src="https://picsum.photos/30" width="30px" height="30px" />
<img class="topbarButtons" src="https://picsum.photos/30" width="30px" height="30px" />
<p id="profileName" #click="showModal">Hemlin <small id="profileArrow">▼</small></p>
</div>
<!--modal -->
<div v-if="this.modal==true" class="modal-content">
<section class="modalSection ModalsectionHeader">
<img class="modalImg" src="https://picsum.photos/30"/> <p id="darkmodeText">Dark Mode</p> <img class="modalImg" src="https://picsum.photos/30" #click="toggleDarkmode" v-if="darkmode==true"/> <img class="modalImg" src="https://picsum.photos/30" #click="toggleDarkmode" v-if="darkmode==false"/>
</section>
<section class="modalSection">
<img class="modalImg" src="https://picsum.photos/30"/> <p>Profile</p> <small>></small>
</section>
<section class="modalSection">
<img class="modalImg" src="https://picsum.photos/30"/> <p>Wallet</p> <small>></small>
</section>
<section class="modalSection">
<img class="modalImg" src="https://picsum.photos/30"/> <p>Saved</p> <small>></small>
</section>
<section class="modalSection">
<img class="modalImg" src="https://picsum.photos/30"/> <p>Get Reports</p> <small>></small>
</section>
</div>
</div>
<!-- TOPBAR -->
</div>
</div>
You have an error on writing toggleDarkMode(), you wrote ,toggleDarkMode(). Move up the comma (,).

Create word bubbles as buttons in HTML/CSS/JS?

I'm trying to create multiple bubbled words as buttons!
what is the best way to approach the design below using CSS or any JS library?
There can be many buttons (depends on the data from DB)
What I've tried:
#tagsContainer {
float: left;
width: 25vw;
margin-top: 10vh;
overflow: hidden;
}
#tags {
display: grid;
justify-content: space-between;
grid-gap: 8px;
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
}
#tag {
background-color: #2F3841;
border-radius: 8px;
margin-top: 10px;
width: max-content;
}
<div id="tagsContainer">
<h3 id="tagsTitle">TOP TAGS</h3>
<div id="tags">
<div id="tag">
<h4 id="tagTitle">Flutter</h4>
</div>
<div id="tag">
<h4 id="tagTitle">Deep Learning</h4>
</div>
<div id="tag">
<h4 id="tagTitle">Machine Learning</h4>
</div>
</div>
</div>
The problem is when using grid layout all the columns would be same in size!
Just use display:inline-block and style your container as you want.
P.s. you have the same id multiple times, use class instead because id must be unique
#tagsContainer {
/*float: left; REMOVE IT!!!*/
width: 25vw;
margin-top: 10vh;
overflow: hidden;
}
#tags {
/* NOT NECESSARY
display: grid;
justify-content: space-between;
grid-gap: 8px;
grid-template-columns: repeat(auto-fill, minmax(30%, 1fr));
*/
}
.tag {
background-color: #2F3841;
border-radius: 8px;
margin-top: 10px;
width: max-content;
display:inline-block;
}
<div id="tagsContainer">
<h3 id="tagsTitle">TOP TAGS</h3>
<div id="tags">
<div class="tag">
<h4 class="tagTitle">Flutter</h4>
</div>
<div class="tag">
<h4 class="tagTitle">Deep Learning</h4>
</div>
<div class="tag">
<h4 class="tagTitle">Machine Learning</h4>
</div>
</div>
</div>
Do you mean this?
body {
background: #202223;
}
#tags {
font-family: cursive;
width: 292px;
}
.tag {
font-family: inherit;
background: #2b333b;
font-size: 14px;
padding: 10px 33px;
border: none;
border-radius: 16px;
color: #d4d4d4;
font-style: italic;
display: inline-block;
width: max-content;
margin: 4px 4px;
}
.tag:hover {
opacity: 0.9;
}
.tag:focus {
outline: 1px solid #6868688f;
outline-offset: -3px;
}
<div id="tags">
<button class="tag">Flutter</button>
<button class="tag">Data Science</button>
<button class="tag">CSS</button>
<button class="tag">Deep Learning</button><button class="tag">Machine Learning</button>
</div>

Advice on flawed logic per JavaScript calculator

How do I improve my logic for building my calculator? I cannot figure out how to integrate sin/cos/tan/percents correctly. This is my first real java script assignment and I am not sure how to go about handling all the errors I get. I frequently get not a number as the result. I know I cannot read everything into a variable to handle the calculations. But I don't know where to go from here.
function in1() {
document.calc.txt.value += '1'
}
function in2() {
document.calc.txt.value += '2'
}
function in3() {
document.calc.txt.value += '3'
}
function in4() {
document.calc.txt.value += '4'
}
function in5() {
document.calc.txt.value += '5'
}
function in6() {
document.calc.txt.value += '6'
}
function in7() {
document.calc.txt.value += '7'
}
function in8() {
document.calc.txt.value += '8'
}
function in9() {
document.calc.txt.value += '9'
}
function inAdd() {
document.calc.txt.value += '+'
}
function inSub() {
document.calc.txt.value += '-'
}
function inMult() {
document.calc.txt.value += '*'
}
function inDiv() {
document.calc.txt.value += '/'
}
function inDecimal() {
document.calc.txt.value += '.'
}
flag = 0;
function inSin() {
document.calc.txt.value += 'Sin('
flag = 1
}
function inCos() {
document.calc.txt.value += 'Cos('
flag = 2
}
function inTan() {
document.calc.txt.value += 'Tan('
flag = 3
}
function inPercent() {
document.calc.txt.value = calc.txt.value / 100;
}
var inputTest = document.getElementById("").value;
function equals() {
if (flag == 1) {
var input = calc.txt.value;
var newNumber = input.substring(4);
document.calc.txt.value = Math.sin(newNumber);
flag = 0
}
if (flag == 2) {
var input = calc.txt.value;
var newNumber = input.substring(4);
document.calc.txt.value = Math.cos(newNumber);
flag = 0
}
if (flag == 3) {
var input = calc.txt.value;
var newNumber = input.substring(4);
document.calc.txt.value = Math.tan(newNumber);
flag = 0
} else if (flag == 0) {
document.calc.txt.value = (eval(calc.txt.value))
}
}
.flexBoxContainer {
display: flex;
justify-content: space-around;
align-items: flex-start;
}
.title {
border: black 5px solid;
color: red;
padding: 2px;
font-size: 21;
width: 310px;
text-align: center;
}
.calculator {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
box-sizing: border-box;
}
.calculator .keys {
border: white 3px ridge;
height: 60px;
width: 75px;
}
.input-box {
border: white 3px ridge;
height: 60px;
width: 236px;
flex-basis: 66%;
}
.input-display {
border: black 3px solid;
background-color: white;
height: 45px;
width: 233x;
flex-basis: 66%;
text-align: right;
}
.center {
display: flex;
flex-direction: column;
justify-content: center;
;
}
.container1 {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-content: center;
}
#media (min-width: 381px) {
.calculator {
width: 380px;
}
}
/* button formatting below */
.button1 {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 19px;
text-align: center;
display: inline-block;
font-size: 36px;
cursor: pointer;
}
.button2 {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 20px;
text-align: center;
display: inline-block;
font-size: 30px;
cursor: pointer;
}
.buttonSin {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 7px;
text-align: center;
display: inline-block;
font-size: 30px;
cursor: pointer;
}
.buttonCos {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 3px;
text-align: center;
display: inline-block;
font-size: 30px;
cursor: pointer;
}
.buttonTan {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 2px;
text-align: center;
display: inline-block;
font-size: 30px;
cursor: pointer;
}
.button3 {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 17px;
text-align: center;
display: inline-block;
font-size: 30px;
cursor: pointer;
}
.buttonMinus {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 22px;
text-align: center;
display: inline-block;
font-size: 30px;
cursor: pointer;
}
.buttonDiv {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 21px;
text-align: center;
display: inline-block;
font-size: 30px;
cursor: pointer;
}
.buttonDec {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 23px;
text-align: center;
display: inline-block;
font-size: 30px;
cursor: pointer;
}
.buttonPer {
border: black 10px solid;
color: white;
background-color: blue;
padding: 1px 12px;
text-align: center;
display: inline-block;
font-size: 30px;
cursor: pointer;
}
<html>
<title>JavaScript Calculator Assignment</title>
<head>
<link rel="stylesheet" href="calculator.css">
<script type="text/javascript" src="calculator.js"></script>
</head>
<div class="flexBoxContainer">
<form class="calculator" name="calc">
<div class="title">JavaScript Calculator</div>
<div class="container1">
<div class="input-box center">
<input class="value input-box center" type="text" name="txt" readonly="">
<!--<span class ="" onclick="document.calc.txt.value +=''"></span> <!--do we need this?-->
</div>
<div class="keys">
<span class="button1" onclick="document.calc.txt.value =''">c</span>
</div>
</div>
<div class="keys">
<span class="button2" onclick="in1()">1</span>
</div>
<div class="keys">
<span class="button2" onclick="in2()">2</span>
</div>
<div class="keys">
<span class="button2" onclick="in3()">3</span>
</div>
<div class="keys">
<span class="buttonSin" onclick="inSin()">Sin</span>
</div>
<div class="keys">
<span class="button2" onclick="in4()">4</span>
</div>
<div class="keys">
<span class="button2" onclick="in5()">5</span>
</div>
<div class="keys">
<span class="button2" onclick="in6()">6</span>
</div>
<div class="keys">
<span class="buttonCos" onclick="inCos()">Cos</span>
</div>
<div class="keys">
<span class="button2" onclick="in7()">7</span>
</div>
<div class="keys">
<span class="button2" onclick="in8()">8</span>
</div>
<div class="keys">
<span class="button2" onclick="in9()">9</span>
</div>
<div class="keys">
<span class="buttonTan" onclick="inTan()">Tan</span>
</div>
<div class="keys">
<span class="button3" onclick="inAdd()">+</span>
</div>
<div class="keys">
<span class="buttonMinus" onclick="inSub()">-</span>
</div>
<div class="keys">
<span class="button2" onclick="inMult()">*</span>
</div>
<div class="keys">
<span class="buttonDiv" onclick="inDiv()">/</span>
</div>
<div class="keys">
<span class="buttonDec" onclick="inDecimal()">.</span>
</div>
<div class="keys">
<span class="button2" onclick="document.calc.txt.value +='0'">0</span>
</div>
<div class="keys">
<span class="button3" onclick="equals()"> = </span>
</div>
<div class="keys">
<span class="buttonPer" onclick="inPercent()">%</span>
</div>
</form>
</div>
</html>

Categories