ultraloveninja
ultraloveninja

Reputation: 2139

If jQuery form is valid show hidden div

I've been messing with some form validation with two identical forms. So far I have the default HTML validation on the form, but for some reason when I submit the form, it reload the form it doesn't show my message that it's been successful.

Here's what I have for the form:

HTML

<div class="place-form">
   <div class="success-msg" style="display:none;">
    <p>Thanks for your submission! We will contact you shortly.</p>
  </div>
  <div class="form-wrap">
    <form id="place-form-item">
    <div class="form-row">
      <input id="fname" type="text" name="fname" placeholder="Your First Name" required />
    </div>
    <div class="form-row">
      <input id="lname" type="text" name="lname" placeholder="Your Last Name" required />
    </div>
    <div class="form-row">
      <input id="form-email" type="email" name="email" placeholder="Your Email" required />
    </div>
    <div class="btn-row">
      <button class="submit-btn">submit</button>
    </div>
      </form>
  </div>
</div>

JS:

$(".submit-btn").click(function(e){
   var $this = $(this);
   if($this.find("#place-form-item").valid()) {
       $this.parents(".form-wrap").hide();
       $this.parents().next(".success-msg").show()
     e.preventDefault();
   }
});

Not sure how to get it so that upon click, the form passed validation and then hides the one form and shows the success message. Unless I'm targeting something incorrectly.

Upvotes: 1

Views: 2205

Answers (3)

Scott Marcus
Scott Marcus

Reputation: 65796

Well, first you know that the .valid() method is a JQuery plug-in, right? Without the plug-in, the code in the if statement will never be reached.

There is a pure JavaScript API for checking a form's validity against the HTML5 validity framework - .checkValidity().

Next, your .next() call isn't going to find the success message because it isn't the next element from your button. Both that and your .find() calls can be replaced by using a higher level selector as context for a search.

Next, don't work with the submit button's click event. Work with the form's submit event.

Lastly, it's better to work with CSS classes than to dynamically create inline styles on an element.

$("#place-form-item").on("submit", function(e){
   var $this = $(this);
   if(this.checkValidity()) {
      e.preventDefault();
      $this.parents(".form-wrap").hide();
      $(".success-msg", ".place-form").removeClass("hidden")
   }
});
.hidden { display:none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="place-form">

  <div class="success-msg hidden">
    Thanks for your submission! We will contact you shortly.
  </div>
  
  <div class="form-wrap">
  
    <form id="place-form-item">
      <div class="form-row">
        <input id="fname" type="text" name="fname" placeholder="Your First Name" required>
      </div>
      <div class="form-row">
        <input id="lname" type="text" name="lname" placeholder="Your Last Name" required>
      </div>
      <div class="form-row">
        <input id="form-email" type="email" name="email" placeholder="Your Email" required>
      </div>
      <div class="btn-row">
        <button class="submit-btn">submit</button>
      </div>
    </form>
    
  </div>
</div>

Upvotes: 1

Obsidian Age
Obsidian Age

Reputation: 42314

The problem is that .next() only targets the sibling that immediately follows the target. Given your structure, .success-msg precedes .form-wrap. As such, .next() cannot target it.

To resolve this, instead of $this.parents().next(".success-msg").show(), you can target the parent element .place-form and then make use of .find() to find the relevant .success-msg with $this.parents(".place-form").find(".success-msg").show().

You'll also want to move your e.preventDefault() to outside of your conditional.

This can be seen in the following example:

$(".submit-btn").click(function(e) {
  e.preventDefault();
  var $this = $(this);
  if ($('#place-form-item').valid()) {
    $this.parents(".form-wrap").hide();
    $this.parents(".place-form").find(".success-msg").show();
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/jquery.validate.min.js"></script>
<script src="https://cdn.jsdelivr.net/jquery.validation/1.16.0/additional-methods.min.js"></script>

<div class="place-form">
  <div class="success-msg" style="display:none;">
    <p>Thanks for your submission! We will contact you shortly.</p>
  </div>
  <div class="form-wrap">
    <form id="place-form-item">
      <div class="form-row">
        <input id="fname" type="text" name="fname" placeholder="Your First Name" required />
      </div>
      <div class="form-row">
        <input id="lname" type="text" name="lname" placeholder="Your Last Name" required />
      </div>
      <div class="form-row">
        <input id="form-email" type="email" name="email" placeholder="Your Email" required />
      </div>
      <div class="btn-row">
        <button class="submit-btn">submit</button>
      </div>
    </form>
  </div>
</div>

Hope this helps! :)

Upvotes: 0

StackOverthrow
StackOverthrow

Reputation: 1284

Intercept the submit event, prevent the default form submission, and substitute your own action.

$("#my-form").on("submit", function (event) {
    event.preventDefault();
    if ($(this).valid()) {
        // do something
    }
});

Upvotes: 0

Related Questions