Home > Software engineering >  For loop for entering email address only 3 times not working well
For loop for entering email address only 3 times not working well

Time:05-11

I'm writing a Javascript program that will ask the user to input an email, and if the email matches I will be sending an automated email to that email about how to claim their old profile data. Otherwise, if the user does not remember/forgot what email they used and tried 3 times, a message will say please call. Right the problem comes in when the user enters the wrong email. I have a for loop set up with if and if else statements. When they enter the wrong email the else if statement does show the the numTries variable by the input box that says 3 after the first wrong email is entered. The input box does turn red, and the input box does clear, but the console does not show the variable numTries in my debugging tool. Thank you for your time. here is the javascript code

<script>

const form         = document.querySelector('#myForm');
const emailDiv     = form.querySelector('#myemailfield');
const resultDiv    = form.querySelector('[data-result]');

const correctEmail = emailDiv.dataset.email;

form.onsubmit = (e) => {
  e.preventDefault();

  let inputValue = emailDiv.value;
let numTries;
let totalTries = 3;
 for(numTries = 0; numTries <= totalTries; numTries  ){ 
 if (inputValue === correctEmail) {
     {!--form.submit(); // use this to submit form.--}
    
    resultDiv.innerText = 'Matches!'
    emailDiv.classList.add('match') 
    document.getElementById("mySubmit").disabled = true;
    
  } 
  else if(inputValue != correctEmail) {
    resultDiv.innerText = numTries;
    emailDiv.classList.add('nomatch');
    emailDiv.value ="";          
    console.log(numTries);
  }
  
  else 
  {
  resultDiv.innerText = "Please call";
  }
  }
  }
</script>

Here is the html

{exp:channel:entries channel="Talent" entry_id="{segment_3}" limit="1"}
<img id="pics" src="{headshot}">
<form id="myForm">
<p>Please enter the address you used in the past to create your profile information in the past.</p>
  <label for="myemailfield">Email</label>  
  <input type="email" id="myemailfield" data-email="{email_addreess}"> 
  <output data-result>{email_addreess}</output>
  <button id ="mySubmit" type="submit">Submit</button>
</form>
{/exp:channel:entries}

CodePudding user response:

The for loop is a bad design pattern in my opinion. Each time you call the function it will reinitialize numTries (first to undefined, then to 0 by the for) and run 3 times the script with the same data.

Initialize let numTries = 0; outside the function form.onsubmit.

Then, each time you call the function check that numTries < 3;. If not, display whatever you want (like a message to invite the user to call).

If it is, compare value inputValue === correctEmail.

Is it true ? Great.

Is it false ? Increment numTries and display a message to inform the user (something like "Wrong email, 2 tries left").

Note that numTries will be reset to 0 if the user reload the page. So using cookie or local storage as mentioned by @fnostro could be even better (but a user can empty his cache anyway).

CodePudding user response:

  1. If you are using a counter variable, define it outside of your function, it will retain it's value after the function ends. See closure.
let attempts = 0;
  1. Since you're using <form> try the HTMLFormElement interface. In the example below it's used to reference not only the <form> but the form controls within it as well.

  2. The if else condition needs to account for the number of failed attempts:

else if (guess !== emailKey && attempts < 2) {
  attempts  ;
  result.value = `Sorry, ${guess} didn't match, you have ${3 - attempts} attempts remaining.
`;
/* If no match AND there are zero or one attempts made. Remember we are counting from zero 
and the console only shows the value as it is within the else if block */
  1. Note in the example the <form> is setup to send to a live test server. If data is sent successfully, you'll see it's response in the <iframe located below the <form>.

I'm not familiar with some of the syntax in OP, I assume it's server-side:

{!--form.submit(); --}
...
<input type="email" id="myemailfield" data-email="{email_addreess}"> 
  <output data-result>{email_addreess}</output>

The {email_address} is secure?

const UI = document.forms.UI;
let attempts = 0;

UI.onsubmit = (e) => {
  e.preventDefault();
  const IO = e.currentTarget.elements;
  const email = IO.email;
  const guess = email.value;
  const result = IO.result;
  const emailKey = email.dataset.email;

  if (guess === emailKey) {
    e.currentTarget.submit();
    result.value = 'Matches!'
    email.classList.add('match');
    IO.btn.disabled = true;
  } else if (guess !== emailKey && attempts < 2) {
    attempts  ;
    console.log(attempts);
    result.value = `Sorry, ${guess} didn't match, you have ${3 - attempts} attempts remaining.`;
    email.value = "";
    email.classList.add('nomatch');
  } else {
    result.value = "Please contact ";
    document.links[0].style.display = 'inline-block';
    IO.btn.disabled = true;
  }
}
#email {
  display: inline-block;
  width: 20ch;
  margin: 0 3px 5px 5px;
  border: 0.5px inset lightgrey;
  border-radius: 2px;
  outline: 0;
}

.match {
  box-shadow: 0 0 0 3px lime
}

.nomatch {
  box-shadow: 0 0 0 3px tomato
}

#btn:disabled {
  opacity: 0.3
}

.as-console-row::after { width: 0; font-size: 0; }
.as-console-row-code { width: 100%; word-break: break-word; }
.as-console-wrapper { min-height: 100% !important; max-width: 50%; margin-left: 50%; }
<form id="UI" action='https://httpbin.org/post' method='POST' target='response' >
  <fieldset>
    <p>Please enter the address you used in the past to create your profile information.</p>
    <label for="email">Email</label>
    <input id="email" name='email' type="email" data-email="[email protected]"><button id='btn'>Submit</button><br>
    <output id='result' data-result></output><a href="#" style='display:none'>Support</a>
  </fieldset>
</form>
<iframe src='about:blank' name='response'></iframe>

  • Related