-1

I'm trying to create a log-in page that validates data before it gets submitted to my php page that handles it. I'm using javascript to validate. This is my code:

 <div class = mainInfo>
    <?php include "header.php"; ?>        
    <form name = SignUpForm action = signUpHandler.php method ='POST' class = inputLists>
       username: <input type = text name = "userName">
       password: <input id= "p1" type = password name = "password">
       reenter password:  <input id ="p2" type = password name = "passwordConfirmation">

       <input type="submit" name =" submitButton" value ="submit">
    </form>
    <div id="feedback"> 
    </div>
 </div>
<script>  
function validate()
{
    document.getElementById("feedback").innerHTML = "functionbeingcalled";
    var p1 = document.getElementById("p1").value,
                p2 = document.getElementById("p2").value);
    if( ! p1===p2 )
    {

        document.getElementById("feedback").innerHTML = "passwords dont match";
    }
    if(p1==="")
    {
         document.getElementById("feedback").innerHTML = "Must have a password";
    }
}
window.setInterval(validate(),1000);
</script>

<?php include "footer.php"; ?>

I would've thought that this script should run every second from the time that the page loads, but the script isn't being run at all. This line:

 document.getElementById("feedback").innerHTML = "functionbeingcalled";

isn't working either.

Besides for this question, is it possible to validate data before submitting using only php? I'm new to web programming.

HerrGanzorig
  • 51
  • 1
  • 14
Ploni
  • 111
  • 1
  • 1
  • 8
  • formatting your code sometimes helps understanding the code better – Mark Knol Nov 14 '17 at 16:16
  • `window.setInterval(validate(),1000);` executes `validate()` and passes it's return value (`undefined`) as the first parameter to `setInterval()` – Andreas Nov 14 '17 at 16:18

3 Answers3

0

Pass the function instead of calling it.

//             no parentheses!
window.setInterval(validate, 1000);

And this is wrong.

if( ! p1===p2 )

it should be this

if( p1!==p2 )

because of the higher precedence of the prefix !

0

I would suggest that you add listeners on your input fields! ;)

  1. It will then only run the validation code when changes are made. In other words; only when necessary.
  2. It will run the validation code "immediately" when input is changes. Instead of validation every 1000 ms.

I see you are not using jQuery (yet)? If you want to validate on 'change' using plain js, here is a solution: Plain js solution

If you are okay with adding the jQuery library to you code, then it can be done very easy like this jQuery solution

Rasmus Puls
  • 3,009
  • 7
  • 21
  • 58
  • I'm trying to go with your javascript method of adding an event listener, the following is my code: p2.addEventListener("onchange",validate); For some reason the function never gets called still – Ploni Nov 14 '17 at 17:18
  • If `p2` is still `document.getElementById("p2").value` then `p2.addEventListener(...)` should throw an error because `p2` is a string. – Andreas Nov 14 '17 at 17:31
  • on p2 change, is where i would put the listener. I would on that 'change' event get both p1 and p2, compare them and do X if match or Y if not. Check Scott Marcus's answer. He implemented listeners in your code and has a running example. I would agree that it is "good practice" that way, and bad practice to use loops, intervals etc. to run code. – Rasmus Puls Nov 14 '17 at 17:46
0

Well, you've got several issues...

First, with setInterval(), you only pass a reference to the function that should be called (validate in your case), you don't actually invoke it as you are doing (validate()). This essentially runs validate immediately and then sets the return value from it as the function to be called every second. Since validate() doesn't return a value, nothing happens every second thereafter.

You also have a typo with: if( ! p1===p2 ), which indicates that the Boolean opposite of p1 is being tested against p2. What you want is: if(p1 !== p2 ), which is how you express "not strictly equal to".

Now, really you are going about validation the wrong way. Instead of running a validation function on a timer, which is inefficient, you'd want to validate in one or more of these cases:

  • just before the entire form is submitted
  • just after the user leaves a form field
  • as the user is entering data
  • some combination of all 3

Each of those scenarios is handled through event handlers and a working example of each is shown below.

// Get the DOM references you'll need just once:
var feedback = document.getElementById("feedback");

// Don't set variables equal to property values of DOM elements because
// if you decide you need a different property value, you have to re-scan
// the DOM for the same element all over again.
var p1 = document.getElementById("p1")
var p2 = document.getElementById("p2");

var form = document.querySelector("form");

// Use this to validate when submit is pressed (causing form to be submitted):
form.addEventListener("submit", function(evt){ 
  // If validate function returns false, don't submit
  if(!validate()){
    evt.preventDefault(); // cancel the form submission
    feedback.textContent = "Can't submit. Form is not valid!";
  }
});

// Get the elements that need to be validated:
var inputs = document.querySelectorAll("input[type=text],input[type=password]");

// Convert that node list into an array:
inputs = Array.prototype.slice.call(inputs);

// Loop over array and set up event handlers for inputs
inputs.forEach(function(input){
  input.addEventListener("blur", validate);   // Used to validate when user moves off of each element
  input.addEventListener("input", validate);  // Used to validate as data is being entered
});


function validate()  {
  // Keep track of whether the form is valid or not. Assume that it is by default
  var valid = true;

  // .innerHTML is for when you want to assign a string containing
  // HTML to a DOM element. This invokes the HTML parser and renders
  // the HTML. If you don't have HTML in the string, use .textContent
  // instead, which doesn't invoke the HTML parser and is more efficient
  
  // See if the password was typed in both boxes before telling the user 
  // that the passwords don't match
  if(p1.value && p2.value){
    // Are they the same?
    if(p1.value !== p2.value){
      feedback.textContent = "passwords dont match";
      valid = false;
    } else {
      feedback.textContent = "passwords match";
    }
  } else {
    // If both password fields aren't filled in, the form can't be valid
    valid = false;
  }
  
  if(p1.value === "") {
   feedback.textContent = "Must have a password";
   valid = false;
  }
  
  // Send a result to the caller so it can be known by other code if the form is valid
  return valid;
}
<div class = "mainInfo">
  <form name="SignUpForm" action="signUpHandler.php" method='POST' class="inputLists">
    <div>username: <input type="text" name="userName"></div>
    <div>password: <input id="p1" type="password" name="password"></div>
    <div>reenter password:  <input id="p2" type="password" name="passwordConfirmation"></div>

    <!-- Any form element that has a "name" attribute will submit its name/value as
         part of the form data when the form gets submitted. You probably don't want
         the actual submit button to be included in this, so don't give the button
         a "name" attribute. -->
    <input type="submit" value="submit">     <input type="reset" value="reset">
  </form>
  <div id="feedback"></div>
</div>
Scott Marcus
  • 64,069
  • 6
  • 49
  • 71
  • `Array.from()` is not available in IE. `valid = true` in the `else` branch is useless. `// If both password fields aren't filled in...` is wrong, already one empty field will trigger the `else` path. _"Get the DOM references you'll need just once"_ but then you're querying the DOM twice for the same elements. Instead of adding the same event handler on every element add one on the form and use event delegation. You're overwriting the error message of the validation with the one from the submit handler. – Andreas Nov 14 '17 at 17:29
  • what does evt refer to? I don't see where you assigned it – Ploni Nov 14 '17 at 23:45
  • @JudahSchwartz ‘evt’ Is the name I gave to the argument that is automatically passed to the event handling function. It is an event object reference and gives you the ability to access the event so that you can cancel it. – Scott Marcus Nov 15 '17 at 00:15