简体   繁体   中英

Detect change for dropdown using jQuery

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 class="calc-wrapper"> <h1 class="form-title">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 class="calc-form-section-1"> <section class="customer-info-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" class="first-name-label"> First Name* </label> <input type="text" class="input" name="First Name" required /> <label for="last-name" class="name last-name-label"> Last Name* </label> <input type="text" class="input" name="Last Name" required /> <label for="phone-number" class="phone-number"> Phone Number* </label> <input type="tel" class="phone-number" id="phone-number-input" name="Phone Number" pattern="[0-9]{3}[0-9]{3}[0-9]{4}" required /> <label class="email-label" for="email">Email*</label> <input type="email" class="input" name="Email" required /> </section> <.-- Address Section --> <section class="address-section"> <label class="address-section-label" id="address-section-label" for="addr-sec" >Address Selection*</label > <input type="text" class="input" placeholder="Address" id="location-input" name="Address" required /> <input type="text" class="input" placeholder="City" id="locality-input" name="City" required /> <input type="text" class="input" placeholder="State/Province" id="administrative_area_level_1" name="State/Province" required /> <input type="text" class="input" placeholder="Zip/Postal code" id="postal-code-input" name="Zip/Postal Code" /> </section> <section class="total-home-sqft-section"> <label class="total-home-sqft-label" for="total-home-sqft" >Total Home Square Footage*</label > <input class="input" data-clear="true" id="total-home-sqft-input" name="Total Home Sqft" type="number" required /> </section> <section class="calculated-roof-sqft-section"> <label class="calculated-roof-sqft-label" for="calculated-roof-sqft" >Calculated Roof Square Footage*</label > <input class="input" data-clear="true" id="calculated-roof-sqft-input" name="Calculated Roof Sqft" type="number" required /> </section> <section class="annual-kwh-section"> <label class="annual-kwh-label" for="annual-kwh" >Total Annual Kilowatt Hours (kWh) Found on Utility Bill*</label > <input class="input" data-clear="true" id="annual-kwh-input" name="Annual kWh" type="number" required /> </section> <section class="calculated-kw-section"> <label class="calculate-kw-label" for="calculated-kw" >Calculated Kilowatts (kW)</label > <input class="input" data-clear="true" id="calculated-kw-input" name="Calcualted kW" type="text" required /> </section> <section class="system-section"> <label class="roof-complexity-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 class="system-size-label" for="system-size" >System Size*</label > <input class="input" id="system-size-input" name="System Size" type="text" value="4 kW" required /> <label class="powerwall-battery-label" for="powerwall-battery" >Powerwall Battery Storage*</label > <button id="powerwall-battery-plus-btn" class="btn powerwall-battery-plus-btn" type="button" > + </button> <input class="input" id="powerwall-battery-input" name="Powerwall Battery" data-clear="true" type="text" value="0" required /> <button id="powerwall-battery-minus-btn" class="btn powerwall-battery-minus-btn" type="button" > - </button> </section> </section> <!-- Totals and Incentives Calculations --> <section class="calc-form-section-2"> <section class="est-totals-section"> <label class="roof-before-itc-label" for="roof-before-itc-label" >Solar Roof Price Before Incentives</label > <input class="input" id="roof-price-before-itc-input" name="Roof Price Before ITC" data-clear="true" type="text" required /> <label class="powerwall-price-before-itc-label" for="powerwall-price-before-itc-label" >Powerwall Price Before Incentives</label > <input class="input" id="powerwall-price-before-itc-input" name="Powerwall Price Before ITC" data-clear="true" type="text" value="0" required /> <label class="est-total-before-itc-label" for="est-total-before-itc" >Estimated Total Price Before Incentive</label > <input class="input" id="est-total-before-itc-input" name="Estimated Total Before ITC" data-clear="true" type="text" required /> <label class="est-itc-label" for="est-itc" >Estimated Solar ITC</label > <input class="input" id="est-itc-input" name="Estimated ITC" data-clear="true" type="text" required /> <label class="total-cost-label" for="total-cost">Total Cost</label> <input class="input" id="total-cost-input" name="Total Cost" data-clear="true" type="text" required /> </section> </section> </form> <section class="submit-section"> <input class="btn submit-btn" id="submit-btn" type="submit" value="Submit" form="tesla-form" required /> </section> <section id="clear-section" class="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, "")
        )
      );
    }
  });
});

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()
});

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);
    }
  });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM