Jump to content

Form validation help (regex and PHP)


Nic727

Recommended Posts

Hi,

I have some problems with my form validation. Here is my HTML which look good.

<div id="form-messages"></div>
                     
            <form id="ajax-contact" name="email" method="post" autocomplete="off" action="contact.php">
                <p>Les champs sont obligatoires*</p>
                    <div class="rowform"> 
                        <div class="half left">   
                            <label>Prénom*</label>
                            <input name="prenom" id="prenom" type="text" autocomplete="off" required>
                        </div>
                        <div class="half right">  
                            <label>Nom*</label>
                            <input name="nom" id="nom" type="text" autocomplete="off" required>
                        </div>
                    </div>
                    <div class="rowform">
                        <label>Courriel*</label>
                        <input name="courriel" id="courriel" type="email" autocomplete="off" required>
                    </div>
                    <div class="rowform"> 
                        <label>Sujet*</label>
                        <input name="sujet" id="sujet" type="text" autocomplete="off" required>
                    </div>
                    <div class="rowform"> 
                        <label>Votre message*</label>
                        <textarea id="message" name="message" autocomplete="off" required></textarea>
                    </div>
                    <div class="end-form">    
                        <button id="submit" class="submit btn btn-dark" name="submit" type="submit" value="envoyer"><i class="fa fa-paper-plane" aria-hidden="true"></i> Envoyer</button>
                    </div>    
                </form>

Here is my JS. For some reasons, my regex doesn't work. If I put it outside the submit part, it add the red border when loading the page, which is good for the code, but if I have it as bellow, it doesn't prevent the form from submitting and it doesn't add the red border. Do you have any ideas how it can do something like when submitting, check if regex ok, if all good, submit the form or don't submit.

