Jump to content

Validate bootsrap modal form before sumbit (server-side or don't know the term)


Zinn

Recommended Posts

 

Hello Coders, wanted to know if anybody could help to validate modal form based on the query below please? 

Appreciate your help if possible.

Thank you so much!

MODAL FORM 

FORM 

<div class="modal fade" id="exampleModal" data-backdrop="static" tabindex="-1" role="dialog" aria-labelledby="staticBackdrop" aria-hidden="true">
   >
   <div class="modal-dialog" role="document">
      <div class="modal-content">
         <div class="modal-header">
            <h5 class="modal-title" id="exampleModalLabel">Add user</h5>
            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <i aria-hidden="true" class="ki ki-close"></i>
            </button>
         </div>
         <div class="modal-body">
            <form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post" class="needs-validation" novalidate id="adduser">
               <div class="form-row">
                  <div class="form-group col-md-6 mb-3">
                     <label for="inputState">Select a name</label><br>
                     <select class="form-control select2 <?php echo (!empty($fullname_err)) ? 'is-invalid' : ''; ?>" id="kt_select2_1" name="fullname" required>
                        <option value="" selected>Select a name</option>
                        <?php
                           require_once('./conn/inc.php');
                           $sql = mysqli_query($link,"SELECT * FROM members ORDER BY fullname ASC");
                           while($row=mysqli_fetch_array($sql))
                           {
                           $mid	= $row['mid'];
                           $fullname	= $row['fullname'];
                           
                           echo '<option value="'.$mid.'">'.$fullname.'</option>';
                           } ?>  
                     </select>
                     <span class="invalid-feedback"><?php echo $fullname_err; ?></span>
                  </div>
                  <div class="col-xxl-6 col-xl-6 col-lg-6 col-md-6 col-sm-12 mb-3">
                     <label for="username">Username</label>
                     <input type="text" class="form-control <?php echo (!empty($uname_err)) ? 'is-invalid' : ''; ?>" placeholder="username" name="uname" required>
                     <span class="invalid-feedback"><?php echo $uname_err; ?></span>
                  </div>
                  <div class="col-xxl-6 col-xl-6 col-lg-6 col-md-6 col-sm-12 mb-3">
                     <label for="showpass">Password</label>
                     <input type="password" class="form-control <?php echo (!empty($password_err)) ? 'is-invalid' : ''; ?>" id="showpass" placeholder="Password" name="password"  required>
                     <span class="invalid-feedback"><?php echo $password_err; ?></span>
                  </div>
                  <div class="col-xxl-6 col-xl-6 col-lg-6 col-md-6 col-sm-12 mb-3">
                     <label for="showpass2">Confirm Password</label>
                     <input type="password" name="confirm_password" class="form-control <?php echo (!empty($confirm_password_err)) ? 'is-invalid' : ''; ?>" id="showpass2" placeholder="Confirm password"  required>
                     <span class="invalid-feedback"><?php echo $confirm_password_err; ?></span>
                  </div>
               </div>
         </div>
         <div class="modal-footer">
         <div class="checkbox-inline mr-2">
         <label class="checkbox">
         <input type="checkbox" onclick="myFunction()" class="form-check-input" id="exampleCheck1">
         <span></span>
         Show password
         </label>
         </div>
         <button type="reset" class="btn btn-secondary">Clear</button>
         <button type="submit" class="btn btn-primary">Submit</button>
         </div>
         </form>
      </div>
   </div>
</div>

VALIDATION QUERY

<?php 
 
// Define variables and initialize with empty values
$fullname = $uname = $password = $confirm_password = "";
$fullname_err = $uname_err = $password_err = $confirm_password_err = "";
 
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
 
    // Validate username
    if(empty(trim($_POST["uname"]))){
        $uname_err = "Please enter a username.";
    } elseif(!preg_match('/^[a-zA-Z0-9_]+$/', trim($_POST["uname"]))){
        $uname_err = "Username can only contain letters, numbers, and underscores.";
    } else{
        // Prepare a select statement
        $sql = "SELECT id FROM users WHERE uname = ?";
        
        if($stmt = mysqli_prepare($link, $sql)){
            // Bind variables to the prepared statement as parameters
            mysqli_stmt_bind_param($stmt, "s", $param_username);
            
            // Set parameters
            $param_username = trim($_POST["uname"]);
            
            // Attempt to execute the prepared statement
            if(mysqli_stmt_execute($stmt)){
                /* store result */
                mysqli_stmt_store_result($stmt);
                
                if(mysqli_stmt_num_rows($stmt) == 1){
                    $uname_err = "This username is already taken.";
                } else{
                    $uname = trim($_POST["uname"]);
                }
            } else{
                echo "Oops! Something went wrong. Please try again later.";
            }

            // Close statement
            mysqli_stmt_close($stmt);
        }
    }
 
    // Validate username
    if(empty(trim($_POST["fullname"]))){
        $fullname_err = "Please enter a fullname.";
    } else{
        // Prepare a select statement
        $sql = "SELECT id FROM users WHERE fullname = ?";
        
        if($stmt = mysqli_prepare($link, $sql)){
            // Bind variables to the prepared statement as parameters
            mysqli_stmt_bind_param($stmt, "s", $param_fullname);
            
            // Set parameters
            $param_fullname = trim($_POST["fullname"]);
            
            // Attempt to execute the prepared statement
            if(mysqli_stmt_execute($stmt)){
                /* store result */
                mysqli_stmt_store_result($stmt);
                
                if(mysqli_stmt_num_rows($stmt) == 1){
                    $fullname_err = "This names is already taken.";
                } else{
                    $fullname = trim($_POST["fullname"]);
                }
            } else{
                echo "Oops! Something went wrong. Please try again later.";
            }

            // Close statement
            mysqli_stmt_close($stmt);
        }
    }
    
    // Validate password
    if(empty(trim($_POST["password"]))){
        $password_err = "Please enter a password.";     
    } elseif(strlen(trim($_POST["password"])) < 6){
        $password_err = "Password must have atleast 6 characters.";
    } else{
        $password = trim($_POST["password"]);
    }
    
    // Validate confirm password
    if(empty(trim($_POST["confirm_password"]))){
        $confirm_password_err = "Please confirm password.";     
    } else{
        $confirm_password = trim($_POST["confirm_password"]);
        if(empty($password_err) && ($password != $confirm_password)){
            $confirm_password_err = "Password did not match.";
        }
    }
    
    // Check input errors before inserting in database
    if(empty($fullname_err) && empty($uname_err) && empty($password_err) && empty($confirm_password_err)){

         $fullname = mysqli_real_escape_string($link, $_REQUEST['fullname']);
         $uname = mysqli_real_escape_string($link, $_REQUEST['uname']);

        // Prepare an insert statement
        $sql = "INSERT INTO users (fullname, uname, password) VALUES (?, ?, ?)";
         
        if($stmt = mysqli_prepare($link, $sql)){
            // Bind variables to the prepared statement as parameters
            mysqli_stmt_bind_param($stmt, "sss", $param_fullname, $param_username, $param_password);
            
            // Set parameters
            $param_fullname = $fullname;
            $param_username = $uname;
            $param_password = password_hash($password, PASSWORD_DEFAULT); // Creates a password hash
            
            // Attempt to execute the prepared statement
            if(mysqli_stmt_execute($stmt)){
                // Redirect to login page
                header("location: users.php");
                $_SESSION['status'] = "Record Successfuly Saved!";
            } else{
                echo "Oops! Something went wrong. Please try again later.";
            }

            // Close statement
            mysqli_stmt_close($stmt);
        }
    }
    
    // Close connection
   //  mysqli_close($link);
}
?>

