Wednesday, 29 September 2021

Output PHP Form Validation Error Messages When Using JavaScript Fetch API

I have a page with multiple forms on, where each form is processed with PHP in the backend that sends data to a MySQL database, but on the front end it uses Javascript's fetchAPI to prevent the page refreshing when an instance of the form is completed and data is sent to the database.

I have some PHP server side validations that take place that still work in terms of not sending the data to the database, although on submission the instance of the form completed does disappear from the page (due to javascript shown below), but re-appears when refreshed if it failed the validations.

The main code example below includes this code block that would normally output the error message:

<?php 
    // echo form validation error messages
    if(isset($error)) {
        foreach($error as $msg) {
            echo "<p>** {$msg}</p>";
        }
    }
?>

In terms of outputting these error messages is it possible to still use this PHP code (currently not working), or now I'm using the javascript fetchAPI in conjuction with PHP, will I have to also write validations in JavaScript to output the errors on the front end, in addition to the PHP ones which securely prevent the form failing the validations?

<?php 

isset($_REQUEST['username']) ? $username = $_REQUEST['username'] : header("Location: login.php");

$user_id = $_SESSION['logged_in'] ?? header("Location: login.php");

if(isset($_POST['upload-submit'])) {
    
    $image_title = $_POST['image-title'];
    $image_tags = $_POST['image-tags'];
    $form_filename = $_POST['image-filename']; // value attribute from hidden form element with name 'image-filename'

    if(empty(trim($image_title))){
        $error[] = "Image Title cannot be blank";
    }

    if(!preg_match('/^[a-zA-Z0-9\s]+$/', $image_title)) {
        $error[] = "Image Title must be letters and numbers only";
    }

    // if no errors process submission
    if (!isset($error)) {

        try {

            $sql = "UPDATE lj_imageposts SET
            image_title = :image_title,
            image_tags = :image_tags,
            user_processed = 'yes',
            lj_approved = 'no'

            WHERE filename = :filename";
                
            $stmt = $connection->prepare($sql);
    
            $stmt->execute([
                ':image_title' => $image_title,
                ':image_tags' => $image_tags,
                ':filename' => $form_filename
            ]);
        

        } catch (PDOException $e) {
            echo "Error: " . $e->getMessage();
        }

    } else {
        // give values an empty string to avoid an error being thrown before form submission if empty
        $image_title = $image_tags = "";
    }
}

?>
<section>
    <h1>Complete Uploads</h1>
    <div>
        <?php 
            // echo form validation error messages
            if(isset($error)) {
                foreach($error as $msg) {
                    echo "<p>** {$msg}</p>";
                }
            }
        ?>

        <!-- OUTPUT IMAGE DETAILS COMPONENT -->

        <?php
            $stmt = $connection->prepare("SELECT * FROM lj_imageposts WHERE user_id = :user_id");

            $stmt->execute([
                ':user_id' => $user_id
            ]); 

            while ($row = $stmt->fetch()) {

                $db_image_id = htmlspecialchars($row['image_id']);
                $db_image_title = htmlspecialchars($row['image_title']);
                $db_image_tags = htmlspecialchars($row['image_tags']);
                $db_image_filename = htmlspecialchars($row['filename']);
                $db_image_ext = htmlspecialchars($row['file_extension']);
                $db_processed= htmlspecialchars($row['user_processed']);

        ?>
        
        <div class="upload-details-component">
            <form method="post" class="image-upload-details-form" enctype="multipart/form-data">
                <img src="<?php echo $www_root . '/images-lib/' . $db_image_filename . '-500' . '.' . $db_image_ext; ?>">
                <div class="edit-zone">
                    <div class="form-row">
                        <label>Image Title</label>
                        <input type="text" name="image-title">
                    </div>
                    <div class="form-row">
                        <label>Comma Separated Image Tags</label>
                        <textarea type="text" name="image-tags"></textarea>
                    </div>
                    <div class="form-row">
                        <button type="submit" name="upload-submit">COMPLETE UPLOAD</button>
                        <button type="submit" name="upload-details-delete">DELETE</button>
                        <input type="hidden" name="username" id="username" value="<?php echo $username; ?>">
                        <input type="hidden" name="image-filename" value="<?php echo $db_image_filename; ?>">
                    </div>
                </div>
            </form>
        </div>

        <?php } ?>

    </div>
</section>

Also here is the javascript fetchAPI code that works on the page.

var forms = document.querySelectorAll('.image-upload-details-form'),

forms.forEach(item => {
    
        item.querySelectorAll('[type="submit"], button').forEach(button => {
            button.addEventListener("click", e => item._button = button); //store this button in the form element
        })

        item.addEventListener("submit", function(evt, btn) {

            evt.preventDefault();

            const formData = new FormData(this);
            if (this._button) //submitted by a button?
            {
            formData.set(this._button.name, this._button.value);
        }

        fetch("upload-details.php", {
            method: 'post',
            body: formData
        }).then(function(response){
            return response.text();
        }).then(function(text){
            console.log(text);
        }).catch(function (error){
            console.error(error);
        })

        // removes form when submitted
        item.remove();

    })

})

Many thanks in advance for any help / advice.



from Output PHP Form Validation Error Messages When Using JavaScript Fetch API

No comments:

Post a Comment