diff --git a/app/interactives/compounding-frequency-calculator/page.tsx b/app/interactives/compounding-frequency-calculator/page.tsx
index 202f7a4..d795bbc 100644
--- a/app/interactives/compounding-frequency-calculator/page.tsx
+++ b/app/interactives/compounding-frequency-calculator/page.tsx
@@ -260,25 +260,29 @@ export default function CompoundInterestCalculator() {
type="text"
value={initialAmount}
onChange={(e) => {
- const input = e.target.value;
- const numericPart = input.replace(/[^0-9.]/g, "");
- const numericValue = parseFloat(numericPart);
+ const raw = e.target.value;
+ const numericValue = parseFloat(raw);
+ if (raw === "") {
+ setInitialAmountError("");
+ setInitialAmount("");
+ return;
+ }
if (
!isNaN(numericValue) &&
- numericValue > MAX_INITIAL_AMOUNT
+ (numericValue < 0 || numericValue > MAX_INITIAL_AMOUNT)
) {
setInitialAmountError(
"Enter an amount between $0 and $100,000,000.",
);
- setInitialAmount(numericPart);
+ setInitialAmount(raw);
} else {
setInitialAmountError("");
- setInitialAmount(numericPart);
+ setInitialAmount(raw);
}
- flagSkippedFields("initialAmount")
+ flagSkippedFields("initialAmount");
}}
onBlur={() => {
- flagSkippedFields("initialAmount")
+ flagSkippedFields("initialAmount");
if (initialAmount.startsWith("."))
setInitialAmount("0" + initialAmount);
if (!initialAmount)
@@ -317,26 +321,30 @@ export default function CompoundInterestCalculator() {
{
- const input = e.target.value;
- const numericPart = input.replace(/[^0-9.]/g, "");
- const numericValue = parseFloat(numericPart);
+ const raw = e.target.value;
+ const numericValue = parseFloat(raw);
+ if (raw === "") {
+ setAnnualRateError("");
+ setAnnualRate("");
+ return;
+ }
if (
!isNaN(numericValue) &&
- numericValue > MAX_ANNUAL_RATE
+ (numericValue < 0 || numericValue > MAX_ANNUAL_RATE)
) {
setAnnualRateError("Enter a rate between 0% and 1,000%.");
- setAnnualRate(numericPart);
+ setAnnualRate(raw);
} else {
setAnnualRateError("");
- setAnnualRate(numericPart);
+ setAnnualRate(raw);
}
- flagSkippedFields("annualRate")
+ flagSkippedFields("annualRate");
}}
onBlur={() => {
- flagSkippedFields("annualRate")
+ flagSkippedFields("annualRate");
if (annualRate.startsWith("."))
setAnnualRate("0" + annualRate);
if (!annualRate)
@@ -393,20 +401,20 @@ export default function CompoundInterestCalculator() {
setPeriods(cleaned);
- if (cleaned !== "" && (Number(cleaned) < 0 || Number(cleaned) > maxPeriods)) {
+ if (
+ cleaned !== "" &&
+ (Number(cleaned) < 0 || Number(cleaned) > maxPeriods)
+ ) {
setPeriodsError(
buildPeriodsRangeError(selectedCompounding, maxPeriods),
);
} else {
setPeriodsError("");
}
- flagSkippedFields("periods")
- }}
- onKeyDown={(e) => {
- if (e.key === "-" || e.key === "e") e.preventDefault();
+ flagSkippedFields("periods");
}}
onBlur={() => {
- flagSkippedFields("periods")
+ flagSkippedFields("periods");
if (periods.startsWith(".")) setPeriods("0" + periods);
if (!periods)
setTimeout(
diff --git a/app/interactives/present-value-calculator-v2/page.tsx b/app/interactives/present-value-calculator-v2/page.tsx
index ca6c3d6..d97aa82 100644
--- a/app/interactives/present-value-calculator-v2/page.tsx
+++ b/app/interactives/present-value-calculator-v2/page.tsx
@@ -58,7 +58,7 @@ function buildPeriodsRangeError(compounding: CompoundingFrequency, max: number):
const maxFormatted = max.toLocaleString("en-US")
const base = `Enter a number of ${label} between 0 and ${maxFormatted}.`
if (compounding === "annually") return base
- return `${base} (${maxFormatted} periods = 100 years with ${freqLabels[compounding]} compounding).`
+ return `${base} (${maxFormatted} ${label} = 100 years with ${freqLabels[compounding]} compounding).`
}
// Prevents -0 from displaying in results (e.g. when future value equals present value).
@@ -296,7 +296,7 @@ export default function PresentValueCalculator() {
setTimeout(
() =>
setFutureValueError(
- "Please enter a future value to calculate.",
+ "Please enter a future value.",
),
150,
);