I have put javascript to validate form before submitting and this only works on client side ; It won't fetch data from database to compare. 

      <script>
      // Example starter JavaScript for disabling form submissions if there are invalid fields
      (function() {
        'use strict';
        window.addEventListener('load', function() {
          // Fetch all the forms we want to apply custom Bootstrap validation styles to
          var forms = document.getElementsByClassName('needs-validation');
          // Loop over them and prevent submission
          var validation = Array.prototype.filter.call(forms, function(form) {
            form.addEventListener('submit', function(event) {
              if (form.checkValidity() === false) {
                event.preventDefault();
                event.stopPropagation();
              }
              form.classList.add('was-validated');
            }, false);
          });
        }, false);
      })();
      </script>
Edited by Zinn
Link to comment
Share on other sites

client-side validation is a nicety for legitimate visitors. since external data can be submitted to your server-side code from anywhere, can be set to anything, and cannot be trusted, you MUST validate all data on the server before using it. since you must do this, it doesn't pay to do more than just use the browser's built in form field checks in the client. also, from the point where you have checked in the client if a value doesn't exist (you would need to use ajax to do this), to the point on the server where you actually try to insert the data, the value(s) could have been taken, and the insert query error handling is place where this check must finally occur.

in the server-side code, the correct way of detecting duplicates, in the case of multiple concurrent requests to your script, is to define the column(s) to be unique indexes, then simply attempt to insert the data, and detect if a duplicate index error has occurred. in the case of more than one unique column, it is after the insert query fails, that you would execute a select query to find which column(s) already contain the submitted values.

