0

I created a product page, in two separate places people can input their e-mail. If they put in a properly formatted e-mail, I want them to get a validation message, if they put in a wrongly formatted e-mail, I want them to get an error message.

My professor is having us connect to a database he built in Ruby On Rails that verifies this for us, and that is already successfully connected to, but we need to use JavaScript to set up the error and validation messages that appear on screen for the user. For some reason I can't seem to get them to come through and I was wondering if anyone had any suggestions about where I'm messing up.

My professor said it's fine to look for help on here if we get stuck, and I've really gotten stuck. I've been playing with options for several hours and can't seem to figure anything out. Any help would be hugely appreciated, thank you!

This is what it's supposed to look like when you submit an incorrectly formatted e-mail:

enter image description here

This is what happens when you submit an incorrectly formatted e-mail (nothing comes up at all):

enter image description here

This is what it's supposed to look like when you submit a correctly formatted e-mail:

enter image description here

This is what happens when you submit a correctly formatted e-mail (nothing comes up at all):

enter image description here

This is what happens in the console.log when I click on the button.

enter image description here

$(document).ready(function() {
    
    $('form').submit(function(event) {

        var formData = $(this).serialize();
      
        $.ajax({
            type         : 'POST',
            url          : 'https://web2-product-page/herokuapp.com/subscribers', 
            data         : formData, 
            dataType     : 'json' 
        }).done(function(data) {

                console.log(data);
                $('.confirmation').fadeIn();
                $('.error-message').text("");
                $('input[name=email]').val("");
            }).fail(function(data) {
                console.log(data);
                var errorMessage = JSON.parse(data.responseText).email[0];
                $('.error-message').text(errorMessage);
                $('.confirmation').hide();
            });
    
        event.preventDefault();
    });    
});
* {
  box-sizing: border-box;
}
@font-face {
    font-family: 'gilroysemibold';
    src: url('radomir_tinkov_-_gilroy-semibold-webfont.woff2') format('woff2'),
         url('radomir_tinkov_-_gilroy-semibold-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;
}
body {
  margin: 0px;
}
#calltoaction {
  background-image: url("calltoactionbackground.jpg");
  background-size: 100%;
  background-repeat: no-repeat;
  display: inline-block;
  height: 500px;
  padding-bottom: 100px;
  padding-left: 70px;
  padding-right: 70px;
  padding-top: 100px;
  text-align: center;
  width: 100%;
}
#calltoaction p {
  margin: auto;
  padding-top: 25px;
  padding-bottom: 55px;
  width: 500px;
}
.clearfix:before,
.clearfix:after {
  content: "";
  display: table;
}

.clearfix:after {
  clear: both;
}

.clearfix {
  zoom: 1; /* ie 6/7 */
}
.confirmation {
  display: none;
}
.error-message {
  display: none;
}
#functions {
  background-color: #FFFFFF;
  display: block;
  height: 1080px;
  margin: auto;
  padding-top: 100px;
  width: 100%;
}
#functions p {
  color: #62CE9C;
}
h1 {
  color: #FFFFFF;
  font-family: 'gilroysemibold';
  font-size: 36px;
  font-weight: lighter;
}
h2 {
  color: #62CE9C;
  font-family: 'gilroysemibold';
  font-size: 30px;
  font-weight: lighter;
}
h3 {
  color: #00AF78;
  font-family: Open Sans;
  font-size: 18px;
  line-height: 10px;
}
.hashtag {
  color:  #00AF78;
  font-weight: bold;
}
#hero {
  background-color: #62CE9C;
  height: 650px;
  margin: 0px;
  padding-bottom: 100px;
  padding-left: 120px;
  padding-right: 120px;
  padding-top: 100px;
  width: 100%;
}
#herocontent {
  margin: auto;
  width: 900px;
}
#herotext {
  float: left;
  width: 600px;
}
#hero h1 {
  width: 470px;
}
#hero img {
  display: block;
  float: right;
}
#hero p {
  padding-top: 30px;
  padding-bottom: 40px;
  width: 500px;
}
input, select, textarea{
  color: #62CE9C;
}

