Home > other >  Detect change for dropdown using jQuery
Detect change for dropdown using jQuery

Time:08-06

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