your database design is duplicating the fullname in two tables. this creates a problem in that if anyone edits a value, you must insure that all occurrences are updated. you should avoid duplicating data in multiple tables. is there some reason that you cannot just use a single table for all this user information?

also, since most people have a first name and a last name, you should store these in two separate columns to avoid ambiguity. is someone's name Ross Martin or Martin Ross?

as to the server-side code, this is largely derived from the bad code examples at w3schools and there's nearly twice as much code as is necessary. instead, the server-side form processing code should -

  1. use an array for the user/validation errors, with the array index being the field name.
  2. keep the form data as an array in a php array variable, then use elements in this array variable throughout the rest of the code.
  3. detect if a post method form was submitted, rather than trying to detect if the submit button is set.
  4. trim all the data ONCE. since you will be keeping the data in a php array variable, you can do this using one single line of code. there's 11 trim() statements in that code for 4 pieces of data.
  5. validate all the data, storing the errors per item #1 on this list.
  6. after the end of all the validation logic, if the array holding the errors is empty, use the submitted data.
  7. don't (switch to) use $_REQUEST variables. use the variables you expect data in. also, you are validating the trimmed input data, but are using the un-trimmed data in the sql query. after you do items #2 and #4 on this list, you will only be using the trimmed data throughout the rest of the code.
  8. you ARE using a prepared query. do NOT also apply any _escape_string() functions to the data. this will result in the escape characters being inserted into the database, messing up the stored data.
  9. don't copy variables to other variables for nothing. this is a waste of your time typing.
  10. if you switch to use the much simpler PDO database extension, about half of the database lines of code will go away.
  11. you need error handling for all the database statements that can fail - connection, query, prepare, and execute. the only place where a user can recover from a database error is when inserting/updating duplicate or out of range value. this is the only case where you should have error handling logic in your code. if you use exceptions for database statement errors and only catch and handle the exception in this case, you can remove any existing error handling logic, simplifying your code.
  12. every redirect needs an exit/die statement after it to stop php code execution.
  13. the redirect upon successful completion of the post method form processing code should be to the exact same url of the current page, to cause a get request for that page. the comment/redirect is not clear if this is what the code is doing.
  14. if there are user/validation errors at item #6 in this list, the code would continue on to display the html document, redisplay the form, with any user/validation error messages, and repopulate the appropriate form field values with the submitted values, so that user doesn't need to keep entering the same values over and over.
  15. any dynamic value that you output on a web page needs htmlentities() applied to it to help prevent cross site scripting.
  16. to get a form to submit to the same page it is on, simply leave out the entire action attribute.

 

  • Great Answer 1