$(function() {
        // Get the form.
        var form = $('#ajax-contact');
     
        // Get the messages div.
        var formMessages = $('#form-messages');
     
        // TODO: The rest of the code will go here...
    // Set up an event listener for the contact form.
    $(form).submit(function(event) {
        // Stop the browser from submitting the form.
        event.preventDefault();
     
        // TODO
        // Serialize the form data.
        var formData = $(form).serialize();
     
        //REGEX            <------------------------------ DOESNT WORK!
        var $prenom = $('#prenom');
        /*var $nom = $('#nom');
        var $email = $('#courriel');*/

        var regex1 =  /[^\d\W]{2,20}[\-\s\']{0,1}/i;
     

        if($prenom != regex1){
            $prenom.css({"border-color":"red"});
            return false;
        }else{

        // Submit the form using AJAX.
        $.ajax({
            type: 'POST',
            url: $(form).attr('action'),
            data: formData,
            success: function(response) {
                // Make sure that the formMessages div has the 'success' class.
                formMessages.removeClass('error');
                formMessages.addClass('success');
     
                // Set the message text.
                formMessages.text(response);
     
                // Clear the form.
                $('#prenom').val('');
                $('#nom').val('');
                $('#courriel').val('');
                $('#sujet').val('');
                $('#message').val('');
            },
            error: function(data) {
                // Make sure that the formMessages div has the 'error' class.
                formMessages.removeClass('success');
                formMessages.addClass('error');
     
                // Set the message text.
                if (data.responseText !== '') {
                    formMessages.text(data.responseText);
                } else {
                    formMessages.text('Oops! An error occured and your message could not be sent.');
                }
            }
        })
    }
    });
    

    });

    $('form').each(function() { this.reset() }) //reset form when refresh or reload the page instead of keeping the infos.

Also, should I add regex to PHP or not? Is it ok just like that?

/ Only process POST requests.
    if ($_SERVER["REQUEST_METHOD"] == "POST") {
        // Get the form fields and remove whitespace.
        $prenom = strip_tags(trim($_POST["prenom"])); //Obligatoire
        $nom = strip_tags(trim($_POST["nom"])); //Obligatoire
        $nom = str_replace(array("\r","\n"),array(" "," "),$nom);
        $courriel = filter_var(trim($_POST["courriel"]), FILTER_SANITIZE_EMAIL);//Obligatoire
        $suj = strip_tags(trim($_POST["sujet"])); //Obligatoire
        $message = trim($_POST["message"]); //Obligatoire

        // Check that data was sent to the mailer.
        if (empty($prenom) || empty($nom) || empty($courriel) || empty($suj) || empty($message) || !filter_var($courriel, FILTER_VALIDATE_EMAIL)) {
            // Set a 400 (bad request) response code and exit.
            http_response_code(400);
            echo "Oops! There was a problem with your submission. Please complete the form and try again.";
            exit;
        }

        // Set the recipient email address.
        // FIXME: Update this to your desired email address.
        $destinataire = "contact@nicolas-duclos.com"; //to or recipient

        // Set the email subject.
        $sujet = $suj; //Obligatoire

        // Build the email content. (Corps du message)
        $email_content = "Prenom : $prenom \r\n";
        $email_content .= "Nom : $nom \r\n";
        $email_content .= "Courriel : $courriel \r\n";
        $email_content .= "Sujet : $sujet \r\n";
        $email_content .= "Message :\r\n \r\n $message \r\n";
	
        // Build the email headers.
	    $semi_rand = md5(time());
	    $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
        $headers = 'From: '.$prenom.' ' .$nom.'<' .$courriel. '>'."\r\n";
        $headers .= 'Reply-To: '.$courriel."\r\n";
        $headers .= "Content-type: text/plain; charset=UTF-8"."\r\n";

        /* Variable email très importante sinon cela envoie deux fois */
        $mail = mail($destinataire,$sujet,$email_content,$headers);

        // Send the email.
        if ($mail) {
            // Set a 200 (okay) response code.
            http_response_code(200);
            echo "Thank You! Your message has been sent.";
        } else {
            // Set a 500 (internal server error) response code.
            http_response_code(500);
            echo "Oops! Something went wrong and we couldn't send your message.";
        }

    } else {
        // Not a POST request, set a 403 (forbidden) response code.
        http_response_code(403);
        echo "There was a problem with your submission, please try again.";
    }

Thank you for your help.

 

PS: Should I keep last name as required? I know most people will skip last name and only write the first name… If I remove the required, should I keep the regex for it and if empty, make it like it's good to submit? Just don't want to have fake or impossible last name even if it's not required.

Edited by Nic727
Link to comment
Share on other sites

Your problem is here:

var $prenom = $('#prenom');

var regex1 =  /[^\d\W]{2,20}[\-\s\']{0,1}/i;

if($prenom != regex1){

You can't just compare a jQuery object to a regular expression. You have to get the field's value out of the object and then apply the regular expression using methods like match(), test() or exec().

You should be doing validation in PHP as well. Javascript validation is optional, PHP validation is necessary. If you only do validation in Javascript, people can bypass it easily.

Should the last name be required? That's up to you, you design the requirements for your own software. If you don't mind not having a last name, you can choose to only validate it when it is not empty.

Link to comment
Share on other sites

I forgot to update my thread last night, but I already changed to that:

 

//REGEX
        var $prenom = $('#prenom').value();
        /*var $nom = $('#nom');
        var $email = $('#courriel');*/

        var regex1 =  /[^\d\W]{2,20}[\-\s\']{0,1}/i;
     

        if(regex1.test($prenom)=false){
            $prenom.css({"border-color":"red"});
            alert("ERROR!");
            return false;
        }else{

But still not working. I did try to add an alert, but doesn't show up.

If I understand the verification correctly.

- Javascript validation to add style

- PHP validation to prevent mailing wrong things? If someone disable JS, is it possible to add styling with PHP or not? For example, my border-color will not change if JS is disable right?

 

Also, I read somewhere that I don't need a Regex if my input type is "email" since the browser already check if it's ok or not. Is it correct?

Edited by Nic727
Link to comment
Share on other sites

15 minutes ago, dsonesuk said:

It's .val() NOT .value()

Not working. Maybe something wrong with my regex or where I placed it? I'm sure I did the good thing by placing it before the .ajax, so it's not submitting, but something doesn't work.

Edited by Nic727
Link to comment
Share on other sites

You are applying css to the variable of $prenon which now is the value of $('#prenom').val();

try

var $prenom = $('#prenom');
        /*var $nom = $('#nom');
        var $email = $('#courriel');*/

        var regex1 =  /[^\d\W]{2,20}[\-\s\']{0,1}/i;
     

        if(regex1.test($prenom.val())=false){
            $prenom.css({"border-color":"red"});
            alert("ERROR!");
            return false;
        }else{

 

Link to comment
Share on other sites

50 minutes ago, dsonesuk said:

And don't reply with "its still not working" look at web developer tools, it should show a error why its not working, that's more helpful.

I know, but I don't get errors. That's weird.

 

Maybe my function is wrong. I tried to remove everything and just keep the regex and I added an new alert for "else" and it didn't show up either. I think my function is not working at all...

I tried:

$(function() {
        // Get the form.
        var form = $('#ajax-contact');
     
        // Get the messages div.
        var formMessages = $('#form-messages');
     
        // TODO: The rest of the code will go here...
    // Set up an event listener for the contact form.
    $(form).submit(function(event) {
        // Stop the browser from submitting the form.
        event.preventDefault();
     
        // TODO
        // Serialize the form data.
        var formData = $(form).serialize();
     
        //REGEX
        var $prenom = $('#prenom');

        var regex1 = /[^\d\W]{2,20}[\-\s\']{0,1}/i;
     

        if(regex1.test($prenom.val())==false){
            $prenom.css({"border-color":"red"});
            alert("ERROR!");
            return false;
        }else{
          alert("GOOD");
        }
    });
});

EDIT: If I only had my if outside the function, I have an alert when loading the page and everything is alright since it load my regex when loading the page. Not sure what is wrong with the function.

Edited by Nic727
Link to comment
Share on other sites

Even like that it doesn't work and no error.

$("form").submit(function(event) {
                    
                    var $prenom = $("#prenom");

                    var regex1 = /[^\d\W]{2,20}[\-\s\']{0,1}/i;
     
                    if(regex1.test($prenom.val())==false){
                        $prenom.css({"border-color":"red"});
                        alert("ERROR!");
                        return false;
                    }else{
                        return true;
                    }
                 })

One thing is certain… My regex work outside of the submit function (but a little bit broken since I can't write 123 as a name, but can write Ba123 which is weird) and I tried to move my code around, but nothing work. I even tried with the variables outside the function. Also the fact that I don't have errors showing make it very hard.

 

Here are my files if you want to look into it.

 

That's the last page of my project and I will be working on it for a week :(

 

contactform.zip

Link to comment
Share on other sites

Figure out what's going on and if it's running that at all.  Have it tell you what it's doing.

$("form").submit(function(event) {

  console.log('Submit');

  var $prenom = $("#prenom");

  console.log($prenom.val());

  var regex1 = /[^\d\W]{2,20}[\-\s\']{0,1}/i;

  if(regex1.test($prenom.val())==false){
    $prenom.css({"border-color":"red"});
    alert("ERROR!");
    console.log('false');
    return false;
  }else{
    console.log('true');
    return true;
  }
})

 

Link to comment
Share on other sites

Look like it doesn't submit at all.

But according to https://api.jquery.com/submit/

I have wrote it correctly no?

 

EDIT: If I change for .click instead of .submit it works. Something is wrong with my submit button… But I have it correctly written, I don't understand.

<button id="submit" class="submit btn btn-dark" name="submit" type="submit" value="envoyer">

 

Like that it can works, but I don't think it's the proper way to do that.

$("#submit").click(function() {

                    
                  
                    var $prenom = $("#prenom");
                    
                    console.log($prenom.val());
                  
                    var regex1 = /[^\d\W]{2,20}[\-\s\']{0,1}/i;
                  
                    if(regex1.test($prenom.val())==false){
                      $prenom.css({"border-color":"red"});
                      alert("ERROR!");
                      console.log('false');
                      return false;
                    }else{
                      console.log('true');
                      console.log('Submit');
                      $("form").submit();
                      return true;
                      
                    }
                  })

Also, my regex doesn't work. My goal for the regex is to not allow numbers and special characters (\d\W) allow just one (\-\s\') at a time for a max of 20 characters, but I think I messed up since it doesn't work correctly.

Edited by Nic727
Link to comment
Share on other sites

So you're saying that in the code I posted, you don't see any of the console messages?  If that's the next thing to debug, start by checking that you're actually attaching the event correctly, print out the form before you attach the submit event:

console.log($("form"));

That's going to look for every form on the page, so make sure yours is included.  You might also want a more specific selector if the page might have more than one form on it.

Link to comment
Share on other sites

ok thank you will look at that. I updated my post above with a regex problem, but I will sort it out later.

 

EDIT: Yes it recognize the form as one object. Not sure why it doesn't submit.

[object Object]: {0: Object, length: 1, prevObject: Object}
0: Object
length: 1
prevObject: Object
__proto__: Object
Edited by Nic727
Link to comment
Share on other sites

Ok I found the problem.

The problem are the "required" inside my input. In fact, when clicking on the submit button, it's blocked by the required input. If I fill them all correctly but the one I have the code, my alert will shows up.

 

Now instead of having a regex for the subject,  message (which can be whatever people want) and email (the browser already have the validation), is it possible with javascript to look if the entry is invalid (no text) to add my red border?

Is this code correct for that?

if ($.trim($(anotherinput).val()).length == 0){

From what I know the trim is removing all white space right?

Link to comment
Share on other sites

ok… now how should I write that?

 

I'm trying to make verification and if everything is good, submit with ajax, but I don't know how I should write it.

For the moment I tried with multiple if statement like.

// Get the inputs
    var $prenom = $("#prenom");
    var $nom = $("#nom");
    var $email = $("#courriel");
    var $sujet = $("#sujet");
    var $message = $("#message");
    // Regex              
    var regex1 = /[^\d\W]{2,20}[\-\s\']{0,1}/i;
    
    // Testing Regex
    if(regex1.test($prenom.val())==false){
        $prenom.css({"border-color":"red"});
        console.log("TEST");
        return false;
    }
    else if(regex1.test($nom.val())==false){
        $nom.css({"border-color":"red"});
        return false;
    }
    else if($.trim($email.val()).length == 0){
        $emaill.css({"border-color":"red"});
        return false;
    }
    else if($.trim($sujet.val()).length == 0){
        $sujet.css({"border-color":"red"});
        return false;
    }
    else if($.trim($message.val()).length == 0){
        $message.css({"border-color":"red"});
        return false;
    }else{

        // Default style for inputs
        $prenom.css({"border-color":""});
        $nom.css({"border-color":""});
        $email.css({"border-color":""});
        $sujet.css({"border-color":""});
        $message.css({"border-color":""});                
        // Submit the form using AJAX.
        $.ajax({

But I have two new problems. Since I now know that my code need to be perfect to prevent "Required" from stopping browser.

1. Now it check only one at a time. So if $prenom is not correct, it doesn't check $nom. How to make it check all? I think I could make it work with OR statement by adding || between each of my verification, but how do I change CSS only for the one who has an error?

 

2. Is it possible to verify email from the type="email" without using Regex? I tried with the trim, but it still add the default box shadow to my input box because the email is invalid. I would like to make that if the email is invalid, don't submit form (return false).

 

Also, my border-color reset doesn't work if I change only one with an error, but not the other one. Is it possible to correct that? I put that into the else statement, but since it doesn't read it if some are not correct, it doesn't work. OR I could make another if where it change the border-color when typing a valid entry? But it's like #1, how to change only the border of the input I'm currently typing into?

Edited by Nic727
Link to comment
Share on other sites

Now it check only one at a time. So if $prenom is not correct, it doesn't check $nom. How to make it check all?

Don't return after every error.  Do all the validation, then once that's finished decide whether or not to return.  That also means not using "else if".  And, if you're doing your own validation, I would remove the required attributes.

Is it possible to verify email from the type="email" without using Regex?

It sounds like the browser will already do that.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email

Keep in mind you'll still need to validate everything on the server, but in general for each field you should decide whether you're going to have the browser do internal validation, or whether you're going to do it in Javascript.  Either way you still need to validate it on the server also.

Link to comment
Share on other sites

That's why you need to validate it on the server also.  Pick one client-side validation method and use that, don't try to mix them.  Regardless of which one you choose, also validate on the server because they don't need to use your form or your Javascript to submit to your page.

Link to comment
Share on other sites

24 minutes ago, justsomeguy said:

That's why you need to validate it on the server also.  Pick one client-side validation method and use that, don't try to mix them.  Regardless of which one you choose, also validate on the server because they don't need to use your form or your Javascript to submit to your page.

Ok thank you. Didn't know that.

Also

if($.trim($email.val()).length == 0){
        $emaill.css({"border-color":"red"});
    }

Doesn't work. Maybe something wrong in the way I wrote it.

Edited by Nic727
Link to comment
Share on other sites

Could you explain what kind of result you're expecting from this statement? I can't tell you how to fix it if I don't know what it is supposed to do.

(regex1.test($prenom.val())==true).onkeydown

The trim() method belongs to the String object, it works like this:

var x = "   String   ";
x = x.trim();

It doesn't matter where you get the string,  but you have to call the trim() method on the string itself.

Link to comment
Share on other sites

5 minutes ago, Ingolme said:

Could you explain what kind of result you're expecting from this statement? I can't tell you how to fix it if I don't know what it is supposed to do.


(regex1.test($prenom.val())==true).onkeydown

The trim() method belongs to the String object, it works like this:


var x = "   String   ";
x = x.trim();

It doesn't matter where you get the string,  but you have to call the trim() method on the string itself.

About the keydown, my idea was that if the entry is false, make the border red like I already have, but when typing a true value, change border to default, but not sure it's possible without a keydown function. I think I will just forget this idea if it's too complicated.

 

About the trim I was following this https://stackoverflow.com/questions/1854556/check-if-inputs-are-empty-using-jquery

It seems to work for them. They are using This, but can I replace This by my variable?

Link to comment
Share on other sites

You don't need a keydown event to change styles. With Javascript you can change styles at any time.

Seeing as it's using the jQuery version of Javascript's trim() method, the trim statement you provided earlier should be working. Looking closer, the issue seems to be that you mistyped your variable name. You've added an extra "L" to $email.

//    ↓
$emaill.css({"border-color":"red"});
//    ↑

Whenever you come across an issue, try to look for typing mistakes first. Carefully analyze your code. If you don't find anything, then start printing out all the values as the program is running to see whether they are correct.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...