textarea:focus, input:focus {
  color: #62CE9C;
}
input::-webkit-input-placeholder {
  color: #62CE9C !important;
}
 
input:-moz-placeholder { /* Firefox 18- */
  color: #62CE9C !important;  
}
 
input::-moz-placeholder {  /* Firefox 19+ */
  color: #62CE9C !important;  
}
 
input:-ms-input-placeholder {  
  color: #62CE9C !important;  
}
p {
  color: #FFFFFF;
  font-family: Open Sans;
  font-size: 18px;
  line-height: 26px;
}
#save {
  align-items: center;
  display: block;
  margin: auto;
  width: 800px;
}
#savefood {
  float: right;
  margin: auto;
}
#savefoodimage {
  float: right;
}
#savefoodtext {
  float: right;
  height: 300px;
  margin-right: 30px;
  padding-top: 30px;
  width: 290px; 
}
#savemoney {
  float: left;
  margin: auto;
}
#savemoneyimage {
  float: left;
}
#savemoneytext {
  float: left;
  height: 300px;
  margin-left: 30px;
  padding-top: 30px;
  width: 330px;
}
#savetime {
  float: left;
  margin: auto;
}
#savetimeimage {
  float: left;
}
#savetimetext {
  float: left;
  height: 300px;
  margin-left: 30px;
  padding-top: 30px;
  width: 330px;
}
#searchbar {
  background-color: #FFFFFF;
  border: none;
  border-radius: 8px;
  font-size: 18px;
  height: 40px;
  padding-left: 15px;
  width: 300px;
}
#searchbutton {
  background-color: #28C787;
  border: none;
  border-radius: 8px;
  color: #FFFFFF;
  font-size: 18px;
  height: 40px;
  margin-left: 20px;
  width: 180px;
}
#searchbutton:hover {
  background-color: #00BE8B;
}
#tweetone {
  background-color: #FFFFFF;
  border-radius: 25px;
  height: 208px;
  margin: auto;
  margin-top: 60px;
  padding-bottom: 30px;
  padding-left: 25px;
  padding-right: 25px;
  padding-top: 30px;
  width: 650px;
}
#tweetone img {
  float: left;
  height: 150px;
  padding-top: 10px;
  width: 150px;
}
#tweetonetext {
  float: left;
  padding-left: 15px;
  width: 450px;
}
#tweettwo {
  background-color: #FFFFFF;
  border-radius: 25px;
  height: 208px;
  margin: auto;
  margin-top: 60px;
  padding-bottom: 30px;
  padding-left: 25px;
  padding-right: 25px;
  padding-top: 30px;
  width: 650px;
}
#tweettwo img {
  float: left;
  padding-top: 10px;
}
#tweettwotext {
  float: left;
  padding-left: 15px;
  width: 400px;
}
#tweetthree {
  background-color: #FFFFFF;
  border-radius: 25px;
  height: 208px;
  margin: auto;
  margin-top: 60px;
  padding-bottom: 30px;
  padding-left: 25px;
  padding-right: 25px;
  padding-top: 30px;
  width: 650px;
}
#tweetthree img {
  float: left;
  padding-top: 10px;
}
#tweetthreetext {
  float: left;
  padding-left: 15px;
  width: 450px;
}
ul {
  list-style-type: none;
}
#vocational {
  background-color: #62CE9C;
  display: inline-block;
  height: 1120px;
  padding-bottom: 100px;
  padding-left: 70px;
  padding-right: 70px;
  padding-top: 100px;
  width: 100%;
}
#vocational h1 {
  margin: auto;
  text-align: center;
  margin-bottom: 0px;
  width: 500px;
}
#vocational p {
  color: #62CE9C;
  display: inline-block;
}
<!DOCTYPE html>
<html>
  <head>
    <link href="css/main.css" rel="stylesheet"/>
    <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="js/main.js"></script>
  </head>
  <body>
    <div class="container clearfix" id="hero">
      <div id="herocontent">
        <div id="herotext">
          <h1>Make the Most of your Food With Pantree</h1>
          <p>Pantree for iOS lets you search for recipes based on the ingredients you already have in your home.</p>
          <form id="subscribe" method="post" action="https://web-2-product-page.herokuapp.com/subscribers">
            <input id="searchbar" type="text" name="email" placeholder="yourname@email.com">
            <input id="searchbutton" type="submit" value="Get Early Access">
            <p class="confirmation">Thank you!</p>
            <p class="error-message">Incorrect E-mail Address.</p>
          </form>
        </div>
        <img src="images/phone.png"/>
      </div>  
    </div>
    <div id="functions">
      <div id=save>
        <div id="savemoney">
          <img id="savemoneyimage" src="images/savemoney.png"/>
          <div id="savemoneytext">
            <h2>Save Money</h2>
            <p>Pantree finds you recipes containing ingredients you already have in your home, saving you from unecessary trips to the grocery store.</p>
          </div>
        </div>  
        <div id="savefood">
          <img id="savefoodimage" src="images/savefood.png"/>
          <div id="savefoodtext">
            <h2>Save Food</h2>
            <p>Pantree keeps track of expiration dates, alerting you when food will go stale so you can use it before it goes bad.</p>
          </div>
        </div>
        <div id="savetime">
          <img id="savetimeimage" src="images/savetime.png"/>
          <div id="savetimetext">
            <h2>Save Time</h2>
            <p>Pantree's built-in kitchen organizing system helps you monitor all of the food in your home, so figuring out what food you have is quick & easy.</p>
          </div>
        </div>  
      </div>  
    </div>
    <div id="vocational">
      <h1>These Folks Could Use Pantree Every Day</h1>
      <ul>
        <li>
          <div id="tweetone">
            <img src="images/tweetone.png"/>
            <div id="tweetonetext">
              <h3>Kat</h3>
              <h3>@devicat</h3>
              <p>I have no idea what to make for dinner. I am so bad at this game. <span class="hashtag">#adulting</span></p>
            </div>          
          </div>  
        </li>
        <li>
          <div id="tweettwo">
            <img src="images/tweettwo.png"/>
            <div id="tweettwotext">
              <h3>Jack Falahee</h3>
              <h3>@RestingPlatypus</h3>
              <p>Dear Mom, How do I organize my kitchen? Love, me</p>
            </div>
          </div>
        </li>
        <li>
          <div id="tweetthree">
            <img src="images/tweetthree.png"/>
            <div id="tweetthreetext">
              <h3>mason ryan</h3>
              <h3>@MasonTheManiac</h3>
              <p>Something in my fridge smells really bad.... <span class="hashtag">#cantfindit</span></p>
            </div>  
          </div>  
        </li>
      </ul>
    </div>
    <div id="calltoaction">
      <h1>Manage your Kitchen, Effortlessly</h1>
      <p>Pantree makes it easy to find recipes, keep track of food, and organize your kitchen.</p>
      <form id="subscribe" method="post" action="https://web-2-product-page.herokuapp.com/subscribers">
        <input id="searchbar" type="text" name="email" placeholder="yourname@email.com">
        <input id="searchbutton" type="submit" value="Get Early Access">
        <p class="confirmation">Thank you!</p>
        <p class="error-message">Incorrect E-mail Address.</p>
      </form>
    </div>
  </body>
