While building a basic application, when I click a button, the text inside my currently focused input overflows only in Chrome. However, that text can be accessed using (right) arrow key(s). Is there any way to avoid this? I tried clipboard copy-paste but that did not work.
const peopleElem = document.querySelector("#people");
const billElem = document.querySelector("#bill");
const submit = document.querySelector("[type=\"submit\"]");
const form = document.querySelector("form");
const tipPerPersonElem = document.querySelector("[data-tip-person]");
const totalPerPersonElem = document.querySelector("[data-total-person]");
let billError = peopleError = false;
class TipCalc {
constructor() {
this.tipPerPerson = 0;
this.totalPerPerson = 0;
this.tip = 0
this.tipPercent = 0;
this.bill = parseFloat(billElem.value);
this.people = parseFloat(peopleElem.value);
}
getTip() {
const element = document.querySelector(".active");
if (!element) return 0;
if (element.tagName === "BUTTON") return this.tipPercent = element.innerText.replace("%", "");
return this.tipPercent = element.value.replace("%", "");
}
getTipPerPerson() {
this.getTip();
this.tip = ((this.tipPercent / 100) * this.bill);
this.tipPerPerson = this.tip / this.people;
return this.tipPerPerson;
}
getTotalPerPerson() {
this.getTipPerPerson();
this.totalPerPerson = (this.bill this.tip) / this.people
return this.totalPerPerson;
}
}
const tipOptions = [...document.querySelectorAll("button"), document.querySelector("#custom")];
tipOptions.forEach(option => {
if (option.tagName === "INPUT" && option.value.length) option.addEventListener("keyup", () => {
tipOptions.forEach(option => option.classList.remove("active"));
option.classList.toggle("active");
})
if (!(option.type == "submit")) option.addEventListener("click", () => {
tipOptions.forEach(option => option.classList.remove("active"));
option.classList.toggle("active");
})
})
form.addEventListener("submit", event => {
event.preventDefault();
checkInputForError(peopleElem, peopleError, true);
checkInputForError(billElem, billError, false);
if (billError || peopleError) return;
const tipCalculator = new TipCalc();
const tip = isNaN(tipCalculator.getTipPerPerson()) ? 0 : tipCalculator.getTipPerPerson();
const total = isNaN(tipCalculator.getTotalPerPerson()) ? 0 : tipCalculator.getTotalPerPerson();
const formatter = new Intl.NumberFormat(undefined, {
style: "currency",
currency: "USD",
signDisplay: "never"
});
tipPerPersonElem.innerText = formatter.format(tip);
totalPerPersonElem.innerText = formatter.format(total);
submit.style.display = "none";
const resetBtn = document.querySelector("[type=\"reset\"]");
resetBtn.style.display = "block";
resetBtn.addEventListener("click", () => {
reset()
resetBtn.style.display = "none";
submit.style.display = "block";
})
})
document.addEventListener("DOMContentLoaded", () => {
reset()
})
peopleElem.addEventListener("keyup", () => checkInputForError(peopleElem, peopleError, true));
billElem.addEventListener("keyup", () => checkInputForError(billElem, billError, false));
function checkInputForError(input, error, showError) {
const value = input.value.trim() || 0;
if (!value || isNaN(parseFloat(value)) || parseFloat(value) == 0) {
if (showError) document.querySelector(".warning").style.display = "inline";
input.classList.add("error");
error = true;
} else {
if (showError) document.querySelector(".warning").style.display = "none";
input.classList.remove("error");
input.classList.add("correct");
error = false;
}
}
function reset(submit = false) {
const tipPerPersonElem = document.querySelector("[data-tip-person]");
const totalPerPersonElem = document.querySelector("[data-total-person]");
tipPerPersonElem.innerText = "";
totalPerPersonElem.innerText = "";
console.log(tipPerPersonElem.innerText, totalPerPersonElem.innerText, "reset", submit);
tipOptions.forEach(option => option.classList.remove("active"));
document.querySelectorAll("input").forEach(input => {
input.classList.remove("correct");
input.classList.remove("error");
input.value = "";
})
}
:root {
--primary-color: hsl(172, 67%, 45%);
--very-dark-cyan: hsl(183, 100%, 15%);
--dark-grayish-cyan: hsl(186, 14%, 43%);
--grayish-cyan: hsl(184, 14%, 56%);
--light-grayish-cyan: hsl(185, 41%, 84%);
--very-light-grayish-cyan: hsl(189, 41%, 97%);
--white: hsl(0, 0%, 100%);
--primary-font-size: 24px;
--primary-font-family: 'Space Mono', monospace;
}
/* GLOABAL TAGS */
body {
width: 100%;
margin: 0;
overflow: hidden;
font-family: var(--primary-font-family);
background-color: var(--light-grayish-cyan);
}
header {
text-align: center;
}
h1 {
color: var(--very-dark-cyan);
margin-top: 0;
text-transform: uppercase;
}
h1 span {
display: block;
margin: 0;
}
label {
display: block;
text-transform: capitalize;
}
button {
outline: none;
border: none;
text-align: center;
background-color: var(--very-dark-cyan);
font-size: var(--primary-font-size);
color: var(--white);
text-transform: capitalize;
margin: 8px;
padding-top: 8px;
padding-bottom: 8px;
border-radius: 4px;
cursor: pointer;
}
legend {
margin-bottom: 8px;
}
/* Chrome,
Safari,
Edge, */
/* Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
input {
display: block;
border: none;
background-color: var(--very-light-grayish-cyan);
font-size: var(--primary-font-size);
height: 30px;
color: var(--very-dark-cyan);
background-repeat: no-repeat;
background-position: left center;
}
input:not(#custom) {
text-indent: 99.8%;
}
aside {
font-size: 11px;
text-align: center;
}
aside a {
color: hsl(228, 45%, 44%);
}
/* END OF GLOBAL TAGS GENERIC IDs */
#bill {
background-image: url('https://kaustubhmaladkar.github.io/Tip-Calculator/images/icon-dollar.svg');
}
#people {
background-image: url('https://kaustubhmaladkar.github.io/Tip-Calculator/images/icon-person.svg');
}
/* END OF GENERIC IDs GENERIC CLASSES*/
button,
#custom {
width: calc(50% - 20px);
font-weight: bold;
}
/* END OF GENERIC CLASSES */
/* INPUT */
.input {
background-color: var(--white);
color: var(--dark-grayish-cyan);
border-top-right-radius: 20px;
border-top-left-radius: 20px;
margin-top: 20px;
padding-bottom: 30px;
}
.input legend {
margin-top: 20px;
margin-left: 20px;
}
legend:nth-of-type(2) label {
width: 100%;
}
legend:nth-of-type(2) {
display: flex;
flex-wrap: wrap;
}
[for="people"] {
display: inline;
}
.warning {
display: none;
/* margin-left: 92px; */
color: red;
font-size: 12px;
background-color: transparent;
}
input#custom {
background-color: var(--white);
color: var(--dark-grayish-cyan);
margin-top: 12px;
margin-left: 2px;
padding-bottom: 8px;
opacity: 1;
}
input#custom::placeholder {
text-transform: capitalize;
color: var(--dark-grayish-cyan);
opacity: 1;
}
/* END OF INPUT */
/*OUTPUT*/
.output {
background-color: var(--very-dark-cyan);
display: flex;
margin-top: -8px;
justify-content: center;
align-items: center;
flex-direction: column;
border-radius: 10px;
}
.output div,
.output span {
width: 100%;
}
.output>div>div {
display: flex;
gap: 15px;
}
.output>div>div:first-of-type {
margin-top: 30px;
margin-bottom: 15px;
}
.output>div>div:last-of-type {
margin-top: 15px;
margin-bottom: 30px;
}
[type="submit"],
[type="reset"] {
font-family: var(--primary-font-family);
background-color: var(--primary-color);
width: 90%;
text-align: center;
color: var(--very-dark-cyan);
}
.tip-person,
.total-person {
font-size: 35px;
color: var(--primary-color);
}
.output>div>div>div>span:first-of-type {
text-transform: capitalize;
color: var(--white);
display: block;
}
.output>div>div>div>span:last-of-type {
color: var(--grayish-cyan);
}
/*END OF OUTPUT */
.active:not(input) {
background-color: var(--primary-color);
color: var(--very-dark-cyan);
transition: background 0.7s ease-in-out;
}
.correct {
border: lightgreen 2px solid;
}
.error {
border: red 2px solid;
}
.correct:focus,
.error:focus {
outline: none;
}
/* JAVASCRIPT CLASSES */
/* END OF JAVASCRIPT CLASSES */
/* FOR DESKTOP */
@media (min-width: 1200px) {
/* RESET */
html,
body,
main {
margin: 0;
}
/* END OF RESET */
/* GENERIC TAGS */
form {
width: 100%;
max-width: 900px;
border-radius: 15px;
overflow: hidden;
margin: auto;
padding-right: 15px;
display: flex;
width: fit-content;
background-color: var(--white);
}
input {
width: 90%;
}
aside {
display: none;
}
/* END OF GENERIC TAGS */
/* GENERIC CLASSES */
.output,
.input {
height: 400px;
}
.warning {
margin-left: 92px;
}
/* END OF GENERIC CLASSES */
/* INPUT */
.input button,
.input input#custom {
width: calc(100% / 3 - 20px);
}
.input {
width: 50%;
padding-bottom: 0;
}
.input legend {
margin-left: 25px;
}
/* END OF INPUT */
/* OUTPUT */
.output {
width: 50%;
margin: 22px;
padding: 0;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.output div {
margin-left: 20px;
}
.output>div>div:first-of-type {
margin-top: -20px;
margin-bottom: 40px;
}
[type="reset"] {
display: none;
}
/* END OF OUTPUT */
}
<h1>
<span>spli</span>
<span>tter</span>
</h1>
<form action="post">
<div >
<legend>
<label for="bill">bill</label>
<input type="number" name="bill" id="bill" >
</legend>
<legend>
<label for="custom">select tip %</label>
<button type="button">5%</button>
<button type="button" >10%</button>
<button type="button">15%</button>
<button type="button">25%</button>
<button type="button">50%</button>
<input placeholder="custom" name="custom" id="custom" >
</legend>
<legend>
<label for="people">Number of People</label>
<p style="display: inline;">Can't be zero</p>
<input type="number" name="people" id="people" >
</legend>
</div>
<div >
<div>
<div>
<div>
<span>tip amount</span>
<span>/ person</span>
</div>
<span data-tip-person=""></span>
</div>
<div>
<div>
<span>Total</span>
<span>/ person</span>
</div>
<span data-total-person=""></span>
</div>
</div>
<button type="submit" style="display: block;">Calculate</button>
<button type="reset" style="display: none;">Reset</button>
</div>
</form>
Live site: https://kaustubhmaladkar.github.io/Tip-Calculator/
Code on Github: https://github.com/KaustubhMaladkar/Tip-Calculator/
CodePudding user response:
The problem comes from this line:
input:not(#custom) {
text-indent: 99.8%;
}
If you only want a alignment to the right, change it to:
input:not(#custom) {
text-align: right;
}
Working example:
const peopleElem = document.querySelector("#people");
const billElem = document.querySelector("#bill");
const submit = document.querySelector("[type=\"submit\"]");
const form = document.querySelector("form");
const tipPerPersonElem = document.querySelector("[data-tip-person]");
const totalPerPersonElem = document.querySelector("[data-total-person]");
let billError = peopleError = false;
class TipCalc {
constructor() {
this.tipPerPerson = 0;
this.totalPerPerson = 0;
this.tip = 0
this.tipPercent = 0;
this.bill = parseFloat(billElem.value);
this.people = parseFloat(peopleElem.value);
}
getTip() {
const element = document.querySelector(".active");
if (!element) return 0;
if (element.tagName === "BUTTON") return this.tipPercent = element.innerText.replace("%", "");
return this.tipPercent = element.value.replace("%", "");
}
getTipPerPerson() {
this.getTip();
this.tip = ((this.tipPercent / 100) * this.bill);
this.tipPerPerson = this.tip / this.people;
return this.tipPerPerson;
}
getTotalPerPerson() {
this.getTipPerPerson();
this.totalPerPerson = (this.bill this.tip) / this.people
return this.totalPerPerson;
}
}
const tipOptions = [...document.querySelectorAll("button"), document.querySelector("#custom")];
tipOptions.forEach(option => {
if (option.tagName === "INPUT" && option.value.length) option.addEventListener("keyup", () => {
tipOptions.forEach(option => option.classList.remove("active"));
option.classList.toggle("active");
})
if (!(option.type == "submit")) option.addEventListener("click", () => {
tipOptions.forEach(option => option.classList.remove("active"));
option.classList.toggle("active");
})
})
form.addEventListener("submit", event => {
event.preventDefault();
checkInputForError(peopleElem, peopleError, true);
checkInputForError(billElem, billError, false);
if (billError || peopleError) return;
const tipCalculator = new TipCalc();
const tip = isNaN(tipCalculator.getTipPerPerson()) ? 0 : tipCalculator.getTipPerPerson();
const total = isNaN(tipCalculator.getTotalPerPerson()) ? 0 : tipCalculator.getTotalPerPerson();
const formatter = new Intl.NumberFormat(undefined, {
style: "currency",
currency: "USD",
signDisplay: "never"
});
tipPerPersonElem.innerText = formatter.format(tip);
totalPerPersonElem.innerText = formatter.format(total);
submit.style.display = "none";
const resetBtn = document.querySelector("[type=\"reset\"]");
resetBtn.style.display = "block";
resetBtn.addEventListener("click", () => {
reset()
resetBtn.style.display = "none";
submit.style.display = "block";
})
})
document.addEventListener("DOMContentLoaded", () => {
reset()
})
peopleElem.addEventListener("keyup", () => checkInputForError(peopleElem, peopleError, true));
billElem.addEventListener("keyup", () => checkInputForError(billElem, billError, false));
function checkInputForError(input, error, showError) {
const value = input.value.trim() || 0;
if (!value || isNaN(parseFloat(value)) || parseFloat(value) == 0) {
if (showError) document.querySelector(".warning").style.display = "inline";
input.classList.add("error");
error = true;
} else {
if (showError) document.querySelector(".warning").style.display = "none";
input.classList.remove("error");
input.classList.add("correct");
error = false;
}
}
function reset(submit = false) {
const tipPerPersonElem = document.querySelector("[data-tip-person]");
const totalPerPersonElem = document.querySelector("[data-total-person]");
tipPerPersonElem.innerText = "";
totalPerPersonElem.innerText = "";
console.log(tipPerPersonElem.innerText, totalPerPersonElem.innerText, "reset", submit);
tipOptions.forEach(option => option.classList.remove("active"));
document.querySelectorAll("input").forEach(input => {
input.classList.remove("correct");
input.classList.remove("error");
input.value = "";
})
}
:root {
--primary-color: hsl(172, 67%, 45%);
--very-dark-cyan: hsl(183, 100%, 15%);
--dark-grayish-cyan: hsl(186, 14%, 43%);
--grayish-cyan: hsl(184, 14%, 56%);
--light-grayish-cyan: hsl(185, 41%, 84%);
--very-light-grayish-cyan: hsl(189, 41%, 97%);
--white: hsl(0, 0%, 100%);
--primary-font-size: 24px;
--primary-font-family: 'Space Mono', monospace;
}
/* GLOABAL TAGS */
body {
width: 100%;
margin: 0;
overflow: hidden;
font-family: var(--primary-font-family);
background-color: var(--light-grayish-cyan);
}
header {
text-align: center;
}
h1 {
color: var(--very-dark-cyan);
margin-top: 0;
text-transform: uppercase;
}
h1 span {
display: block;
margin: 0;
}
label {
display: block;
text-transform: capitalize;
}
button {
outline: none;
border: none;
text-align: center;
background-color: var(--very-dark-cyan);
font-size: var(--primary-font-size);
color: var(--white);
text-transform: capitalize;
margin: 8px;
padding-top: 8px;
padding-bottom: 8px;
border-radius: 4px;
cursor: pointer;
}
legend {
margin-bottom: 8px;
}
/* Chrome,
Safari,
Edge, */
/* Opera */
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* Firefox */
input[type=number] {
-moz-appearance: textfield;
}
input {
display: block;
border: none;
background-color: var(--very-light-grayish-cyan);
font-size: var(--primary-font-size);
height: 30px;
color: var(--very-dark-cyan);
background-repeat: no-repeat;
background-position: left center;
}
input:not(#custom) {
text-align: right;
}
aside {
font-size: 11px;
text-align: center;
}
aside a {
color: hsl(228, 45%, 44%);
}
/* END OF GLOBAL TAGS GENERIC IDs */
#bill {
background-image: url('https://kaustubhmaladkar.github.io/Tip-Calculator/images/icon-dollar.svg');
}
#people {
background-image: url('https://kaustubhmaladkar.github.io/Tip-Calculator/images/icon-person.svg');
}
/* END OF GENERIC IDs GENERIC CLASSES*/
button,
#custom {
width: calc(50% - 20px);
font-weight: bold;
}
/* END OF GENERIC CLASSES */
/* INPUT */
.input {
background-color: var(--white);
color: var(--dark-grayish-cyan);
border-top-right-radius: 20px;
border-top-left-radius: 20px;
margin-top: 20px;
padding-bottom: 30px;
}
.input legend {
margin-top: 20px;
margin-left: 20px;
}
legend:nth-of-type(2) label {
width: 100%;
}
legend:nth-of-type(2) {
display: flex;
flex-wrap: wrap;
}
[for="people"] {
display: inline;
}
.warning {
display: none;
/* margin-left: 92px; */
color: red;
font-size: 12px;
background-color: transparent;
}
input#custom {
background-color: var(--white);
color: var(--dark-grayish-cyan);
margin-top: 12px;
margin-left: 2px;
padding-bottom: 8px;
opacity: 1;
}
input#custom::placeholder {
text-transform: capitalize;
color: var(--dark-grayish-cyan);
opacity: 1;
}
/* END OF INPUT */
/*OUTPUT*/
.output {
background-color: var(--very-dark-cyan);
display: flex;
margin-top: -8px;
justify-content: center;
align-items: center;
flex-direction: column;
border-radius: 10px;
}
.output div,
.output span {
width: 100%;
}
.output>div>div {
display: flex;
gap: 15px;
}
.output>div>div:first-of-type {
margin-top: 30px;
margin-bottom: 15px;
}
.output>div>div:last-of-type {
margin-top: 15px;
margin-bottom: 30px;
}
[type="submit"],
[type="reset"] {
font-family: var(--primary-font-family);
background-color: var(--primary-color);
width: 90%;
text-align: center;
color: var(--very-dark-cyan);
}
.tip-person,
.total-person {
font-size: 35px;
color: var(--primary-color);
}
.output>div>div>div>span:first-of-type {
text-transform: capitalize;
color: var(--white);
display: block;
}
.output>div>div>div>span:last-of-type {
color: var(--grayish-cyan);
}
/*END OF OUTPUT */
.active:not(input) {
background-color: var(--primary-color);
color: var(--very-dark-cyan);
transition: background 0.7s ease-in-out;
}
.correct {
border: lightgreen 2px solid;
}
.error {
border: red 2px solid;
}
.correct:focus,
.error:focus {
outline: none;
}
/* JAVASCRIPT CLASSES */
/* END OF JAVASCRIPT CLASSES */
/* FOR DESKTOP */
@media (min-width: 1200px) {
/* RESET */
html,
body,
main {
margin: 0;
}
/* END OF RESET */
/* GENERIC TAGS */
form {
width: 100%;
max-width: 900px;
border-radius: 15px;
overflow: hidden;
margin: auto;
padding-right: 15px;
display: flex;
width: fit-content;
background-color: var(--white);
}
input {
width: 90%;
}
aside {
display: none;
}
/* END OF GENERIC TAGS */
/* GENERIC CLASSES */
.output,
.input {
height: 400px;
}
.warning {
margin-left: 92px;
}
/* END OF GENERIC CLASSES */
/* INPUT */
.input button,
.input input#custom {
width: calc(100% / 3 - 20px);
}
.input {
width: 50%;
padding-bottom: 0;
}
.input legend {
margin-left: 25px;
}
/* END OF INPUT */
/* OUTPUT */
.output {
width: 50%;
margin: 22px;
padding: 0;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.output div {
margin-left: 20px;
}
.output>div>div:first-of-type {
margin-top: -20px;
margin-bottom: 40px;
}
[type="reset"] {
display: none;
}
/* END OF OUTPUT */
}
<h1>
<span>spli</span>
<span>tter</span>
</h1>
<form action="post">
<div >
<legend>
<label for="bill">bill</label>
<input type="number" name="bill" id="bill" >
</legend>
<legend>
<label for="custom">select tip %</label>
<button type="button">5%</button>
<button type="button" >10%</button>
<button type="button">15%</button>
<button type="button">25%</button>
<button type="button">50%</button>
<input placeholder="custom" name="custom" id="custom" >
</legend>
<legend>
<label for="people">Number of People</label>
<p style="display: inline;">Can't be zero</p>
<input type="number" name="people" id="people" >
</legend>
</div>
<div >
<div>
<div>
<div>
<span>tip amount</span>
<span>/ person</span>
</div>
<span data-tip-person=""></span>
</div>
<div>
<div>
<span>Total</span>
<span>/ person</span>
</div>
<span data-total-person=""></span>
</div>
</div>
<button type="submit" style="display: block;">Calculate</button>
<button type="reset" style="display: none;">Reset</button>
</div>
</form>