Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

alborz
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
alborz
Full Stack JavaScript Techdegree Graduate 30,885 Points

Can't get payment option validation to work on form

I can't get my payment option validation to work properly. So far the error message displays if the user does not enter in a valid credit card number, zip code, and 3 digit CVV, but the error won't disappear when the user meets the valid format and hits the submit button.

Here's my snippet below:

// Global variabls
var jobRoleSelection = document.getElementById("title");
var basicInfoSection = document.getElementsByClassName("basicinfo")[0];
var designSelection = document.getElementById("design");
var colorSelection = document.getElementById("color");
var activities = document.getElementsByClassName("activities")[0];
// console.log(jobRoleSelection);
// console.log(basicInfoSection);
// console.log(designSelection);
// console.log(colorSelection);
// console.log(colorSelection.selectedIndex);
 console.log(activities);
// console.log(colorSelection);
// console.log(document.getElementsByClassName("puns")[0]);

// Variable containing the payment select menu
var paymentOptions = document.getElementById("payment");
//console.log(paymentOptions.options[1]);
//console.log(paymentOptions);

// Variables containing Bitcoin, Paypal, and credit card information
var paypalInfo = document.getElementById("paypalinfo");
var bitcoinInfo = document.getElementById("bitcoininfo");
var creditCardInfo = document.getElementById("credit-card");

// When the page loads, give focus to the first text field.
window.onload = function() {
    document.getElementById("name").focus();
    /** The "Credit Card" payment option should be selected by default and result in the display 
    of the #credit-card div. When credit card option is selected by default, hide the Paypal and Bitcoin information **/
    var defaultSelectedPayment = paymentOptions.options[paymentOptions.selectedIndex] = paymentOptions.options[1];
    paypalInfo.style.display = "none";
    bitcoinInfo.style.display = "none";
}

/** When credit card option is selected by default, hide the Paypal and Bitcoin information
When Paypal or Bitcoin option is selected, display respective information **/
paymentOptions.addEventListener("change", function () {

    // The indexing appears to accord with order as displayed when select is prompted
    if (paymentOptions.options[paymentOptions.selectedIndex] == paymentOptions.options[1]) {
        paypalInfo.style.display = "block";
        bitcoinInfo.style.display = "none";
        creditCardInfo.style.display = "none";
    } 

    if (paymentOptions.options[paymentOptions.selectedIndex] == paymentOptions.options[2]) {
        bitcoinInfo.style.display = "block";
        paypalInfo.style.display = "none";
        creditCardInfo.style.display = "none";
    } 

    if (paymentOptions.options[paymentOptions.selectedIndex] == paymentOptions.options[0]) {
        creditCardInfo.style.display = "block";
        paypalInfo.style.display = "none";
        bitcoinInfo.style.display = "none";
    }
});

// "Job Role" section of the form: reveal a text field when the "Other" option is selected from the "Job Role" drop down menu
jobRoleSelection.addEventListener("change", function () {

    // Variable containing the selecting job role from the job role dropdown
    var selectedJobRole = jobRoleSelection.options[jobRoleSelection.selectedIndex].value;
    //console.log(selectedJobRole);

    // If the "other" option is selected, display a text field
    if (selectedJobRole === "other") {
        var otherTextField = document.createElement('input');
        otherTextField.setAttribute('id', 'other-title');
        otherTextField.setAttribute('placeholder', 'Your Title');
        otherTextField.setAttribute('type', 'text');

        basicInfoSection.appendChild(otherTextField);
    }

});

// For the T-Shirt color menu, only display the options that match the design selected in the "Design" menu
designSelection.addEventListener("change", function () {

    // Variable containing the selected option from design
    var selectedDesign = designSelection.options[designSelection.selectedIndex].value;
    //console.log(selectedDesign);

    // Depending on which design is selected, display the matching colors and hide the colors that do not match design
   if (selectedDesign === "js puns") {

       // Grab the first option for "puns" and have it display as selected
       colorSelection.selectedIndex = 0;

       document.getElementsByClassName("heart")[0].style.display = 'none';
       document.getElementsByClassName("heart")[1].style.display = 'none';
       document.getElementsByClassName("heart")[2].style.display = 'none';

       document.getElementsByClassName("puns")[0].style.display = 'block';
       document.getElementsByClassName("puns")[1].style.display = 'block';
       document.getElementsByClassName("puns")[2].style.display = 'block';

   } else if (selectedDesign === "heart js") {

       // Grab the first option for "heart js" and have it display as selected
       colorSelection.selectedIndex = 3;

       document.getElementsByClassName("puns")[0].style.display = 'none';
       document.getElementsByClassName("puns")[1].style.display = 'none';
       document.getElementsByClassName("puns")[2].style.display = 'none';

       document.getElementsByClassName("heart")[0].style.display = 'block';
       document.getElementsByClassName("heart")[1].style.display = 'block';
       document.getElementsByClassName("heart")[2].style.display = 'block';

   } else if (selectedDesign === "select theme") {

       // Grab the first option in the select menu and have it display as selected
       colorSelection.selectedIndex = 0;

       document.getElementsByClassName("puns")[0].style.display = 'block';
       document.getElementsByClassName("puns")[1].style.display = 'block';
       document.getElementsByClassName("puns")[2].style.display = 'block';

       document.getElementsByClassName("heart")[0].style.display = 'block';
       document.getElementsByClassName("heart")[1].style.display = 'block';
       document.getElementsByClassName("heart")[2].style.display = 'block';
   }

});

/* If the user selects a workshop, don't allow selection of a workshop at the same date and time
Disable the checkbox and visually indicate that the workshop in the competing time slot isn't available */
activities.addEventListener("change", function () {

    // The workshop checkboxes
    var main = document.getElementsByTagName("input")[name="all"];
    var jsFrameworks = document.getElementsByTagName("input")[name="js-frameworks"];
    var jsLibs = document.getElementsByTagName("input")[name="js-libs"];
    var express = document.getElementsByTagName("input")[name="express"]
    var node = document.getElementsByTagName("input")[name="node"];
    var buildTools = document.getElementsByTagName("input")[name="build-tools"];
    var npm = document.getElementsByTagName("input")[name="npm"];

    // Labels for the workshop checkboxes to be disabled
    var expressLabel = document.getElementById("expresslabel");
    var jsFrameworksLabel = document.getElementById("frameworkslabel");
    var jsLibsLabel = document.getElementById("libslabel");
    var nodeLabel = document.getElementById("nodelabel");

    // Variable containing the total cost of all the workshops
    var totalCost = 0;

    // Variable containing the div to append to the checkboxes section for total cost
    var totalCostDiv = document.createElement('div');
    totalCostDiv.setAttribute("id", "totalcost");

    // Actitivities section with the appended div to inform user of total cost of workshops selected
    activities.appendChild(totalCostDiv);

    // If the workshops that do not have a time conflict are checked, update the total cost
    if (main.checked == true) {
        totalCost += 200;
    }

    if (buildTools.checked == true) {
        totalCost += 100;
    }

    if (npm.checked == true) {
        totalCost += 100;
    }

    // If a workshop is selected that conflicts with another, disable the other
    // As a user selects activities to register for, a running total is listed below the list of checkboxes
    if (jsFrameworks.checked == true) {
        express.disabled = true;
        expressLabel.style.color = "grey";
        totalCost += 100;
    } else if (express.checked == true) {
        jsFrameworks.disabled = true;
        jsFrameworksLabel.style.color = "grey";
        totalCost += 100;
    }

    if (jsLibs.checked == true) {
        node.disabled = true;
        nodeLabel.style.color = "grey";
        totalCost += 100;
    } else if (node.checked == true) {
        jsLibs.disabled = true;
        jsLibsLabel.style.color = "grey";
        totalCost += 100;
    }

    // Update the cost each time a workshop is selected
    document.getElementById("totalcost").innerHTML = "Total: $ " + totalCost;

    // If a workshop that conflicted with another is deselected, reenable the disabled, conflicting workshop
    if (jsFrameworks.checked == false) {
        express.disabled = false;
        expressLabel.style.color = "black";
    }

    if (express.checked == false) {
        jsFrameworks.disabled = false;
        jsFrameworksLabel.style.color = "black";
    }

    if (jsLibs.checked == false) {
        node.disabled = false;
        nodeLabel.style.color = "black";
    }

    if (node.checked == false) {
        jsLibs.disabled = false;
        jsLibsLabel.style.color = "black";
    }

});

// Form validation: display error messages and don't let the user submit the form if any of these validation errors exist:
// Name field can't be empty
var nameField = document.getElementById("name"); // global variables
//console.log(nameField);
var submitButton = document.getElementById("submit");
//console.log(submitButton);
var nameLabel = document.getElementById("name-label");
//console.log(nameLabel);
var emailLabel = document.getElementById("email-label")
// Validate email format
// Method to validate email format
var emailField = document.getElementById("mail");
// Activities label
var activityLabel = document.getElementById("activities-label");
// Payment label
var paymentLabel = document.getElementById("payment-label");
// Activity checkboxes
var checkboxes = document.querySelectorAll(".activities input");
console.log(checkboxes);

// Validation functions
function validateEmail(emailString) {
    var emailFormat = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
    return emailFormat.test(emailString);
    }

function validateName(name) {
    return name !== "";
}

function validateActivity(activity) {
    for (var i = 0; i < checkboxes.length; i++) {
        if (checkboxes[i].checked) {
            return true;
        }
    }
    return false;
}

function validatePayment(options) {
    var creditCardFormat = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][‌​0-9])[0-9]{12}|3[47]‌​[0-9]{13}|3(?:0[0-5]‌​|[68][0-9])[0-9]{11}‌​|(?:2131|1800|35\\d{‌​3})\\d{11})$/;
    var zipCodeFormat = /(^\d{5}$)|(^\d{5}-\d{4}$)/;
    var cvvFormat = /^[0-9]{3,4}$/;
    if (paymentOptions.options[paymentOptions.selectedIndex] == paymentOptions.options[1]) {
        if (creditCardFormat.test(paymentOptions) && zipCodeFormat.test(paymentOptions) && cvvFormat.test(paymentOptions)) {
            return true; // do something like return emailFormat.test(emailString);
             }
        }
    return false;
}

// Event listener to validate fields upon selecting submit button
submitButton.addEventListener("click", function(event) {

console.log(event);
console.log("emailvalidate is", validateEmail(emailField.value));
console.log(emailLabel.children);

    if (!validateEmail(emailField.value)) {
        event.preventDefault();
        if (emailLabel.children.length < 1) {
            var emailErrorMessage = document.createElement("p");
            emailErrorMessage.innerHTML = "Please enter a valid email address.";
            emailErrorMessage.style.color = "red";
            emailLabel.appendChild(emailErrorMessage);
        }
    } else if (emailLabel.children.length >= 1) {
        emailLabel.removeChild(emailLabel.children[0]);
    }

    if (!validateName(nameField.value)) {
        event.preventDefault();
        if (nameLabel.children.length < 1) {
            var nameErrorMessage = document.createElement("p");
            nameErrorMessage.innerHTML = "Please enter your name.";
            nameErrorMessage.style.color = "red";
            //console.log(nameErrorMessage);
            nameLabel.appendChild(nameErrorMessage);
            //console.log(validateEmail("test@gmail.com"));
        }
    } else if (nameLabel.children.length >= 1) {
        nameLabel.removeChild(nameLabel.children[0]);
    }

    // At least one activity must be checked from the list under "Register for Actitivities."
    if (!validateActivity(checkboxes)) {
        event.preventDefault();
        if (activityLabel.children.length < 1) {
            var activityErrorMessage = document.createElement("p");
            activityErrorMessage.innerHTML = "Please select at least one activity.";
            activityErrorMessage.style.color = "red";
            activityLabel.appendChild(activityErrorMessage);
        } 
    } else if (activityLabel.children.length >= 1) {
            activityLabel.removeChild(activityLabel.children[0]);   
    }

    //  Payment option must be selected
    if (!validatePayment(paymentOptions)) {
        event.preventDefault();
        if (paymentLabel.children.length < 1) {
            var paymentErrorMessage = document.createElement("p");
            paymentErrorMessage.innerHTML = "Please select at least one payment method.";
            paymentErrorMessage.style.color = "red";
            paymentLabel.appendChild(paymentErrorMessage);
        }
    } else if (paymentLabel.children.length >= 1) {
            paymentLabel.removeChild(paymentLabel.children[0]);   
    }

});
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Register for Full Stack Conf</title>
  <link href="https://fonts.googleapis.com/css?family=Roboto:400,500,700" rel="stylesheet" type="text/css">
    <link rel="stylesheet" href="css/style.css">
</head>
<body>
    <div class="container">

    <header>
      <span>Register for</span>
      <h1>Full Stack Conf</h1>
    </header>

    <form action="index.html" method="post">

      <fieldset class="basicinfo">         
        <legend>Basic Info</legend>

        <label for="name" id="name-label">Name:</label>
        <input type="text" id="name" name="user_name">

        <label for="mail" id="email-label">Email:</label>
        <input type="email" id="mail" name="user_email">

        <label for="title">Job Role</label>
        <select id="title" name="user_title">
          <option value="full-stack js developer">Full Stack JavaScript Developer</option>
          <option value="front-end developer">Front End Developer</option>
          <option value="back-end developer">Back End Developer</option>
          <option value="designer">Designer</option>          
          <option value="student">Student</option>
          <option value="other">Other</option>  
        </select>           
      </fieldset>

      <fieldset class="shirt">
        <legend>T-Shirt Info</legend>

        <div>
          <label for="size">Size:</label>
          <select id="size" name="user_size">
            <option value="small">S</option>
            <option value="medium" selected>M</option>
            <option value="large">L</option>
            <option value="extra large">XL</option>
          </select>
        </div>

        <div class="design-section">
          <label for="design">Design:</label>
          <select id="design" name="user_design">
            <option value="select theme">Select Theme</option>
            <option value="js puns">Theme - JS Puns</option>
            <option value="heart js">Theme - I &#9829; JS</option>
          </select>
        </div>

        <div id="colors-js-puns" class="">
          <label for="color">Color:</label>
          <select id="color">
            <option class="puns" value="cornflowerblue">Cornflower Blue (JS Puns shirt only)</option>
            <option class="puns" value="darkslategrey">Dark Slate Grey (JS Puns shirt only)</option> 
            <option class="puns" value="gold">Gold (JS Puns shirt only)</option> 
            <option class="heart" value="tomato">Tomato (I &#9829; JS shirt only)</option>
            <option class="heart" value="steelblue">Steel Blue (I &#9829; JS shirt only)</option> 
            <option class="heart" value="dimgrey">Dim Grey (I &#9829; JS shirt only)</option> 
          </select>
        </div>                
      </fieldset>

      <fieldset id ="activities" class="activities">
        <legend id="activities-label">Register for Activities</legend>
        <label><input type="checkbox" name="all"> Main Conference — $200</label>
        <label id="frameworkslabel"><input type="checkbox" name="js-frameworks"> JavaScript Frameworks Workshop — Tuesday 9am-12pm, $100</label>
        <label id="libslabel"><input type="checkbox" name="js-libs"> JavaScript Libraries Workshop — Tuesday 1pm-4pm, $100</label>
        <label id="expresslabel"><input type="checkbox" name="express"> Express Workshop — Tuesday 9am-12pm, $100</label>
        <label id="nodelabel"><input type="checkbox" name="node"> Node.js Workshop — Tuesday 1pm-4pm, $100</label>          
        <label><input type="checkbox" name="build-tools"> Build tools Workshop — Wednesday 9am-12pm, $100</label>
        <label><input type="checkbox" name="npm"> npm Workshop — Wednesday 1pm-4pm, $100</label>

      </fieldset>
      <fieldset>
        <legend id="payment-label">Payment Info</legend>

        <label for="payment">I'm going to pay with:</label>
        <select id="payment" name="user_payment">
          <option value="select_method">Select Payment Method</option>
          <option value="credit card">Credit Card</option>
          <option value="paypal">PayPal</option>
          <option value="bitcoin">Bitcoin</option>
        </select>

        <div id="credit-card" class="credit-card">

          <div class="col-6 col">
            <label for="cc-num">Card Number:</label>
              <input id="cc-num" name="user_cc-num" type="text">
          </div>

          <div class="col-3 col">
            <label for="zip">Zip Code:</label>
            <input id="zip" name="user_zip" type="text"> 
          </div>

          <div class="col-3 col">
            <label for="cvv">CVV:</label>
            <input id="cvv" name="user_cvv" type="text"> 
          </div>

          <label for="exp-month">Expiration Date:</label>
          <select id="exp-month" name="user_exp-month">
            <option value="1">1 - January</option>
            <option value="2">2 - February</option>
            <option value="3">3 - March</option>
            <option value="4">4 - April</option>
            <option value="5">5 - May</option>
            <option value="6">6 - June</option>
            <option value="7">7 - July</option>
            <option value="8">8 - August</option>
            <option value="9">9 - September</option>
            <option value="10">10 - October</option>
            <option value="11">11 - November</option>   
            <option value="12">12 - December</option>                         
          </select>
          <label for="exp-year">Expiration Year:</label>
          <select id="exp-year" name="user_exp-year">
            <option value="2016">2016</option>
            <option value="2017">2017</option>
            <option value="2018">2018</option>
            <option value="2019">2019</option>
            <option value="2020">2020</option>                        
          </select>                                  
        </div>

        <div id="paypalinfo">
            <p>If you selected the PayPal option we'll take you to Paypal's site to set up your billing information, when you click “Register” below.</p>
        </div> 

        <div id="bitcoininfo">
            <p>If you selected the Bitcoin option we'll take you to the Coinbase site to set up your billing information. Due to the nature of exchanging Bitcoin, all Bitcoin transactions will be final.</p>
        </div>                  

      </fieldset>        

      <button type="submit" id="submit">Register</button>

    </form>

    </div>
  <script src="js/script.js"></script>
</body>
</html>