</html>
Alison Dyer
  • 69
  • 1
  • 10
  • It'd be better if you posted exactly what you've tried, and what result you're getting vs what's expected; the CSS generally isn't necessary to post either if your question is about JS functionality. Also, what does the JSON response from the AJAX call look like for both a properly formatted email & a wrongly formatted one? Bear in mind the `.fail()` callback on an AJAX call is if for when the call to the URL specified fails (i.e. returns an HTTP error code) - whereas you may need to inspect the JSON for an actual evaluation of the email the user submitted. – Stevangelista Nov 20 '16 at 20:10
  • Actually, the CSS can help here, because the question is about how the page appears. – Tim Grant Nov 20 '16 at 20:16
  • Your jQuery seems to be OK. Do you know whether your Ajax call is succeeding? (If it is misconfigured, you'll always get your "fail" condition) http://stackoverflow.com/questions/21897398/how-do-i-debug-jquery-ajax-calls – Tim Grant Nov 20 '16 at 20:22
  • Well the issue is that this is what our professor told us to try, and the result I'm getting is nothing. When you submit content and hit the button you don't get any sort of response. You're supposed to get a response that either validates that you have a correct e-mail or tells you that you inputed it incorrectly. – Alison Dyer Nov 20 '16 at 21:30
  • @Stevangelista I updated it with what it's supposed to look like. The way my professor explained it is this is what you're supposed to try, I don't think telling you guys what I've tried would help since I'm so new to Javascript (we just started learning about this last week) I have absolutely no idea what I'm doing, I'm trying to read up as much as I can, but nothing is clicking at all like it did for CSS and Javascript. – Alison Dyer Nov 20 '16 at 21:41
  • Could you post your `console.log(data);` output. That will help diagnose the problem – K Scandrett Nov 20 '16 at 22:13
  • I'd also add some text around it so you know which branch is taken. Something like `console.log('Data Done: ' + data);` and `console.log('Data Fail: ' + data);` – K Scandrett Nov 20 '16 at 22:19
  • @KScandrett I added my console.log(data); output to the question, does this make anything more clear? – Alison Dyer Nov 21 '16 at 17:00
  • Please take a look at how to create a [mcve]. This ... is not Minimal. – Heretic Monkey Nov 21 '16 at 17:46
  • Thanks Mike, I will be sure to do that from now on! – Alison Dyer Nov 23 '16 at 19:57

1 Answers1

1

Two points:

1) The API endpoint you have specified in your code (https://web2-product-page/herokuapp.com/subscribers) returns 404 not found, so you are never going to get a response from it.
I believe you have misunderstood what the .done() and .fail() methods are for - these are not called in response to a pass or fail email validation, but in response to a pass/fail request to the server. In your code, because the server returns 404, fail() will always be called. Because the response has failed, there is no data.responseText to use.
I would use something more like the following (assuming that when the server exists it returns data.validEmail to represent email validity (your actual server probably uses something different).

$.ajax({
        type         : 'POST',
        url          : 'https://web2-product-page/herokuapp.com/subscribers', 
        data         : formData, 
        dataType     : 'json' 
    }).done(function(data) {

            if (data.validEmail) {
                $('.confirmation').fadeIn();
                $('.error-message').text("");
                $('input[name=email]').val("");
            } else {
                $('.error-message').text("Not a valid email address");
            }


        }).fail(function() {
            $('.error-message').text("The server did not respond.");                
        });

2) Although this is a valid learning exercise in communicating with a remote server via AJAX, in reality the easiest way to validate an email is to use the HTML5 type attribute on your input.

<input type="email" id="searchbar" name="email" placeholder="yourname@email.com">

Now the browser will do the hard work for you, provide a validation message and prevent form submission unless it is valid.

Edit: If you post a valid email to your API then it returns a JSON object with the details of the email it has saved, and a "201 Created" status, which you can test for as follows:

$.ajax({
        type         : 'POST',
        url          : 'https://web2-product-page/herokuapp.com/subscribers', 
        data         : formData, 
        dataType     : 'json' 
    }).done(function(data) {

            if (data.status === 201) {
                $('.confirmation').fadeIn();
                $('.error-message').text("");
                $('input[name=email]').val("");
            } else {
                $('.error-message').text(data.email);
            }


        }).fail(function() {
            $('.error-message').text("The server did not respond.");                
        });
Alex Young
  • 4,009
  • 1
  • 16
  • 34
  • Hi, thank you, I'm going to contact my professor about the API issue and implement what you suggested. Thank you and everyone for all your help, it's greatly appreciated. Once I'm sure the API issue is resolved and I have a chance to play with it working correctly to verify this answer I'll mark it as the answer, thank you. – Alison Dyer Nov 21 '16 at 17:50
  • No problem. I just looked a bit closer at that API URL and realised you have a slash where you should have a dot! The correct URL is https://web2-product-page.herokuapp.com/subscribers – Alex Young Nov 21 '16 at 17:54
  • I've had a bit more of a play with the API using Postman and edited my answer. – Alex Young Nov 21 '16 at 19:01
  • Thank you so much for all this information, it has been incredibly helpful! It's now marked as the answer. – Alison Dyer Nov 23 '16 at 19:54