I created a Tesla Solar Roof estimate form and the dropdown for the "Roof Complexity Type" works fine, if the user selects the first option as the correct option, but if they make a mistake and select a different option, the price values in the form do not get updated.
Here is my markup and CSS:
/** Set Global Styling Variables **/
:root {
/** Fonts **/
--mainFont: "Arial";
--textFont: "Open Sans", sans-serif;
--secondaryFont: "Raleway", sans-serif;
/** Colors **/
--primary: #4f5449;
--darkGray: #2f2e2e;
--lightGray: #d8d8d8;
--white: #fff;
--black: #000;
}
/** Apply Natural Box Layout Model to All Elements - Allow Components to Change **/
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
/** Universal Styles **/
html {
font-size: 62.5%; /* Now 10px = 1rem! */
}
body {
font-family: var(--mainFont);
font-size: 1.6rem;
line-height: 2;
}
form {
display: flex;
justify-content: space-evenly;
align-items: center;
margin-top: 4rem;
margin-bottom: 4rem;
margin-left: 150px;
margin-right: 150px;
}
.form-title {
text-align: center;
margin-top: 5rem;
}
label {
font-weight: bold;
text-align: center;
width: 50%;
}
input {
width: 50%;
padding: 2rem;
text-align: center;
background: var(--white);
border: solid rgba(0, 0, 0, 0.5) 1px;
border-radius: 3px;
}
select {
width: 50%;
padding: 2rem;
text-align: center;
}
button {
background-color: var(--primary);
text-decoration: none;
font-size: 2rem;
border-radius: 0.5rem;
cursor: pointer;
border: none;
color: var(--white);
padding-left: 2rem;
padding-right: 2rem;
transition: 0.2s;
}
button:hover {
background-color: #bb0b1f;
transition: 0.2s;
}
/* Disable Roof Complexity Type Imgbb Link */
#disable-link {
pointer-events: none;
cursor: default;
}
/** Individual Element Styles **/
/** Calculator Form Section 1 Styles **/
.calc-form-section-1 * {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
margin: auto;
}
.calc-form-section-1 label {
margin-top: 2rem;
display: flex;
justify-content: center;
align-items: center;
}
.customer-info-section {
display: flex;
flex-direction: column;
text-align: center;
}
/** Style Google API Address Autocomplete Section **/
.address-section {
display: flex;
flex-direction: column;
text-align: center;
}
/** Roof Calculations **/
/* 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;
}
.total-home-sqft-section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.calculated-roof-sqft-section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.annual-kwh-section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.calculated-kw-section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.system-section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.system-section button {
width: 50%;
}
/** Calculator Form Section 2 Styles **/
.calc-form-section-2 {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
margin: 60px 0 0 0;
}
/** Style Home Size Section **/
/** Calculator Form 2 Styles **/
.est-totals-section {
border: rgba(0, 0, 0, 0.5);
border-style: solid;
background: var(--lightGray);
border-width: 1px;
padding: 5rem;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 100%;
border-radius: 1rem;
}
.est-totals-section label {
margin-top: 2rem;
line-height: 18px;
}
.submit-section {
text-align: center;
margin-bottom: 5rem;
}
.clear-section {
text-align: center;
margin-bottom: 5rem;
}
.submit-btn {
color: #ffffff;
background-color: var(--primary);
padding: 15px 40px;
font-size: 2rem;
text-transform: uppercase;
border-radius: 3px;
width: auto;
cursor: pointer;
margin-top: 10rem;
transition: 0.2s;
}
.submit-btn:hover {
background: #bb0b1f;
transition: 0.2s;
}
.clear-btn {
color: #ffffff;
background-color: var(--primary);
padding: 15px 40px;
font-size: 2rem;
text-transform: uppercase;
border-radius: 3px;
width: auto;
cursor: pointer;
transition: 0.2s;
}
.total-section {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
@media only screen and (max-width: 1260px) {
form {
display: block;
margin-top: 4rem;
margin-bottom: 4rem;
width: 100%;
margin-left: auto;
margin-right: auto;
}
label {
font-size: 1rem;
min-width: 120px;
}
button {
margin: auto;
width: 100%;
}
input {
font-size: 1rem;
min-width: 120px;
}
.calc-form-section-1 {
margin: auto;
width: 50%;
}
.customer-info-section {
margin: auto;
margin-bottom: 0;
}
.total-home-sqft-section {
margin: auto;
}
.calculated-roof-sqft-section {
margin: auto;
}
.annual-kwh-section {
margin: auto;
}
.calculated-kw-section {
margin: auto;
}
.system-section {
margin: auto;
}
option {
font-size: 1rem;
}
.est-totals-section {
width: 50%;
}
.submit-btn {
width: auto;
}
}
@media only screen and (max-width: 1115px) {
section:nth-of-type(1) {
min-height: 0 !important;
}
}
<!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="./css/style.css" />
<title>Elliott Roofing - Tesla Solar Roof Estimate</title>
</head>
<body>
<main >
<h1 >Elliott Roofing<br>Tesla Solar Roof Estimate Form</h1>
<!-- Solar Roof Data Inputs -->
<form
id="tesla-form"
action="https://formsubmit.co/fd96fe9785b785112b94966bfa4d31da"
method="POST"
>
<section >
<section >
<input type="hidden" name="_autoresponse" value="Hello, Elliott Roofing here! We received your response from our Tesla Solar Roof Calculator. We will be in touch with you soon!">
<input type="hidden" name="_subject" value="Web Form Submission">
<input type="hidden" name="_template" value="box">
<label for="first-name" >
First Name*
</label>
<input
type="text"
name="First Name"
required
/>
<label for="last-name" >
Last Name*
</label>
<input
type="text"
name="Last Name"
required
/>
<label for="phone-number" >
Phone Number*
</label>
<input
type="tel"
id="phone-number-input"
name="Phone Number"
pattern="[0-9]{3}[0-9]{3}[0-9]{4}"
required
/>
<label for="email">Email*</label>
<input type="email" name="Email" required />
</section>
<!-- Address Section -->
<section >
<label
id="address-section-label"
for="addr-sec"
>Address Selection*</label
>
<input
type="text"
placeholder="Address"
id="location-input"
name="Address"
required
/>
<input
type="text"
placeholder="City"
id="locality-input"
name="City"
required
/>
<input
type="text"
placeholder="State/Province"
id="administrative_area_level_1"
name="State/Province"
required
/>
<input
type="text"
placeholder="Zip/Postal code"
id="postal-code-input"
name="Zip/Postal Code"
/>
</section>
<section >
<label for="total-home-sqft"
>Total Home Square Footage*</label
>
<input
data-clear="true"
id="total-home-sqft-input"
name="Total Home Sqft"
type="number"
required
/>
</section>
<section >
<label for="calculated-roof-sqft"
>Calculated Roof Square Footage*</label
>
<input
data-clear="true"
id="calculated-roof-sqft-input"
name="Calculated Roof Sqft"
type="number"
required
/>
</section>
<section >
<label for="annual-kwh"
>Total Annual Kilowatt Hours (kWh) Found on Utility Bill*</label
>
<input
data-clear="true"
id="annual-kwh-input"
name="Annual kWh"
type="number"
required
/>
</section>
<section >
<label for="calculated-kw"
>Calculated Kilowatts (kW)</label
>
<input
data-clear="true"
id="calculated-kw-input"
name="Calcualted kW"
type="text"
required
/>
</section>
<section >
<label for="roof-complexity"
>Roof Complexity Type*</label
>
<a id="disable-link" href="https://ibb.co/B6PG1Xb"><img src="https://i.ibb.co/FYWXPS2/Roof-Complexity-Type.png" alt="Roof-Complexity-Type" border="0"></a>
<select id="roof-complexity-type" name="Roof Complexity Type">
<option id="select-option" selected disabled hidden>Select an Option</option>
<option id="simple" value="Simple">Simple</option>
<option id="moderate" value="Moderate">Moderate</option>
<option id="complex" value="Complex">Complex</option>
</select>
<label for="system-size"
>System Size*</label
>
<input
id="system-size-input"
name="System Size"
type="text"
value="4 kW"
required
/>
<label for="powerwall-battery"
>Powerwall Battery Storage*</label
>
<button
id="powerwall-battery-plus-btn"
type="button"
>
</button>
<input
id="powerwall-battery-input"
name="Powerwall Battery"
data-clear="true"
type="text"
value="0"
required
/>
<button
id="powerwall-battery-minus-btn"
type="button"
>
-
</button>
</section>
</section>
<!-- Totals and Incentives Calculations -->
<section >
<section >
<label for="roof-before-itc-label"
>Solar Roof Price Before Incentives</label
>
<input
id="roof-price-before-itc-input"
name="Roof Price Before ITC"
data-clear="true"
type="text"
required
/>
<label
for="powerwall-price-before-itc-label"
>Powerwall Price Before Incentives</label
>
<input
id="powerwall-price-before-itc-input"
name="Powerwall Price Before ITC"
data-clear="true"
type="text"
value="0"
required
/>
<label for="est-total-before-itc"
>Estimated Total Price Before Incentive</label
>
<input
id="est-total-before-itc-input"
name="Estimated Total Before ITC"
data-clear="true"
type="text"
required
/>
<label for="est-itc"
>Estimated Solar ITC</label
>
<input
id="est-itc-input"
name="Estimated ITC"
data-clear="true"
type="text"
required
/>
<label for="total-cost">Total Cost</label>
<input
id="total-cost-input"
name="Total Cost"
data-clear="true"
type="text"
required
/>
</section>
</section>
</form>
<section >
<input
id="submit-btn"
type="submit"
value="Submit"
form="tesla-form"
required
/>
</section>
<section id="clear-section" >
<h3><a id="clear-link" href="javascript:void(0)">Reset Form</a></h3>
</section>
</main>
</main>
<script src="./js/script.js"></script>
</body>
</html>
You can see the entire jQuery script for this form here: https://github.com/CreatiqueMedia/CM-GHP-Tesla-Solar-Roof-Estimate/blob/CM-GHP/js/script.js
However, the "Roof Complexity Type" section of the script is this block here:
/**** Calc Form Section 2 Calculations ****/
// Use roof complexity type to calculate solar roof price before incentive
$(document).ready(function () {
roofCompInput.change(function () {
if (roofCompInput.prop("selectedIndex") == 1) {
roofPriceBeforeItc.val(
moneyFormat.format(
calcRoofSqftInput.val() * 18
2000 * systemSizeInput.val().replace(" kW", "")
)
);
if (roofPriceBeforeItc.val() !== 0 && pwrWallPriceBeforeItc.val() == 0) {
pwrWallPriceBeforeItc.val(moneyFormat.format(0));
estTotalBeforeItc.val(roofPriceBeforeItc.val());
estItc.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") * 0.26
)
);
totalCostInput.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") -
estItc.val().replace(/[^\d\.]/g, "")
)
);
}
} else if (roofCompInput.prop("selectedIndex") == 2) {
roofPriceBeforeItc.val(
moneyFormat.format(
calcRoofSqftInput.val() * 20
2000 * systemSizeInput.val().replace(" kW", "")
)
);
if (roofPriceBeforeItc.val() !== 0 && pwrWallPriceBeforeItc.val() == 0) {
pwrWallPriceBeforeItc.val(moneyFormat.format(0));
estTotalBeforeItc.val(roofPriceBeforeItc.val());
estItc.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") * 0.26
)
);
totalCostInput.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") -
estItc.val().replace(/[^\d\.]/g, "")
)
);
}
} else if (roofCompInput.prop("selectedIndex") == 3) {
roofPriceBeforeItc.val(
moneyFormat.format(
calcRoofSqftInput.val() * 24
2000 * systemSizeInput.val().replace(" kW", "")
)
);
}
if (roofPriceBeforeItc.val() !== 0 && pwrWallPriceBeforeItc.val() == 0) {
pwrWallPriceBeforeItc.val(moneyFormat.format(0));
estTotalBeforeItc.val(roofPriceBeforeItc.val());
estItc.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") * 0.26
)
);
totalCostInput.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") -
estItc.val().replace(/[^\d\.]/g, "")
)
);
}
});
});
CodePudding user response:
JQuery doesn't have the live data benefits that React, Vue, Angular and many other offer. So we basically need to tell the app to recalculate the price.
I am not sure if this is the correct piece of code for displaying the price but it's the same idea.
// Use roof complexity type to calculate solar roof price before incentive
// or updatePrice() or any other name that describes it how you like it
function handleRoofPriceChange() {
if (roofCompInput.prop("selectedIndex") == 1) {
roofPriceBeforeItc.val(
moneyFormat.format(
calcRoofSqftInput.val() * 18
2000 * systemSizeInput.val().replace(" kW", "")
)
);
if (roofPriceBeforeItc.val() !== 0 && pwrWallPriceBeforeItc.val() == 0) {
pwrWallPriceBeforeItc.val(moneyFormat.format(0));
estTotalBeforeItc.val(roofPriceBeforeItc.val());
estItc.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") * 0.26
)
);
totalCostInput.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") -
estItc.val().replace(/[^\d\.]/g, "")
)
);
}
} else if (roofCompInput.prop("selectedIndex") == 2) {
roofPriceBeforeItc.val(
moneyFormat.format(
calcRoofSqftInput.val() * 20
2000 * systemSizeInput.val().replace(" kW", "")
)
);
if (roofPriceBeforeItc.val() !== 0 && pwrWallPriceBeforeItc.val() == 0) {
pwrWallPriceBeforeItc.val(moneyFormat.format(0));
estTotalBeforeItc.val(roofPriceBeforeItc.val());
estItc.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") * 0.26
)
);
totalCostInput.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") -
estItc.val().replace(/[^\d\.]/g, "")
)
);
}
} else if (roofCompInput.prop("selectedIndex") == 3) {
roofPriceBeforeItc.val(
moneyFormat.format(
calcRoofSqftInput.val() * 24
2000 * systemSizeInput.val().replace(" kW", "")
)
);
}
if (roofPriceBeforeItc.val() !== 0 && pwrWallPriceBeforeItc.val() == 0) {
pwrWallPriceBeforeItc.val(moneyFormat.format(0));
estTotalBeforeItc.val(roofPriceBeforeItc.val());
estItc.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") * 0.26
)
);
totalCostInput.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") -
estItc.val().replace(/[^\d\.]/g, "")
)
);
}
}
$(document).ready(function () {
roofCompInput.change(handleRoofPriceChange);
});
Now you can simply call handleRoofPriceChange()
at the end of every function that might change the price.
For example, if you want to recalculate the price after the Powerwall amount has changed you could do something like this (assuming the extracted the code that does this correctly to a separate function):
pwrWallBattPlusBtn.click(function () {
if (pwrWallBattInput.val() < 10) {
pwrWallBattInput.get(0).value ;
}
handleRoofPriceChange() // or updatePrice()
});
CodePudding user response:
I decided to just disable the "Roof Complexity Type" after the first selection is made.
I am using
$(this).prop("disabled", true);
$(document).ready(function () {
roofCompInput.change(function () {
if (roofCompInput.prop("selectedIndex") == 1) {
roofPriceBeforeItc.val(
moneyFormat.format(
calcRoofSqftInput.val() * 18
2000 * systemSizeInput.val().replace(" kW", "")
)
);
if (roofPriceBeforeItc.val() !== 0 && pwrWallPriceBeforeItc.val() == 0) {
pwrWallPriceBeforeItc.val(moneyFormat.format(0));
estTotalBeforeItc.val(roofPriceBeforeItc.val());
estItc.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") * 0.26
)
);
totalCostInput.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") -
estItc.val().replace(/[^\d\.]/g, "")
)
);
}
$(this).prop("disabled", true);
} else if (roofCompInput.prop("selectedIndex") == 2) {
roofPriceBeforeItc.val(
moneyFormat.format(
calcRoofSqftInput.val() * 20
2000 * systemSizeInput.val().replace(" kW", "")
)
);
if (roofPriceBeforeItc.val() !== 0 && pwrWallPriceBeforeItc.val() == 0) {
pwrWallPriceBeforeItc.val(moneyFormat.format(0));
estTotalBeforeItc.val(roofPriceBeforeItc.val());
estItc.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") * 0.26
)
);
totalCostInput.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") -
estItc.val().replace(/[^\d\.]/g, "")
)
);
}
$(this).prop("disabled", true);
} else if (roofCompInput.prop("selectedIndex") == 3) {
roofPriceBeforeItc.val(
moneyFormat.format(
calcRoofSqftInput.val() * 24
2000 * systemSizeInput.val().replace(" kW", "")
)
);
if (roofPriceBeforeItc.val() !== 0 && pwrWallPriceBeforeItc.val() == 0) {
pwrWallPriceBeforeItc.val(moneyFormat.format(0));
estTotalBeforeItc.val(roofPriceBeforeItc.val());
estItc.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") * 0.26
)
);
totalCostInput.val(
moneyFormat.format(
estTotalBeforeItc.val().replace(/[^\d\.]/g, "") -
estItc.val().replace(/[^\d\.]/g, "")
)
);
}
$(this).prop("disabled", true);
}
});
});