简体   繁体   中英

Error Messages For Entire Form Are Being Outputted On Each Instance Of A Loop - PHP

I have a form that outputs images and some HTML <input> elements for adding titles and tags to images. This is outputted onto the page using a while loop inside a <form> element. The submit button for the form is outside of the loop, so you can submit multiple images one go.

When an error is present I would like to output the error message for that particular instance of the image component inside its related upload component - namely the div with the class upload-component . Is that possible with PHP or is it better to just prevent the form processing with PHP if an error is found (eg an empty title input element), and then show the specific errors with JavaScript for that particular image component (which I should be able to work out how to do with JS)?

Currently when an error is found the PHP outputs each error for the entire form in each component - ie if there are 3 errors on just one component, 3 error messages appear appear at the top of every component in the loop. This is obviously being caused by using a foreach loop to output the errors. When I remove the foreach though it doesn't output anything because it can't process the array of potential errors?

NOTE: The $user_id variable is assigned through a $_SESSION when the user is logged in.

Many thanks in advance for any help.

<?php 

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

    // check for errors - empty title input element not allowed
    forEach($image_title as $title) {
        if(empty(trim($title))){
            $error[] = "Image Title must be between 10 and 150 characters long";
        }
    }

    if (!isset($error)) {

        // ---- UPDATE DATABASE WITH PDO STATEMENTS IF NO ERRORS

    } 
}
?>

<form method="post" enctype="multipart/form-data">

    <!-- IMAGE COMPONENT - START -->

        <?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']);
        ?>

    <div class="upload-component">                
        <?php 
            // echo error messages from above
            if(isset($error)) {
                foreach($error as $msg) {
                    echo "<p>** ERROR: {$msg}</p>";
                }
            }
        ?>
            <div class="upload-image-wrapper">
                <img class="img upload-details-img" src="project/img/image.jpg">
            </div>
            <div class="edit-zone">
                <div class="form-row">
                    <label for="title-id-<?php echo $db_image_id; ?>">Image Title</label>
                    <input id="title-id-<?php echo $db_image_id; ?>" value="<?php $db_image_title; ?>" type="text" name="image-title[]">
                </div>
                <div class="form-row">
                    <label for="tags-id-<?php echo $db_image_id; ?>">Comma Separated Image Tags</label>
                    <textarea id="tags-id-<?php echo $db_image_id; ?>" type="text" name="image-tags[]"></textarea>
                    <input type="hidden" name="image-id[]" value="<?php echo $db_image_id; ?>">
                </div>
            </div>
    </div>

    <?php } ?>

    <div class="form-row">
        <button type="submit" name="upload-submit">COMPLETE UPLOAD</button>
    </div>
</form>

To associate a particular error with a particular record/ upload-component div the error should be assigned a known key and the most obvious is the image-id . All fields in the form use the array syntax for names so you can associate the various fields in the POST array using this index. Later when you wish to display the relevant error message in the appropriate upload-component container you look at the array key ( which is the image-id ) and compare to the image-id coming from the sql query - if they match then display the error.

<?php
    $error=array();

    if( isset( 
        $_POST['upload-submit'],
        $_POST['image-title'],
        $_POST['image-id']
    )) {
        $image_title = $_POST['image-title'];
        $image_tags = $_POST['image-tags'];
        $image_id = $_POST['image-id'];
        
        /*
            As the form has elements employing the the array syntax in
            their names (ie: <input type="text" name="image-id[]" /> etc )
            then the index within the POST array can be used to identify the relevant image-id
            and thus assign to the $error array as a key. This later helps identify which error
            is related to which generated 
            
        */
        forEach( $image_title as $index => $title ) {
            $id=$_POST['image-id'][ $index ];
            /*
                Assign the ID as key to the error in this array
            */
            if( empty( trim( $title ) ) ){
                $error[ $id ] = "Image Title must be between 10 and 150 characters long";
            }
        }

        if( empty( $error ) ) {
            // ---- UPDATE DATABASE WITH PDO STATEMENTS IF NO ERRORS
        }
    }
?>

<form method="post" enctype="multipart/form-data">

    <!-- IMAGE COMPONENT - START -->
    <?php

        $stmt = $connection->prepare("SELECT * FROM lj_imageposts WHERE user_id = :user_id");
        $stmt->execute([
            ':user_id' => $user_id
        ]); 

        while( $row = $stmt->fetch( PDO::FETCH_OBJ ) ) {
        
            $id = htmlspecialchars( $row->image_id );
            $title = htmlspecialchars( $row->image_title );
            $tags = htmlspecialchars( $row->image_tags );
            
            
            
            /* loop continues... */
    ?>

    <div class="upload-component">                
        <?php
        
            if( !empty( $error ) ) {
                foreach( $error as $element_id => $msg ) {
                    if( $element_id == $id ) echo "<p>** ERROR: {$msg}</p>";
                }
            }
        ?>
            <div class="upload-image-wrapper">
                <img class="img upload-details-img" src="project/img/image.jpg" />
            </div>
            
            <div class="edit-zone">
            
                <div class="form-row">
                    <label for="title-id-<?php echo $id; ?>">Image Title</label>
                    <input id="title-id-<?php echo $id; ?>" value="<?php $title; ?>" type="text" name="image-title[]" />
                </div>
                
                <div class="form-row">
                    <label for="tags-id-<?php echo $id; ?>">Comma Separated Image Tags</label>
                    <textarea id="tags-id-<?php echo $id; ?>" type="text" name="image-tags[]"></textarea>
                    
                    <input type="hidden" name="image-id[]" value="<?php echo $id; ?>" />
                </div>
            </div>
    </div>

    <?php 
    } //close while loop
    ?>

    <div class="form-row">
        <button type="submit" name="upload-submit">COMPLETE UPLOAD</button>
    </div>
</form>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM