title: Salesforce form showing errors even when filled out correctly
body: <p>I am new to salesforce and don't have a lot of experience with javascript. The issue I am having is that as I am testing a form and filling out the inputs it is adding the the "has-error" class to the parent div even when the input is filled out correctly. However, it will allow the form to be submitted so it is not conflicting with that. </p>
  
  <p>I took over the work from another developer so Im not sure what is causing the error.</p>
  
  <p>The is the javascript for the salesforce form. I am also using validate.js:</p>
  
  <pre><code>'use strict';
  
  var constraints = {
      // First Name
      '00N4100000CJ8sT': {
          presence: {
              message: '^First Name is required'
          },
          length: {
              maximum: 80
          }
      },
      // Last Name
      '00N4100000CJ8sY': {
          presence: {
              message: '^Last Name is required'
          },
          length: {
              maximum: 80
          }
      },
      // Appointment Date
      '00N4100000EWaN0': {
          presence: {
              message: '^Date is not valid'
          },
          format: {
              pattern: /^\d{1,2}\/\d{1,2}\/\d{4}$/,
          },
      },
      // Patient Email
      '00N4100000CJ8sE': {
          presence: {
              message: '^Email is required'
          },
          email: {
              message: '^Email is not valid'
          }
      },
      // Phone
      'phone': {
          presence: true,
          format: {
              pattern: /^[(]{0,1}[0-9]{3}[)]{0,1}[-\s\.]{0,1}[0-9]{3}[-\s\.]{0,1}[0-9]{4}$/,
              message: '^Phone Number is not valid'
          }
      }
  };
  
  $('.salesforce-form').each(function () {
  
      var form = this;
      form.addEventListener('submit', function (ev) {
          ev.preventDefault();
          handleFormSubmit(form);
      });
  
      var inputs = document.querySelectorAll('input, textarea, select');
      for (var i = 0; i &lt; inputs.length; ++i) {
          inputs.item(i).addEventListener('change', function (ev) {
              var errors = validate(form, constraints) || {};
              showErrorsForInput(this, errors[this.name]);
          });
      }
  
      function handleFormSubmit(form, input) {
          var errors = validate(form, constraints);
          showErrors(form, errors || {});
          if (!errors) {
              showSuccess(form);
          }
      }
  
      function showErrors(form, errors) {
          _.each(form.querySelectorAll('input[name], select[name]'), function (input) {
              showErrorsForInput(input, errors &amp;&amp; errors[input.name]);
          });
      }
  
      function showErrorsForInput(input, errors) {
          var formGroup = closestParent(input, 'form-group');
          var messages = formGroup.querySelector('.messages');
          resetFormGroup(formGroup);
          if (errors) {
              formGroup.classList.add('has-error');
              _.each(errors, function (error) {
                  addError(messages, error);
              });
          } else {
              formGroup.classList.add('has-success');
          }
      }
  
      function closestParent(child, className) {
          if (!child || child == document) {
              return null;
          }
          if (child.classList.contains(className)) {
              return child;
          } else {
              return closestParent(child.parentNode, className);
          }
      }
  
      function resetFormGroup(formGroup) {
          formGroup.classList.remove('has-error');
          formGroup.classList.remove('has-success');
          _.each(formGroup.querySelectorAll('.help-block.error'), function (el) {
              el.parentNode.removeChild(el);
          });
      }
  
      function addError(messages, error) {
          var block = document.createElement('p');
          block.classList.add('help-block');
          block.classList.add('error');
          block.innerText = error;
          messages.appendChild(block);
      }
  
      function showSuccess(form) {
          var myEmail = form.querySelector('#my-email').value;
  
          if (!myEmail.length &gt; 0) {
              form.querySelector('#orgid').value = '00D41000000MWct';
              var postData = $(form).serializeArray();
              $.ajax({
                  type: 'POST',
                  url: '(salesforce url goes here)',
                  data: postData,
                  success: function success(data, textStatus, jqXHR) {
                      //data: return data from server
                  },
                  error: function error(jqXHR, textStatus, errorThrown) {
                      //if fails
                      $(form).find('.form-group').fadeOut();
                      $('.thank-you-message').last().clone().appendTo(form).fadeIn();
                      dataLayer.push({
                          'event': 'gtm.formSubmit',
                          'gtm.elementClasses': form.className
                      });
                  }
              });
          }
      }
  });
  </code></pre>
  
  <p>This is the html for the salesforce form:</p>
  
  <pre><code>&lt;form class="salesforce-form salesforce-contact-form" novalidate&gt;
      &lt;div class="hide form-group"&gt;
          &lt;input id="my-email" name="my-email" type="text" /&gt;
          &lt;input type="hidden" id="orgid" name="orgid" /&gt;
  
          &lt;input type="hidden" id="email" name="email" value="test@email.com"/&gt;
          &lt;input type="hidden" id="00N4100000IkI2v" name="00N4100000IkI2v" value="&lt;?php echo get_permalink(); ?&gt;" /&gt;
          &lt;input type="hidden" id="00N4100000IkHtO" name="00N4100000IkHtO" value="&lt;?php echo get_client_ip(); ?&gt;" /&gt;
          &lt;input type="hidden" id="00N4100000HxXj4" name="00N4100000HxXj4" value="New" /&gt;
          &lt;input type="hidden" id="00N4100000CL2tK" name="00N4100000CL2tK" value="Request Appointment" title="Form Type" /&gt;
      &lt;/div&gt;
      &lt;div class="col-md-6 col-sm-6 col-xs-6 form-group first-name"&gt;
          &lt;label for="00N4100000CJ8sT" class="hidden"&gt;First Name&lt;/label&gt;
          &lt;input id="00N4100000CJ8sT" maxlength="80" name="00N4100000CJ8sT" size="20" type="text" placeholder="First Name: *"&gt;
          &lt;div class="messages"&gt;&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="col-md-6 col-sm-6 col-xs-6 form-group last-name"&gt;
          &lt;label for="00N4100000CJ8sY" class="hidden"&gt;Last Name&lt;/label&gt;
          &lt;input id="00N4100000CJ8sY" maxlength="80" name="00N4100000CJ8sY" size="20" type="text" placeholder="Last Name: *"&gt;
          &lt;div class="messages"&gt;&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="col-md-6 col-sm-6 col-xs-6 form-group email"&gt;
          &lt;label for="00N4100000CJ8sE" class="hidden"&gt;Email&lt;/label&gt;
          &lt;input id="00N4100000CJ8sE" maxlength="80" name="00N4100000CJ8sE" size="20" type="email" placeholder="Email: *"&gt;
          &lt;div class="messages"&gt;&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="col-md-6 col-sm-6 col-xs-6 form-group phone"&gt;
          &lt;label for="phone" class="hidden"&gt;Phone&lt;/label&gt;
          &lt;input id="phone" maxlength="40" name="phone" size="20" type="text" placeholder="Phone: *"&gt;
          &lt;div class="messages"&gt;&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="col-md-12 col-xs-12 form-group appointment-date"&gt;
          &lt;label for="00N4100000EWaN0" class="hidden"&gt;Appointment Date&lt;/label&gt;
          &lt;input id="00N4100000EWaN0" name="00N4100000EWaN0" size="20" type="text" placeholder="Appointment Date: *"&gt;
          &lt;div class="messages"&gt;&lt;/div&gt;
      &lt;/div&gt;
      &lt;div class="col-md-12 col-sm-12 col-xs-12 form-group comments"&gt;
          &lt;label for="description" class="hidden"&gt;Comments&lt;/label&gt;
          &lt;textarea id="description" name="description" placeholder="Comments:"&gt;&lt;/textarea&gt;
      &lt;/div&gt;
      &lt;div class="col-md-12 col-sm-12 col-xs-12 form-group submit"&gt;
          &lt;input type="submit" value="Submit +" class="btn small"/&gt;
      &lt;/div&gt;
  &lt;/form&gt;
  </code></pre>
  
  <p>Let me know if this needs more explanation or if you need to see any other files.</p>