Link to comment
Share on other sites

13 minutes ago, mac_gyver said:

client-side validation is a nicety for legitimate visitors. since external data can be submitted to your server-side code from anywhere, can be set to anything, and cannot be trusted, you MUST validate all data on the server before using it. since you must do this, it doesn't pay to do more than just use the browser's built in form field checks in the client. also, from the point where you have checked in the client if a value doesn't exist (you would need to use ajax to do this), to the point on the server where you actually try to insert the data, the value(s) could have been taken, and the insert query error handling is place where this check must finally occur.

in the server-side code, the correct way of detecting duplicates, in the case of multiple concurrent requests to your script, is to define the column(s) to be unique indexes, then simply attempt to insert the data, and detect if a duplicate index error has occurred. in the case of more than one unique column, it is after the insert query fails, that you would execute a select query to find which column(s) already contain the submitted values.

your database design is duplicating the fullname in two tables. this creates a problem in that if anyone edits a value, you must insure that all occurrences are updated. you should avoid duplicating data in multiple tables. is there some reason that you cannot just use a single table for all this user information?

also, since most people have a first name and a last name, you should store these in two separate columns to avoid ambiguity. is someone's name Ross Martin or Martin Ross?

as to the server-side code, this is largely derived from the bad code examples at w3schools and there's nearly twice as much code as is necessary. instead, the server-side form processing code should -

  1. use an array for the user/validation errors, with the array index being the field name.
  2. keep the form data as an array in a php array variable, then use elements in this array variable throughout the rest of the code.
  3. detect if a post method form was submitted, rather than trying to detect if the submit button is set.
  4. trim all the data ONCE. since you will be keeping the data in a php array variable, you can do this using one single line of code. there's 11 trim() statements in that code for 4 pieces of data.
  5. validate all the data, storing the errors per item #1 on this list.
  6. after the end of all the validation logic, if the array holding the errors is empty, use the submitted data.
  7. don't (switch to) use $_REQUEST variables. use the variables you expect data in. also, you are validating the trimmed input data, but are using the un-trimmed data in the sql query. after you do items #2 and #4 on this list, you will only be using the trimmed data throughout the rest of the code.
  8. you ARE using a prepared query. do NOT also apply any _escape_string() functions to the data. this will result in the escape characters being inserted into the database, messing up the stored data.
  9. don't copy variables to other variables for nothing. this is a waste of your time typing.
  10. if you switch to use the much simpler PDO database extension, about half of the database lines of code will go away.
  11. you need error handling for all the database statements that can fail - connection, query, prepare, and execute. the only place where a user can recover from a database error is when inserting/updating duplicate or out of range value. this is the only case where you should have error handling logic in your code. if you use exceptions for database statement errors and only catch and handle the exception in this case, you can remove any existing error handling logic, simplifying your code.
  12. every redirect needs an exit/die statement after it to stop php code execution.
  13. the redirect upon successful completion of the post method form processing code should be to the exact same url of the current page, to cause a get request for that page. the comment/redirect is not clear if this is what the code is doing.
  14. if there are user/validation errors at item #6 in this list, the code would continue on to display the html document, redisplay the form, with any user/validation error messages, and repopulate the appropriate form field values with the submitted values, so that user doesn't need to keep entering the same values over and over.
  15. any dynamic value that you output on a web page needs htmlentities() applied to it to help prevent cross site scripting.
  16. to get a form to submit to the same page it is on, simply leave out the entire action attribute.

 

Hi @mac_gyver

Thank you for your best and valuable advice.

I will follow all these rules and learn more.

Thank you once again.

Kind regards,

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.